内核Makefile

本文详细解析了Linux内核Makefile的工作原理,包括决定编译哪些文件、如何编译以及链接顺序。介绍了顶级Makefile、体系结构相关Makefile、子目录Makefile的角色,以及.config配置文件对编译过程的影响。同时,阐述了编译选项的分类和链接过程中的字符串处理函数应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

. Documentation/kbuild/makefiles.txt

 

. Makefile的作用:

1). 决定编译哪些文件

2). 怎么编译这些文件

3). 怎么样链接这些文件(顺序)

 

 

. Makefile 类别:

//顶层Makefile

. Makefile the top Makefile.

 

//体系结构相关Makefile

. arch/$(ARCH)/Makefile the arch Makefile.

具体体系结构相关的哪些文件被编译。

并提供一些规则来生成对应体系结构的image.

 

//子目录Makefile

. kbuild Makefiles there are about 500 of these.

 

//配置文件

. .config the kernel configuration file.

 

//Makefile共用规则、脚本

. scripts/Makefile.* common rules etc. for all kbuild Makefiles.

 

. 根据Makefile的3个作用来分析上面这5类文件:

1. 决定编译哪些文件

==================

 

内核的编译过程从top Makefile开始,然后递归的调用各级子目录中的Makefile,

分为以下3步:

1). top Makfiel决定内核根目录下的哪些子目录被编译进内核.

2). arch/$(ARCH)/Makefile决定arch/$(ARCH)下的哪些文件和目录被编译进内核.

3). 子目录Makefile决定子目录中哪些文件和目录被编译进内核,或编译成模块,或进入下一级目录继续调用Makefile.

 

1). top Makefile:

-----------------

 

. 根下的13个子目录分为5类:

init-y := init/

drivers-y := drivers/ sound/

net-y := net/

libs-y := lib/

core-y := usr/

core-y          += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

 

. 除去include和2个和无源码的目录

. 还有一个arch目录,在include $(srctree)/arch/$(ARCH)/Makefile中包含。

 

2). arch/$(ARCH)/Makefile

-------------------------

 

ARCH ?= arm

CROSS_COMPILE ?= arm-linux-

 

e.g: arch/arm/Makefile

//新类别head-y, 以文件名出现,head指定的都被链接在最前面

head-y          := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

. 说明:

head$(MMUEXT)

= head-nommu.S

or

= head.S

 

core-y                          += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/

 

core-y                          += $(machdirs) $(platdirs)

. 说明:

$(machdirs) = mach-s3c2410 mach-s3c2440

$(platdirs) = plat-s3c24xx

 

libs-y                          := arch/arm/lib/ $(libs-y)

 

core-$(CONFIG_xxx)

CONFIG_xxx在.config配置中得到,

y - 编译进内核

m - 模块

 

. 内核编译时,会根据5类top Makefile中的xxx-y,进入对应的子目录,

在每个目录下生成built-in.o, libs-y所列目录会生成lib.a, 加上head-y指定的head.o将它们按照一定的

顺序(head在最前面)链接成一个内核image -- vmlinux.

 

3). 各级子Makefile

------------------

 

obj-y -> built-in.o

obj-m -> 模块.ko

 

. built-in.o 还是模块.ko由配置文件的宏定义决定

obj-$(CONFIG_TEST) += test.o

 

 

.config:

在配置内核后生成一个.config配置文件,内核的Makefile就是根据它里面定义的Makefile中需要的

宏变量来决定哪些文件编译,怎么编译,和对代码功能的控制。

 

.config是在top Makefile中被间接包含的,

top Makefile包含的是auto.conf, 而auto.conf就是由.config生成的。

include/config/auto.conf

 

 

. 顺序:

obj-$(CONFIG_A) += a.o

obj-$(CONFIG_B) += b.o

如果被编译进内核,CONFIG_A/B = y

那么a.o中module_init(a_init)定义的a_init被先调用.

 

. 多文件组成:

obj-$(CONFIG_TEST) += test.o

test-objs := 1.o 2.o 3.o

 

. 有下级子目录:

obj-$(CONFIG_TEST) += lee/

这样就会自动进入下级子目录lee下看它的Makefile

 

e.g:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test/

Makefile

-------------

obj-$(CONFIG_TEST) += lee/

 

-------------

lee/

1.o 2.o Makefile

--------------

obj-$(CONFIG_LEE) += lee.o

lee-objs := 1.o 2.o

--------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

 

 

2. 怎么编译这些文件

===================

 

即编译选项的问题.

kernel编译选项有3类:

1) 全局的(适用于整个内核代码树)

2) 局部的(仅用于某个Makefile文件)

3) 个体的(仅适用于某个源代码文件.c)

 

. 1)全局:

在top Makefile和arch/arm/Makefile中被定义.

CFLAGS

AFLAGS

LDFLAGS

ARFLAGS

 

. 2)局部的:

各子目录中的Makefile中定义,

EXTRA_CFLAGS

...

. 3)个体的:

CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF

在gcc -Dxxx

 

以上3各编译选项在scripts/Makefile.lib中一起使用。

 

3. 怎么样链接,顺序

==================

. 根据2个顶层Makefile(Makefle, arch/arm/Makefile)定义的6类

head-y, init-y, drivers-y, net-y, libs-y, core-y

 

在这2个Makefile中将这6类找到, 可见除head-y定义的是文件,

其他的都定义的为目录.

 

那么这些目录是如何链接的呢,换句话说如何将这些目录下的所有.o链接起来的?

就是将这些目录下的所有.o统一到built-in.o中去,然后链接e.g:drivers/built-in.o

就可以了。

 

. patsubst字符串处理函数

$(patsubst pattern, replacement, text)

在"text"字串中找到"pattern",然后用replacement来替换它。

e.g:

test-y := a/ b/

test-y := (patsubst %/, %/built-in.o, $(test-y))

--->

 

test-y := a/built-in.o b/built-in.o

 

. vmlinux-all & vmlinux-lds:

如果是arm架构的vmlinux, 链接脚本vmlinux-lds := arch/arm/kernel/vmlinux.lds

 

 

. 内核Makefile总结:

~~~~~~~~~ 哪些文件被编译 ~~~~~~~~~~~~~~~~

1. .config配置文件定义宏变量,Makefile根据它来决定哪些文件被编译进内核,哪些编译成模块,代码中的宏.

2. 顶层Makefile和arch/$(ARCH)/Makefile决定根目录下哪些文件和子目录参加编译.

3. 子目录Makefile根据.config的宏变量定义决定哪些文件和目录参与编译,如果编译是编译进内核还是模块。

还可以进入下一级子目录继续调用下一级子目录的Makefile。

 

.config的宏变量:

CONFIG_xxx = y

CONFIG_xxx = m

CONFIG_xxx = not set //不被编译

 

~~~~~~~~~ 怎么编译 ~~~~~~~~~~~~~~~~

4. Makefile中定义的全局,局部,个体的编译选项影响如何编译.

 

~~~~~~~~~ 顺序, 链接 ~~~~~~~~~~~~~~~~~~~~~

5. 顶层Makefile按照一定的顺序组织文件,最后用arch/arm/kernel/vmlinux.lds链接成vmlinux.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值