Linux设备驱动开发(一)内核的配置与编译

Linux内核的源码结构

Linux内核主要由五个子系统组成:

  • 进程调度
  • 内存管理
  • 虚拟文档系统
  • 网络接口
  • 进程间通信

kernel

进程调度(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 命令以文本选单的形式配置内核,直接在内核源码目录输入

1
make menuconfig

配置选择

选择相应的配置时,有三种选择,它们分别代表的含义如下:

Y—-将该功能编译进内核
N—-不将该功能编译进内核
M—-将该功能编译成可以在需要时动态插入到内核中的模块

一些内核特性可以直接编译进内核。一些可以被编译为可装载的模块。一些则可以完全被一起移除。这里还有一些内核参数,它不是真正的特性,但是必须输入有效的十进制或者十六进制或者一些文本。

菜单项目中,以这些符号开始的表示特性可以:

  • **[ ]**:编译或者移除
  • **< >**:编译或者模块化或者移除
  • **{ }**:编译或者模块化(被其他特性选择)
  • **- -**:被其他特性选择

make menuconfig下,* 表示Y,M 表示 M,空白表示N。

为了改变这些特性,你需要用光标键移动使之高亮显示,同时按Y将其编译,按M模块化,按N将它移除。

你可能也需要按空格键来在几个选择中循环(Y -> N -> M -> Y)。

可能出现的问题

Ubuntu下,若 make menuconfig报以下错误,则需要安装库

报错信息

1
2
3
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

解决

1
sudo apt-get install ncurses-dev

linux内核源码的编译

1
make -j 2
  • -j 参数表示允许多个任务并行编译

编译成功后,生成的linux内核映像(zImage)生成在/arch/arm/boot路径下。