Makefile之---linux内核Makefile和Kconfig的浅要分析

本文深入探讨了Linux内核中顶层Makefile的作用及其内部结构,详细解析了内核编译流程、连接顺序及关键文件的角色。通过分析顶层Makefile的内容,解释了内核如何被划分为不同类别并最终生成内核镜像文件vmlinux的过程。同时,文章还介绍了内核配置文件Kconfig的用法,展示如何通过配置界面定制内核特性。

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

内核中那些文件将被编译?他们是怎样被编译的?他们连接时顺序如何确定?那个文件在最前面?内核最先执行的文件怎样确定?这些都是通过Makefile来管理的。

a)顶层Makefile它是所有Makefile文件的核心,从总体上控制内核编译,连接

b).config配置文件(make menuconfig内核配置完之后自动生成),所有Makefile文件都是根据.config来确定使用那些文件的

c)arch/$(ARCH)/Makefile对应体系的Makefile(如arch/arm/Makefile),它用来决定那些体系结构相关的文件参与内核的生成,并提供一些规则来生成特定格式的内核镜像

d)各级目录下的Makefile文件,它们被上一层Makefile调用来编译当前目录下文件

接下来看一下内核顶层的Makefile内容如下:

461 # Objects we will link into vmlinux / subdirs we need to visit
462 init-y := init/
463 drivers-y := drivers/ sound/ firmware/
464 net-y := net/
465 libs-y := lib/
466 core-y := usr/
....

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

可以看到顶层Makefile将14个目录分成5类:init-y ,drivers-y,net-y ,libs-y,
core-y,除去include和arch目录没有包含进来,arch在arch/$(ARCH)/Makefile中被包含进内核如下

441 include $(srctree)/arch/$(SRCARCH)/Makefile
在arch/arm/Makefile下可以看到

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

182 # If we have a machine-specific directory, then include it in the build.
183 core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
184 core-y += $(machdirs) $(platdirs)
185 core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
186 core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
187 core-$(CONFIG_VFP) += arch/arm/vfp/
188
189 drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
190
191 libs-y := arch/arm/lib/ $(libs-y)
94行那里除了前面5类子目录又多了一种head-y,不过他直接以文件名出现,对于arm处理器$(MMUEXT)为空,通过分析可知内核执行的第一个文件就是arch/arm/kernel/head.S(可以看我的另一篇博文)。

当我们编译内核时,将依次进入init-y ,drivers-y,net-y ,libs-y,core-y所列出的目录执行他们的Makefile,每个子目录都会生成一个built-in.o(libs所列目录下有可能生成lib.a文件),最后head-y所表示的文件和这些built-in.o,lib.a一起连接成内核镜像文件vmlinux.

在顶层Makefile中可以看到如下

670 vmlinux-init := $(head-y) $(init-y)
671 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
672 vmlinux-all := $(vmlinux-init) $(vmlinux-main)
673 vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds
第672行的vmlinux-all表示构成内核镜像文件的vmlinux的目标文件,这里就不展开各个文件了,可以看我另一篇博文,从中可以知道这些目标文件的顺序为head-y,init-y,core-y,libs-y,net-y.

具体怎样连接要看内核连接脚本,对于arm体系连接脚本就是arch/arm/kernel/vmlinux.lds,它由arch/arm/kernel/vmlinux.lds.S文件生成。

最后还看一下在顶层Makefile中的

634
635 init-y := $(patsubst %/, %/built-in.o, $(init-y))
636 core-y := $(patsubst %/, %/built-in.o, $(core-y))
637 drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
638 net-y := $(patsubst %/, %/built-in.o, $(net-y))
639 libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
640 libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
641 libs-y := $(libs-y1) $(libs-y2)
上面的patsubst是个字符串处理函数,进行了上面转换之后init-y变成init/built-in.o,表示要连接进内核,其它的一样。

上面说的主要是顶层Makefile下面说一下各个目录下的Makefile这个相对来说简单一点

58 obj-$(CONFIG_TLAN) += tlan.o
59 obj-$(CONFIG_EPIC100) += epic100.o
60 obj-$(CONFIG_SIS190) += sis190.o
61 obj-$(CONFIG_SIS900) += sis900.o
62 obj-$(CONFIG_R6040) += r6040.o
63 obj-$(CONFIG_YELLOWFIN) += yellowfin.o
64 obj-$(CONFIG_ACENIC) += acenic.o
65 obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
66 obj-$(CONFIG_NATSEMI) += natsemi.o
67 obj-$(CONFIG_NS83820) += ns83820.o
68 obj-$(CONFIG_STNIC) += stnic.o 8390.o
69 obj-$(CONFIG_FEALNX) += fealnx.o
70 obj-$(CONFIG_TIGON3) += tg3.o
71 obj-$(CONFIG_BNX2) += bnx2.o
就像上面列出的一样,直接把文件名*.c在Makefile中按照一定格式改成*.o就可以了,最后编译完之后会生成一个*.o文件和一个built-in.o

下面分析一下内核Kconfig

linux内核中所有配置工具都是通过读取arch/arm/Kconfig文件来生成配置界面的,这个文件是所有配置文件的入口,它会包含其他目录的Kconfig文件进来。

我们内核中每个子目录中都会有一个Makefile和Kconfig文件,每个目录下的Kconfig文件是配置界面的源文件。

下面我们来看一下arch/arm/Kconfig文件,看看他是怎样包含别的Kconfig文件的

555 source "arch/arm/mach-clps711x/Kconfig"
556
557 source "arch/arm/mach-ep93xx/Kconfig"
558
559 source "arch/arm/mach-footbridge/Kconfig"
560
561 source "arch/arm/mach-integrator/Kconfig"
562
563 source "arch/arm/mach-iop32x/Kconfig"
564
565 source "arch/arm/mach-iop33x/Kconfig"
其中source表示包含后面目录的Kconfig,这样我们就可以把分散在其它目录Kconfig组合在一次了

下面来看一下Kconfig中每个菜单是怎样生成的

Kconfig文件的基本要素config条目,config条目是用来生成菜单的,通常被其它条目包含

22 config MFD_SM501_GPIO
23 bool "Export GPIO via GPIO layer"
24 depends on MFD_SM501 && GPIOLIB

default y
25 ---help---
26 This option uses the gpio library layer to export the 64 GPIO
27 lines on the SM501. The platform data is used to supply the
28 base number for the first GPIO line to register.
29
其中config为关键字,表示一个配置项开始,接着的是MFD_SM501_GPIO配置项名称也就是我们在.config中看到的项,这里省略了CONFIG_,第23行bool表示变量类型,在Kconfig中变量类型主要有bool,tristate,string,hex,int,其中tristate,string是两种基本类型,bool变量取值为两种y和n,tristate为三种y,m,n,bool之后就是字符串提示信息也就是我们在配置是看到的名称,

depends on表示依赖关系例子中表示依赖MFD_SM501 与 GPIOLIB,意思是只有这两项也选上了Export GPIO via GPIO layer才会显示出来才能选

default y 表示默认值为y

"select" <symbol>选择关系也就是A如果选了B,在A被选中的时候B自动选中

8 config ARM
9 bool
10 default y
11 select HAVE_AOUT
12 select HAVE_IDE
13 select RTC_LIB
"prompt" <prompt>提示信息

help帮助信息

下面再来介绍一下menu条目

menu条目用于生成菜单

menu "Floating point emulation"

config FPE_NWFPE

....

config FRE_NEFPE_XP

.....

....

endmenu

menu...endmenu中可以包含很多config条目,它相当于一个大的菜单

还有choice...endchoice也一样这个是将多个类似的菜单放在一次和menu格式差不多

198 choice
199 prompt "ARM system type"
200 default ARCH_VERSATILE
201
202 config ARCH_AAEC2000
203 bool "Agilent AAEC-2000 based"
204 select ARM_AMBA
205 select HAVE_CLK
206 help
207 This enables support for systems based on the Agilent AAEC-2000
208
209 config ARCH_INTEGRATOR
210 bool "ARM Ltd. Integrator family"
211 select ARM_AMBA
212 select HAVE_CLK
...

endchoice

comment条目是定义一些帮助信息,这里就不说了

下面通过一个例子来说明Kconfig和Makefile的关系

假设我们要在源码目录drivers目录下增加一个test目录里面内容只有一个myleds.c文件

这时我们要做的就是在这个目录里增加Makefile和Kconfig使运行make menuconfig时能进行菜单选择

在新增的test目录下,Kconfig如下

1 menu "TEST Driver"
2 comment "TEST Driver"
3
4 config CONFIG_TEST
5 bool "TEST support"
6 config CONFIG_TEST_USER
7 tristate "TEST user-space interface"
8 depends on CONFIG_TEST
9 endmenu

上面首先创建一个菜单TEST Driver,然后显示TEST support给用户选择,接下来就是判断是否选择了,来进一步显示子菜单功能

为了这个Kconfig起作用,我们还要修改arch/arm/Kconfig文件,增加

source "drivers/test/Kconfig"
下面是test目录Makefile文件

obj-$(CONFIG_TEST) += myled.o hello.o
为了能编译到test目录父目录下Makefile要新增内容如下:

obj-y += test/

这样就可以了

到了这里Makefile和Kconfig就分析完了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值