第二章 Linux 的内核结构及构建
- ---->这一章是自己总结的
1、内核结构(主要是下面这几个部分)
- 系统调用接口<–>System call interface
- 进程管理<------>Process management
- 内存管理<------>Memory management
- 虚拟文件系统<–>VFS
- 网络设备<------>Net
- 进程间通信<---->IPC
- 设备驱动<------>Drivers
- -------->具体对应的目录见书上59页
2、Makefiles and build system of kernel–kbuild
2.1 makefile包含五大部分
-
The top Makefile
:内核源码根目录下的Makefile,所有内核代码编译的入口。它负责两类东西的编译:vmlinux
:内核映像,Image->zImage -> boot.img,img是内核的常住居民。随系统启动而运行,直到系统关机。modules
:内核模块 xxx.ko,这种形式,也是内核源码的一种二进制形式,从本质上来说和内核映像是一样。但是ko是以普通文件的形式存在的,不随系统启动而运行,在系统需要你的时候 insmod xxx.ko,不需要你的时候就rmmod xxx.ko.如: camera.ko,ko形式多见于外设驱动它递归进入到内核源码树子目录去构建这些目标,应该至少包含一个arch的makefile和一个arch/$(ARCH)/Makefile(跟具体硬件平台相关)
-
.config
:内核源码根目录下,内核编译的配置文件,该文件直接决定哪些文件编译、怎么编译,内核配置文件包含像下面这些选项:- CONFIG_EXPERIMENTAL=y
- CONFIG_BROKEN_ON_SMP=y
- CONFIG_INIT_ENV_ARG_LIMIT=32
- CONFIG_CROSS_COMPILE=“arm-linux-”
-
arch/$(ARCH)/Makefile
:体系结构相关的Makefile,决定底层CPU相关的源码如何编译。为top Makefile提供具体硬件体系结构相关的信息。 -
scripts/Makefile.*
:包含了一些通用的Makefile模式,函数,脚本等等。供其他Makefile包含 -
kbuild Makefiles
_:每个子目录有一个kubild makefile,决定哪些文件编译到vmlinux(built-in),哪些编成在ko,kbuild(内核编译系统)内置了几个变量-
obj-y
: 这个变量指定的.o文件列表,最终编译到vmlinux中去
obj-y := a.o b.o c.o
a-y = 1.o 2.o- 1.o <- 1.c,2.o < 2.c
->a.o - b.o <- b.c,c.o <- c.c
=> vmlinux -> … -> boot.img
- 1.o <- 1.c,2.o < 2.c
-
obj-m
:obj-m这个变量指定的.o文件列表,kbuild最终会为每个.o生成一个同名的ko文件- obj-m := a.o b.o,a.o -> a.ko,b.o -> b.ko
-
语法:
目标名-y/目标名-objs
:生成"目标名"所依赖的.o文件列表-
obj-m := a.o b.o
- a.c(a.s) ->a.o -> a.ko
- b.c(b.s) ->b.o -> b.ko
-
obj-m := sb.o nb.o
-
sb-y := a.o b.o c.o
- a.o <- a.c(a.s)
- b.o <- b.c(b.s)
- c.o <- c.c(c.s)
- =>sb.o -> sb.ko
- nb.c(nb.s) -> nb.o -> nb.ko
-
obj-$(CONFIG_XXX) += sb.o
-
kbuild只认 obj-y obj-m
-
sb.o编还是不编,得看变量CONFIG_XXX的值
-
if CONFIG_XXX = y sb.o编,而且编进vmlinux
-
if CONFIG_XXX = m sb.o编成sb.ko
-
else other , 不编
obj-m += camera.o camera-objs += a.o b.o camera-$(CONFIG_MEIYANG) += mei.o
-
-
obj-$(CONFIG_XXX) += xxx/
- 表示你如果选择了CONFIG_XXX请到子目录xxx下面去读Makefile
-
-
2.2 内核编译的两大步骤
- 1、配置
make menuconfig
:=> 生成一个人性化的配置菜单树(供你选择)- sudo apt-get install libncurses5-dev
- 目的是生成一个 .config (配置文件,决定哪些文件编译,哪些不编译)
- CONFIG_FOO = y
- CONFIG_MM = m
- CONFIG_XX = n
- 2、编译 make(sudo ./mk -k)
- a. 先读.config里面的内容,把相应的变量值替换到Makefile中去
- obj-$(CONFIG_FOO) += foo.o
- obj-$(CONFIG_MM) += mm.o
- obj-$(CONFIG_XX) += xx.o
- ----->
- obj-y += foo.o
- obj-m += mm.o
- obj-n += xx.o
- b. 编译
- foo.o -> foo.o -> vmlinux
- mm.c -> mm.o -> mm.ko
- a. 先读.config里面的内容,把相应的变量值替换到Makefile中去
- 3、一个例子
- 先准备好下面的文件:my_char_drivers/hello.c,Kconfig,Makefile
- (1) 把my_char_drivers整个目录拷贝到 内核源码目录的 drivers/char
- (2) 修改 drivers/char/Kconfig 增加一行,让其包含my_char_drivers/Kconfig
- vim dirvers/char/Kconfig 增加一行
- source “drivers/char/my_char_drivers/Kconfig”
- (3) 修改 drivers/char/Makefile 增加一行,让其包含my_char_drivers/Makefile
- vim drivers/char/Makefile 增加-行
- obj-$(CONFIG_zhoulong_drivers) += my_char_drivers/
2.3 .config的内容
- Kconfig
- Kconfig是作为.config的配置文件
- 内容是用kconfig特有的语言编写
- 配置信息的数据库是一个配置选项的集合
- Kconfig 语法
- config
- config <symbol>
- <config options>
-
关键字config开始一个新的配置入口,紧接着的一行是上一个选项的属性,举例:
config FOO tristate prompt "a test" depends on BAR default m help "a example for config entry"
-
- menuconfig
- menuconfig <symbol>
- <config options>
- menu/endmenu
- menu “some prompt info”
- <menu options>
- <menu block>
- endmenu
- if/endif
- if <expr>
- endif
- source
- source “xxx/xxx/Kconfig”
- choice/endchoice
- choice [symbol]
- <choice options>
- <choice block>
- endchoice
- 一个选择只能是一个布尔值或三态,布尔选项只允许单个配置选项被选中,但是三态选择还允许将任意数量的配置项设置为“m”。
- 这个可以用在如果一个硬件有多个驱动程序存在并且只有一个驱动程序可以编译进内核,但是所有的驱动程序可以编译成模块
- comment
- comment “some prompt info”
- <comment options>
- 这定义了一个注释,它在配置过程中显示给用户,并且也与输出到输出文件。唯一可能的选项是依赖项。
- config