Linux设备驱动开发(一)内核的配置与编译
Linux内核的源码结构
Linux内核主要由五个子系统组成:
- 进程调度
- 内存管理
- 虚拟文档系统
- 网络接口
- 进程间通信
进程调度(SCHED)
功能:控制进程对CPU的访问
当需要选择下一个进程运行时,由调度程式选择最值得运行的进程。可运行进程实际上是仅等待CPU资源的进程,假如某个进程在等待其他资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。
内存管理(MM)
功能:允许多个进程安全的共享主内存区域
Linux 的内存管理支持虚拟内存,即在电脑中运行的程式,其代码,数据,堆栈的总量能够超过实际内存的大小,操作系统只是把当前使用的程式块保留在内存中,其余的程式块则保留在磁盘中。必要时,操作系统负责在磁盘和内存间交换程式块。内存管理从逻辑上分为硬件无关部分和硬件有关部分。硬件无关部分提供了进程的映射和逻辑内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。
虚拟文件系统(Virtual File System,VFS)
隐藏了各种硬件的具体细节,为任何的设备提供了统一的接口,VFS提供了多达数十种不同的文档系统。 虚拟文档系统能够分为逻辑文档系统和设备驱动程式。逻辑文档系统指Linux所支持的文档系统,如ext2,fat等,设备驱动程式指为每一种硬件控制器所编写的设备驱动程式模块。
网络接口(NET)
提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程式。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程式负责和硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程式。
进程间通讯(IPC)
支持进程间各种通信机制。
内核结构目录
目录名 | 描述 |
---|---|
arch | 体系结构相关的代码,相对于具体的CPU架构,如:arm、m68k、mips、PowerPC等。在arm目录有mach-s3c2440目录,该目录下是针对2440的支持代码。 |
block | 块设备的通用函数,如blk-core.c、blk-ioc.c等。 |
crypto | 常用的加密或校验算法等。 |
drivers | 目录中是系统中所有的设备驱动程序。它又进一步划分成几类设备驱动,每一种有对应的子目录,如:声卡的驱动对应于drivers/sound;drivers/block 下为块设备驱动程序;drivers/mtd下为Nor和Nand flash的驱动程序;drivers/char下为字符设备驱动程序。 |
Documents | 关于内核的一些帮助文档,是对每个目录作用的具体说明。 |
firmware | 一些固件驱动程序,如: |
fs | Linux支持的文件系统代码,如:ext2、ext3、ext4、jffs2、nfs等。 |
include | 目录包括编译核心所需要的大部分头文件,例如linux内核的头文件在include/linux子目录下,与cpu相关的头文件在include/asmgeneric子目录下;另外有些设备驱动程序的头文件,如:sound、video、net、pcmcia等。 |
init | 内核的初始化代码(不是系统的引导代码),其中,main.c文件中的start_kernel函数是内核引导后运行的第一个函数。 |
ipc | 目录包含了核心进程间的通信代码。 |
kernel | 内核管理的核心代码,此目录下的文件实现了大多数linux系统的内核函数,其中最重要的文件当属sched.c;同时与处理器结构相关代码都放在arch/*/kernel目录下。 |
lib | 目录包含了核心的库代码,不过与处理器结构相关的库代码被放在arch/*/lib/目录下。 |
nm | 目录包含了所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等。与具体硬件体系结构相关的内存管理代码位于arch/*/mm目录下 。 |
net | 目录里是核心的网络部分代码,其每个子目录对应于网络的一个方面。 |
samples | 一些调试的程序 |
scripts | 用于配置、编译内核的脚本文件。 |
security | 安全、密钥相关的代码。 |
sound | 音频设备的驱动程序 |
tools | 一些工具 |
usr | 用来制作一个压缩的cpio归档文件:initrd的镜像,它可以作为内核启动后挂载的第一个文件系统 |
virt | kvm |
Makefile | 目录第一个Makefile文件。用来组织内核的各模块,记录了个模块间的相互这间的联系和依托关系,编译时使用;仔细阅读各子目录下的Makefile文件对弄清各个文件这间的联系和依托关系很有帮助。 |
ReadMe | 目录里是核心及其编译配置方法简单介绍 |
REPORTING-BUGS | 目录里是有关报告Bug 的一些内容 |
CREDITS | 目录下是光荣榜。对Linux做出过很大贡献的一些人的信息。 |
COPYING | 目录下是GPL版权申明。对具有GPL版权的源代码改动而形成的程序,或使用GPL工具产生的程序,具有使用GPL发表的义务,如公开源代码。 |
MAINTAINERS | 目录存放了维护人员列表,对当前版本的内核各部分都有谁负责。 |
Linux内核源码的配置方法
配置linux内核的方法主要有下面几种方法:
make config
:基于文本的最为传统的配置界面,不推荐使用make menuconfig
:基于文本选单的配置界面,字符终端下推荐使用make xconfig
:基于图形窗口模式的配置界面,Xwindow下推荐使用make oldconfig
:如果只想在原来内核配置的基础上修改一些小地方,会省去不少麻烦
例如,采用 make menuonfig 命令以文本选单的形式配置内核,直接在内核源码目录输入
make menuconfig
配置选择
选择相应的配置时,有三种选择,它们分别代表的含义如下:
Y----将该功能编译进内核 N----不将该功能编译进内核 M----将该功能编译成可以在需要时动态插入到内核中的模块
一些内核特性可以直接编译进内核。一些可以被编译为可装载的模块。一些则可以完全被一起移除。这里还有一些内核参数,它不是真正的特性,但是必须输入有效的十进制或者十六进制或者一些文本。
菜单项目中,以这些符号开始的表示特性可以:
- [ ]:编译或者移除
- < >:编译或者模块化或者移除
- { }:编译或者模块化(被其他特性选择)
- - -:被其他特性选择
在make menuconfig
下,* 表示Y,M 表示 M,空白表示N。
为了改变这些特性,你需要用光标键移动使之高亮显示,同时按Y将其编译,按M模块化,按N将它移除。
你可能也需要按空格键来在几个选择中循环(Y -> N -> M -> Y)。
可能出现的问题
Ubuntu下,若 make menuconfig
报以下错误,则需要安装库
报错信息
Unable to find the ncurses libraries or the required header files. 'make menuconfig' requires the ncurses libraries. Install ncurses (ncurses-devel) and try again.
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2
解决
sudo apt-get install ncurses-dev
linux内核源码的编译
make -j 2
- -j 参数表示允许多个任务并行编译
编译成功后,生成的linux内核映像(zImage)生成在/arch/arm/boot路径下。