内核编译-分析编译流程

前言

写文章的目的是想通过记录自己的学习过程,以便以后使用到相关的知识点可以回顾和参考。

编译流程

其实内核的编译跟uboot编译差不多,uboot的编写方式就是参考内核源码来的,等下分析的顶层Makefile就能看出来了,下面是内核编译的流程:

1、make distclean ------第一次编译时需清理一下工程文件
2、make xxx_defconfig------xxx一般是半导体厂家根据soc的架构或者名称命名的,xxx_defconfig是半导体厂家提供的内核默认配置文件,在arch\arm\configs中

3、make menuconfig------在默认配置基础上,通过图形化界面追加一些配置选项
4、make all------编译生成zImage,会生成在arch\arm\boot中

其中,配置后会在内核根文件目录下生成一个.config文件,里面就是具体的配置的内容。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210429121338984.png

分析流程

分析流程之前先理解一下各层Makefile的作用和区别
在这里插入图片描述

一、清理工程

make distclean跟清理uboot工程一样,通常是第一个编译时需要清理,如果后续通过make menuconfig图形化界面追加配置了内核,千万不要执行这个清理命令,不然配置都会被清掉。

二、配置内核

在arch\arm\configs中有很多以xxx_defconfig命名的文件,选择一个跟自己板子相似的配置文件,然后使用命令make xxx_defconfig进行配置

它的具体执行在顶层Makefile中的体现如下:

%config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

build 定义在文件 scripts/Kbuild.include 中,值为 build := -f $(srctree)/scripts/Makefile.build obj
obj,展开就是:make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
Makefile.build 会读取 scripts/kconfig/Makefile 中的内容,此文件中有如下内容:

%_defconfig: $(obj)/conf
	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

目标%_defconfig 与 xxx_defconfig 匹配,所以会执行这条规则,将其展开就是:

%_defconfig: scripts/kconfig/conf
scripts/kconfig/conf --defconfig=arch/arm/configs/%_defconfig Kconfig

%_defconfig依赖scripts/kconfig/conf,所以会编译scripts/kconfig/conf.c生成conf这个软件。
此软件就会将%_defconfig 中的配置输出到.config 文件中,最终生成内核根目录下
的.config 文件。

二、编译内核

通过顶层Makefile可以知道all依赖vmlinux,而vmlinux就是编译出来的内核文件了,但是它是ELF格式的文件,在arch/arm/Makefile中需要把它
转换成最终的zImage二进制内核镜像文件。下面分析下vmlinux是如何生成的。
首先在顶层Makefile中找到vmlinux

vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
	+$(call if_changed,link-vmlinux)

依赖于$(vmlinux-deps),在顶层Makefile中可以知道

vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)

将其展开得:

vmlinux-deps := arch/$(SRCARCH)/kernel/vmlinux.lds  $(head-y) $(init-y)   $(core-y) $(libs-y)  $(drivers-y) $(net-y)

综上所述:

vmlinux依赖于:scripts/link-vmlinux.sh,FORCE,arch/$(SRCARCH)/kernel/vmlinux.lds
$(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)

然后重点是这6个变量的值 $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)
我们可以通过顶层Makefile 和 arch/arm/Makefile把这6个变量展开得:

head-y = arch/arm/kernel/head.o
init-y = init/built-in.o
core-y = usr/built-in.o arch/arm/vfp/built-in.o \
		arch/arm/vdso/built-in.o arch/arm/kernel/built-in.o \
		arch/arm/mm/built-in.o arch/arm/common/built-in.o \
		arch/arm/probes/built-in.o arch/arm/net/built-in.o \
		arch/arm/crypto/built-in.o arch/arm/firmware/built-in.o \
		arch/arm/mach-imx/built-in.o kernel/built-in.o\
		mm/built-in.o fs/built-in.o \
		ipc/built-in.o security/built-in.o \
		crypto/built-in.o block/built-in.o
libs-y = arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o
drivers-y = drivers/built-in.o sound/built-in.o firmware/built-in.o
net-y = net/built-in.o

从上面可以知道这6个变量都是一些 built-in.o 或.a 等文件,这个和 uboot 一样,都是将相应目录中的源码文件进行编译,然后在各自目录下生成 built-in.o 文件,有些生成了.a 库文件。最终将这些 built-in.o 和.a 文件进行链接即可形成 ELF 格式的可执行文件,也就是 vmlinux!但是链接是需要链接脚本的,vmlinux 的依赖 arch/arm/kernel/vmlinux.lds 就是整个 Linux 的链接脚本。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值