源码包编译方法-让您快速高效掌握linux内核编译流程

Linux内核编译

1、Linux内核的配置与编译:

1.配置内核

1)导出默认配置:

makexxxx_defconfig

注1:xxxx表示内核支持的芯片名称,如makeexynos_defconfig

注2:每个支持的芯片在内核源码中都有默认配置,而默认配置很少只能保证系统完成最基本的功能

注3:可以通过直接更改.config文件来配置内核(麻烦),所有内核配置的本质都是更改.config文件

注4:配置文件中的xxxx=y表示添加该功能,注释表示不添加该功能(减少内核体积)

2)更改配置(内核提供了几种简单的配置方法,其本质就是更改.config文件中的配置)

makegconfig 依赖 GTK 库

makexconfig 依赖于 QT 库

makeconfig 麻烦

->makemenuconfig

选定状态开关:空格

搜索一个选项:/

[ ] 有两种状态。

输入Y,显示为“*”,表示该函数在内核中被选中,相关函数代码将被编译到内核中。

输入N,显示为空,说明内核中没有选择该函数。

<>有三种状态

输入Y,显示为“*”,表示选择内核中的函数

输入N,显示为空源码包编译方法,说明内核中没有选择该函数

输入M,会显示为“M”,说明选择内核中的函数作为模块(编译后与内核镜像不在同一个文件中)

2.编译内核

makeuImage编译内核镜像(将选项选为“*”编译到内核)

makemodules 编译内核模块(编译选项选为“M”)

makedtbs编译设备树文件(使驱动程序和设备之间的关系变得完美的文件)

makeclean 删除文件

2.向内核添加子菜单

每级目录都包含一个Kconfig文件,用于生成可选菜单。 你可以根据Kconfig的句型改变相应的Kconfig文件,在菜单中添加自己的选项。在Kconfig文件中,menu就是本级菜单,比如菜单“Characterdevices”。 如果我们想在这个菜单下添加子菜单,可以按照句型添加在menu和endmenu之间。

句型:

configFS4412_LED#固定句型,configXXX、XXX用于与MakeFile关联,即配置后MakeFile会根据配置进行编译

三态“FS4412LEDDeviceSupport”

#tristate“菜单显示名称”; tristate表示该选项有三种状态(即可以选择N/Y/M),bool表示有两个选项[](N/Y)

默认值

#defaultn默认为'N',即不添加该功能defaulty默认添加defaultm默认编译成模块(重新配置后生效)

取决于 ARCH_EXYNOS4

#dependson 依赖菜单 未选择依赖选项时不显示此选项

帮助

supportleddeviceonFS4412developboard#帮助文档可选

详细信息请参考:文档/kbuild

要将您自己的模块添加到菜单中:

1.更改Kconfig添加子菜单

2.添加对应的.C文件(驱动文件)

3、更改相应的Makefile,将菜单与编译关联起来(编译驱动文件)

3、linux内核(uImage)的编译过程:

1、在顶层目录下执行makeuImage

2、顶层目录下的MakeFile

第155章

#srctree为当前MakeFile所在目录

198ARCH?=arm#自己改的

第203章

504include$(srctree)/arch/$(SRCARCH)/Makefile

->includearch/arm/MakeFile

-> 执行makeuImage后,会根据我们设置的CPU架构执行对应架构下的MakeFile

3. arch/arm/MakeFile

291boot:=拱/臂/启动

第299章

#uImage 是 BOOT_TARGETS 的成员

304$(BOOT_TARGETS):vmlinux

#生成uImage需要生成BOOT_TARGETS大目标

#依赖源码顶层目录中的vmlinux(编译时生成的文件)

第305章

#Q是@的封装,不输出编译信息

#MAKE是make-C的封装 -C表示切换到指定目录下的MakeFile

#$(build)=$(boot)->build=arch/arm/boot

#MACHINE=$(MACHINE)->MACHINE:=arch/arm/mach-exynos

#$(boot)/$@->arch/arm/boot/uImage

->make-Carch/arm/bootMACHINE=arch/arm/mach-exynosarch/arm/boot/uImage

->依赖顶层目录中的vmlinux,切换到arch/arm/boot下的MakeFile(参数为MACHINE)并执行,在arch/arm/boot/下生成目标uImage(uImage就在该目录下)

/********************机器变量的来源********************/

.config/291CONFIG_ARCH_EXYNOS=y

155机器-$(CONFIG_ARCH_EXYNOS)+=exynos

->.config 文件是在最初导出配置时形成的。 .config中仅包含形参CONFIG_ARCH_EXYNOS(其他已注释)

->machine-y+=exynos 表示 machine-y=exynos

232ifneq($(机器-y),)

#比较machine-y与空值(machine-y=exynos),不相等

233MACHINE:=arch/arm/mach-$(word1,$(machine-y))/#word1,$(machine-y)word 是一个函数,它从 machine-y 变量中获取第一个短语

->机器:=arch/arm/mach-exynos

/******************************************************** ***** ******************/

4. arch/arm/boot/Makefile

78$(obj)/uImage:$(obj)/zImageFORCE

#依赖zImageobj来表示当前MakeFile的路径。 FORCE强制编译,无论是否已编译。

79@$(check_for_multiple_loadaddr)

80$(callif_changed,uimage)

81@$(kecho)'Image$@isready'#输出信息

->依赖当前目录下的zImage生成uImage

-> 跟踪 zImage

30ifeq($(CONFIG_XIP_KERNEL),y)

#CONFIG_XIP_KERNEL 在.config中定义,无形参

41其他

54$(obj)/zImage:$(obj)/压缩/vmlinuxFORCE

#依赖arch/arm/boot/compressed/vmlinux(和之前的不一样)

55$(callif_changed,objcopy)

#使用gcc编译的程序都是elf格式,需要转换成二进制补码格式。

56@$(kecho)'内核:$@isready'#显示信息

51$(obj)/压缩/vmlinux:$(obj)/ImageFORCE

#vmlinux 依赖于 arch/arm/boot/Image

52$(Q)$(MAKE)$(build)=$(obj)/压缩$@

#make-Carch/arm/boot/compressedarch/arm/boot/compressed/vmlinux

->依赖arch/arm/boot/Image源码包编译方法,切换到arch/arm/boot/compressed/下的MakeFile生成vmlinux

/************机器参数参考********************/

拱/臂/启动/Makefile

14ifneq($(机器),)

在#arch/arm/MakeFile中传递参数,输入MACHINE=arch/arm/mach-exynos

15include$(srctree)/$(MACHINE)/Makefile.boot

#includearch/arm/mach-exynos/Makefile.boot

16 结束

arch/arm/mach-exynos/Makefile.boot

1zreladdr-y+=0x40008000

#内核入口地址(运行起始地址)

2params_phys-y:=0x40000100

#uboot和内核协商存储参数的位置。

拱/臂/启动/Makefile

22ZRELADDR:=$(zreladdr-y)

#ZRELADDR=0x40008000

23PARAMS_PHYS:=$(params_phys-y)

#PARAMS_PHYS=0x40000100

24INITRD_PHYS:=$(initrd_phys-y)

25

26exportZRELADDRINITRD_PHYSPARAMS_PHYS

#Import 使其在全球范围内可用

/******************************************************** ***** **************/

5.arch/arm/boot/压缩/MakeFile

185$(obj)/vmlinux:$(obj)/vmlinux.lds$(obj)/$(HEAD)$(obj)/piggy.$(suffix_y).o

186$(addprefix$(obj)/,$(OBJS))$(lib1funcs)$(ashldi3)

187$(bswapsdi2)强制

#vmlinux 依赖很多文件来形成

#依赖文件来源

#$(obj)/vmlinux.lds

#arch/arm/boot/compressed/vmlinux.lds链接脚本决定了elf文件(内核源文件)的布局

#$(obj)/$(HEAD)=arch/arm/boot/compressed/$(HEAD)

#25HEAD=head.o由head.S生成(内核源文件)

#$(obj)/piggy.$(suffix_y).o

#86suffix_$(CONFIG_KERNEL_GZIP)=gzip

#.config/40CONFIG_KERNEL_GZIP=y导出默认配置时配置的内核的压缩格式

#->suffix_y=gzip

#->$(obj)/piggy.$(suffix_y).o=arch/arm/boot/compressed/piggy.gzip.o是由piggy.gzip.S生成的(编译时生成)

#$(addprefix$(obj)/,$(OBJS))#给变量$(OBJS)添加前缀$(addprefix$(obj)/)

#26OBJS+=misc.odecompress.o->OBJS=misc.odecompress.o

#->$(addprefix$(obj)/,$(OBJS))=arch/arm/boot/compressed/misc.odecompress.o由misc.cdecompress.c(内核源文件)生成

#这两个文件是用来解压内核的。 内核包含解压代码。

#$(lib1funcs)

#148lib1funcs=$(obj)/lib1funcs.o->lib1funcs=arch/arm/boot/compressed/lib1funcs.o(由lib1funcs.S生成)

#150$(obj)/lib1funcs.S:$(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S(内核源文件)

#$(ashldi3)

#154ashldi3=$(obj)/ashldi3.o->ashldi3=arch/arm/boot/compressed/ashldi3.o(ashldi3.S生成)

#156$(obj)/ashldi3.S:$(srctree)/arch/$(SRCARCH)/lib/ashldi3.S(内核源文件)

#$(bswapsdi2)

#160bswapsdi2=$(obj)/bswapsdi2.o->bswapsdi2=arch/arm/boot/compressed/bswapsdi2.o(由bswapsdi2.S生成)

#162$(​​obj)/bswapsdi2.S:$(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S(内核源文件)

/****************************piggy.gzip.o**************** ** ******************/

#195$(obj)/piggy.$(suffix_y).o:$(obj)/piggy.$(suffix_y)FORCE->piggy.gzip.o:piggy.gzip->piggy.gzip.o 取决于 Piggy。压缩包

#192$(obj)/piggy.$(suffix_y):$(obj)/../ImageFORCE->piggy.gzip:arch/arm/boot/ImageFORCE->piggy.gzip依赖下层目录下的Image

->返回下层目录跟踪arch/arm/boot/Image

/******************************************************** ***** **********************/

6.arch/arm/boot/MakeFile

47$(obj)/图片:vmlinuxFORCE

#依赖顶层源码下的vmlinuxFORCE来执行

48$(callif_changed,objcopy)

49@$(kecho)'内核:$@isready'

->返回顶层源码跟踪vmlinux

7.顶层目录MakeFile

817vmlinux:脚本/link-vmlinux.sh$(vmlinux-deps)强制

#scripts/link-vmlinux.sh 编译所需脚本

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

#追踪某些路径下的源文件

#802exportKBUILD_VMLINUX_INIT:=$(head-y)$(init-y)

#803exportKBUILD_VMLINUX_MAIN:=$(核心-y)$(库-y)$(驱动程序-y)$(网络-y)

#804exportKBUILD_LDS:=arch/$(SRCARCH)/kernel/vmlinux.lds

#链接脚本(两个链接过程)

倒序总结:uImage是zImage使用uboot中的工具在其上添加一个back来生成的。

zImage是由arch/arm/boot/compressed/vmlinux(elf格式)文件通过二进制补码格式转换生成的。

vmlinux是根据vmlinux.lds链接(二级链接)从/arch/arm/boot/compressed/piggy.gzip(压缩内核)和misc.c、decompress.c(用于解压内核的代码)生成的

piggy.gzip 是从 /arch/arm/boot/Image 文件(不包含解压代码的二进制补码内核文件)压缩而来的

Image文件是由源码顶层目录中的vmlinux(elf格式)进行二进制补码转换生成的。

vmlinux是基于链接脚本arch/arm/kernel/vmlinux.lds(一个链接)由一系列内核源代码和工具生成的

时序总结:按照arch/arm/kernel/vmlinux.lds和各级Makefile的规则编译一系列源码和工具,在源码顶层目录生成vmlinux(elf格式内核),这是第一个链接。

vmlinux通过二进制补码转换生成arch/arm/boot/Image(二进制补码格式的内核)

将Image文件压缩得到piggy.gzip文件(压缩二进制补码内核)(piggy.gzip文件需要解压才能运行)

Piggy.gzip和解压文件misc.c、decompress.c等的代码根据链接脚本arch/arm/boot/compressed/vmlinux.lds链接成一个文件(第二链接)vmlinux(elf)

通过二进制补码转换将vmlinux文件转换为zImage。

zImage通过添加回生成uImage

关于嵌入式物联网,确实有很多东西需要学习。 不要学错路线和内容,导致你错失薪​​资!

我免费给大家分享一个数据包,差不多150G。 以上学习内容、面试、项目都比较新、全面! 网上买一条鱼,恐怕起码要几十块。加莫莫发布信息

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 源码包编译方法-让您快速高效掌握linux内核编译流程 https://www.wkzy.net/game/196200.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务