分类:
2011-03-16 10:40:13
原文地址:Linux内核Makefile简述 作者:自语的骆驼
前言
本文记录了本人通过阅读内核文档makefile.txt所提炼的本人认为对linux驱
动开发有帮助的知识要点。敬请指出错误和不足。
----------------------------------------------------------------------------------
内核Makefile的框架
---------------------->
|
|- Makefile
|
|- .config
|
|- arch
| |- $(ARCH)
| |- Makefile
|
|- scripts
| |- Makefile.*
|
|-
| |- kbuild Makefile
根据内核配置文件,通过向下访问makefile的方式,制作内核文件vmlinux与模块文件。
# .config
有内核配置程序所生成。
# arch/$(ARCH)/Makefile
向顶层Makefile提供硬件架构的特别信息,与对象机器硬件架构对应的Makefile会被顶
层Makefile所包含。
# scripts/Makefile.*
包含用于编译内核的kbuild Makefile规则。
# kbuild Makefile
执行上层Makefile传递下来的命令,从.config中提取信息,生成Kbuild,完成内核编
译所需的文件列表。
----------------------------------------------------------------------------------
.config
.config文件可以被理解为一个Makefile的变量表,该文件记录了内核Makefile中与特定文件
编译是否被编译相关变量的值。内核配置程序根据每个目录下的KCONFIG文件生成内核配置程序
选项界面,用户通过该界面设定了需要编译的功能,内核配置程序再根据KCONFIG中的内容生成
了不同的变量,并把该变量导入到.config,供内核编译时参照调用。
---------------------------------------------------------------------------------
架构Makfile
顶层Makefile为各子目录下Makefile包含的公共部分,而顶层Makefile又首先包含了arch/
$(ARCH)/Makefile。该架构Makefile包含了针对特定架构的配置信息,相关变量及目标等。
一具体架构Makefile的具体目的就是,将生成并压缩 vmlinux 文件,写入启动代码,并将其拷
贝到正确的位置。这就包含了多种不同的安装命令。该具体目的也无法在各个平台间进行标
准化。一般,附加的处理命令入在arch/$(ARCH)/下的boot目录。
----------------------------------------------------------------------------------
Kbuild文件
内核使用Kbuild组织Kbuild Makefile。如果同一目录中同时出现Makefile与Kbuild,
Kbuild将会被使用。
编译内核文件的主要目标有两个:分别是obj-y和obj-m。
Kbuild Makefile规定所有编译进内核的目标文件存在$(obj-y)列表中,编译成模块的
目标文件存在$(obj-m)列表中。而这些列表依赖内核的配置文件。
修改目标内容采用以下方式:
obj-$(CONFIG_
此语句告诉内核,当前目录下有一名为filename.o的目标。此目标将由filename.c或
filename.s文件编译得到。
CONFIG_
Makefile只对当前目录对象负责,Kbuild通过辨别Kconfig中CONFIG_
的值来判断是否应该递归操作,但是它指代的值只能够是y(编译进内核)或m(编译成模块),其
余值一律不会被编译链接, 如:
#fs/Makefile
obj-$(CONFIG_EXT2_FS) = ext2/
如果,CONFIG_EXT2_FS的值有效,Kbuild就会递归访问ext2目录,递归的原因是ext2/是一个目录,
再调用该目录下的Makefile进行编译操作。
----------------------------------------------------------------------------------
Kbuild执行的步驟
1) 根据内核配置生成文件 .config
2) 将内核的版本号存储在 include/linux/version.h
3) 生成指向 include/asm-$(ARCH) 的符号链接
4) 更新所有编译所需的文件:
-附加的文件由 arch/$(ARCH)/Makefile 指定。
5) 递归向下访问所有在下列变量中列出的目录:
init-* core* drivers-* net-* libs-*
并编译生成目标文件。
-这些变量的值可以在 arch/$(ARCH)/Makefile 中扩充。
6) 链接所有的目标文件,在源代码树顶层目录中生成 vmlinux。
最先联接是在 head-y中列出的文件,该变量由
arch/$(ARCH)/Makefile 赋值。
7) 最后完成具体架构的特殊要求,并生成最终的启动镜像。
-包含生成启动指令
-准备 initrd 镜像或类似文件
----------------------------------------------------------------------------------
目标 obj-y
1). Kbuild编译所有的$(obj-y)文件,然后,然后将它们链接为build-in.o文件,最后
链接到vmlinux中。
2). 相同的目标可以在obj-y列表中重复出现,已成功链接到built-in.o的目标会被忽略。
3). 目标链接时是按顺序的。如果链接顺序出错,有可能造成硬盘数据出错。
----------------------------------------------------------------------------------
目标 obj-m
1). 一个文件编译一个模块
obj-$(CONFIG_
2). 多个文件编译一个模块
obj-$(CONFIG_
Kbuild能够识别目标文件的后缀为-objs和-y。kbuild通过CONFIG_符号来判断对象是
否用于组合。
----------------------------------------------------------------------------------
编辑标志
下面标志仅在它们所被指定的Kbuild makefile有效。
ccflags-y
用于编译C源代码的编译选项。源代码树拥有。
asflags-y
用于编译汇编源代码的编译选项。当前目录拥有。
ldflags-y
用于链接目标文件的选项。当前目录拥有。
CFLAGS_$(filename), AFLAGS_$(filenam)
编译源代码选项,单个文件拥有的。
----------------------------------------------------------------------------------
依赖跟踪
改变下面任意项内容,所有受影响文件将会重新被编译。
1). 所有参与编译的文件(*.o和*.h)
2). 所有参与使用的CONFIG_项
3). 用于编译的命令行
----------------------------------------------------------------------------------
相关变量列表
----------------------------------------------------------------------------------
KERNELRELEASE
$(KERNELRELEASE) 是一个字符串,类似"2.4.0-pre4",用于安装目录的命名或显示当前的版本号。
一部分架构Makefile使用该变量。内容通过cat include/config/kernel.release所得。
ARCH
该变量定义了目标架构,比如"i386","arm" 或"sparc"。有些Kbuild Makefile
根据 $(ARCH) 决定编译哪些文件。
默认情况下,顶层Makefile将其设置为本机架构。如果是跨平台编译,用户可以
用下面的命令覆盖该值:
make ARCH=m68k ...
INSTALL_PATH
该变量为架构Makefile定义了安装内核镜像与 System.map 文件的目录。
主要用来指明架构特殊的安装路径。
INSTALL_MOD_PATH,MODLIB
$(INSTALL_MOD_PATH) 为了安装模块,给 $(MODLIB) 声明了前缀。该变量不能
在Makefile中定义,但可以由用户传给Makefile。
$(MODLIB) 具体的模块安装的路径。顶层Makefile将$(MODLIB)定义为
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用户可以通过命令行
参数的形式将其覆盖。
INSTALL_MOD_STRIP
如果该变量有定义,模块在安装之前,会被剥出符号表。如果
INSTALL_MOD_STRIP 为 "1",就使用默认选项 --strip-debug。否则,
INSTALL_MOD_STRIP 将作为命令 strip 的选项使用。
---------------------------------------------------------------------------------------------
与设备驱动相关的琐碎
. 编译额外模块
make M=dir modules 顶层Makefile会调用dir目录下的Makefile去构造额外模块