让你快速高效的掌握linux内核编译过程

news2024/10/5 21:17:44

Linux内核编译

一、linux内核的配置与编译:

1.配置内核

1)导入默认配置:

make xxxx_defconfig

注1:xxxx表示内核支持的芯片的名称 比如make exynos_defconfig

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

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

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

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

make gconfig 依赖于GTK库

make xconfig 依赖于QT库

make config 麻烦

-> make menuconfig

选中的状态切换:空格

搜索一个选项:/

[ ] 有两种状态。

输入Y,显示为“*”,表示内核中该功能被选中,相关功能代码将会被编译进内核。

输入N,显示为空,表示内核中该功能没有被选中。

< > 有三种状态

输入Y,显示为“*”,表示内核中该功能被选中

输入N,显示为空,表示内核中该功能没有被选中

输入M,则显示为“M”,表示内核中该功能被选为模块(编译后与内核镜像不在同一文件)

2.编译内核

make uImage 编译内核镜像(编译选中为“*”的选项到内核)

make modules 编译内核模块(编译选中为“M”的选项)

make dtbs 编译设备树文件(使驱动与设备建立关系的文件)

make clean 删除文件

二、在内核中添加子菜单:

每一级目录中都包含一个Kconfig文件,用于生成选配菜单的。按照Kconfig的语法修改对应的Kconfig文件就可以在菜单中添加自己的选项。在一个Kconfig文件中menu是本级菜单,如menu "Character devices",如果我们想在该菜单下自己添加子菜单按照语法添加在menu和endmenu之间即可

语法:

config FS4412_LED # 固定语法,config XXX,XXX用来与MakeFile关联,即配置后MakeFile会按照该配置进行编译

tristate "FS4412LED Device Support"

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

default n

# default n 默认是'N',即不添加该功能 default y 默认添加该功能default m 默认编译成模块(重新配置后生效)

depends on ARCH_EXYNOS4

# depends on 依赖的菜单 当有依赖关系的选项没有被选择时该选项也不显示

help

support leddevice on FS4412 develop board # 帮助文档 可有可无

详情参考:Documentation/kbuild

将自己的模块添加到菜单的步骤:

1.修改Kconfig添加子菜单

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

3.修改对应的Makefile使菜单与编译关联(将驱动文件编译)

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

1.在顶层目录下执行make uImage

2.顶层目录下的MakeFile

155 srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))

# srctree为当前MakeFile所在目录

198 ARCH ?= arm # 自己修改的

203 SRCARCH := $(ARCH)

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

-> include arch/arm/MakeFile

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

3.arch/arm/MakeFile

291 boot := arch/arm/boot

299 BOOT_TARGETS = zImage Image xipImage bootpImage uImage

# uImage属于BOOT_TARGETS中的一个成员

304 $(BOOT_TARGETS): vmlinux

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

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

305 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

# 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 -C arch/arm/boot MACHINE=arch/arm/mach-exynos arch/arm/boot/uImage

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

/***************MACHINE变量的来源******************/

.config/291 CONFIG_ARCH_EXYNOS=y

155 machine-$(CONFIG_ARCH_EXYNOS) += exynos

-> 在最开始导入配置时产生了.config文件,.config中只对CONFIG_ARCH_EXYNOS进行了赋值(其他都注释)

-> machine-y += exynos 即 machine-y = exynos

232 ifneq ($(machine-y),)

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

233 MACHINE := arch/arm/mach-$(word 1,$(machine-y))/ # word 1,$(machine-y) word为函数 表示从machine-y变量中取第一个单词

-> MACHINE := arch/arm/mach-exynos

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

4.arch/arm/boot/Makefile

78 $(obj)/uImage: $(obj)/zImage FORCE

# 依赖于zImage obj表示当前MakeFile所在路径 FORCE强制编译不管是否编译过

79 @$(check_for_multiple_loadaddr)

80 $(call if_changed,uimage)

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

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

-> 追踪zImage

30 ifeq ($(CONFIG_XIP_KERNEL),y)

# CONFIG_XIP_KERNEL在.config中定义 没有赋值

41 else

54 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE

# 依赖arch/arm/boot/compressed/vmlinux(与之前不是同一个)

55 $(call if_changed,objcopy)

# 使用gcc编译出的程序都是elf格式的,需要进行二进制格式的转换

56 @$(kecho) ' Kernel: $@ is ready' # 显示信息

51 $(obj)/compressed/vmlinux: $(obj)/Image FORCE

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

52 $(Q)$(MAKE) $(build)=$(obj)/compressed $@

# make -C arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux

-> 依赖arch/arm/boot/Image,切换到arch/arm/boot/compressed/下的MakeFile生成vmlinux

/***********MACHINE参数的引用*******************/

arch/arm/boot/Makefile

14 ifneq ($(MACHINE),)

# arch/arm/MakeFile中传参进来MACHINE=arch/arm/mach-exynos

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

# include arch/arm/mach-exynos/Makefile.boot

16 endif

arch/arm/mach-exynos/Makefile.boot

1 zreladdr-y += 0x40008000

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

2 params_phys-y := 0x40000100

# uboot和内核协商好的存放参数的位置

arch/arm/boot/Makefile

22 ZRELADDR := $(zreladdr-y)

# ZRELADDR = 0x40008000

23 PARAMS_PHYS := $(params_phys-y)

# PARAMS_PHYS = 0x40000100

24 INITRD_PHYS := $(initrd_phys-y)

25

26 export ZRELADDR INITRD_PHYS PARAMS_PHYS

# 导出让全局可用

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

5.arch/arm/boot/compressed/MakeFile

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

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

187 $(bswapsdi2) FORCE

# vmlinux依赖很多文件产生

# 依赖文件的来源

# $(obj)/vmlinux.lds

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

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

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

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

# 86 suffix_$(CONFIG_KERNEL_GZIP) = gzip

# .config/40 CONFIG_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)/

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

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

# 这两个文件用于解压内核 内核当中包含了解压的代码

# $(lib1funcs)

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

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

# $(ashldi3)

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

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

# $(bswapsdi2)

# 160 bswapsdi2 = $(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.gzip

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

-> 退回上层目录追踪arch/arm/boot/Image

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

6.arch/arm/boot/MakeFile

47 $(obj)/Image: vmlinux FORCE

# 依赖顶层源码下的vmlinux FORCE强制执行

48 $(call if_changed,objcopy)

49 @$(kecho) ' Kernel: $@ is ready'

-> 退回顶层源码下追踪vmlinux

7.顶层目录MakeFile

817 vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE

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

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

# 追踪得到一些路径下的源文件

# 802 export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)

# 803 export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)

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

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

逆序总结:uImage由zImage通过uboot中的工具为其添加头部生成

zImage由arch/arm/boot/compressed/vmlinux(elf格式)文件经过二进制格式转换生成

vmlinux由/arch/arm/boot/compressed/piggy.gzip(压缩后的内核)和misc.c、decompress.c、(用于解压内核的代码)按照vmlinux.lds链接生成(二次链接)

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

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。(点击找小助理领取)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【博学谷学习记录】超强总结,用心分享|架构师-RabbitMQ消息可靠性保障

文章目录一、生产者保证1.1 失败通知1.2 发送方确认1.3 Broker丢失消息二、消费方消息可靠性2.1 消费者手动确认消息依靠三个对象&#xff1a;生产者、消费者、broker一、生产者保证 生产者发送消息到broker时&#xff0c;要保证消息的可靠性&#xff0c;主要的方案有&#xf…

5.28 综合案例2.0-简易起夜灯

HaaS506 - 简易起夜灯简介准备硬件连接图功能实现1.继电器使用说明2. 5.8G雷达感应传感器模块说明3.简易代码3.1测试log简介 案例为了解决晚上起床找不到灯的问题。当你从床上起来时&#xff0c;雷达感应传感器检测到你的活动后自动打开电灯。省去了寻找电灯开关的麻烦。 准备…

java学习笔记 day07-Java基础-综合练习

练习一&#xff1a;飞机票 需求: ​ 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 ​ 按照如下规则计算机票价格&#xff1a;旺季&#xff08;5-10月&#xff09;头等舱9折&#xff0c;经济舱8.5折&#xff0c;淡季&#xff08;11月到来…

表白墙(web版)

文章目录前言一、需求分析1.表白墙页面设计2.表白墙功能二、实现1.客户端2.服务器端3.连接数据库前言 前面前端部分写过一个表白墙页面&#xff0c;但是它不能存储提交信息&#xff0c;为了能够让它在提交信息后可以保存其信息&#xff0c;页面刷新后信息依然存在&#xff0c;…

itk配准整理(1)

示例地址&#xff1a; itk\ITK\Examples\RegistrationITKv4\ImageRegistration7.cxx 说明&#xff1a;itk二维图像的配准&#xff1a;平移旋转缩放 效果图&#xff1a; 运行结果&#xff1a; 52 53.6213 [0.8333298229719548, -0.17450270771316403, -12.806452097490313, -1…

在Win10中使用YAMAHA S-YXG50软波表

曾经非常经典的一款软波表YAMAHA S-YXG50我个人非常的喜欢。在XP系统的时代&#xff0c;是我必装的软件&#xff0c;用来听一些MIDI音质和效果很好。而如今玩MIDI的人越来越少了&#xff0c;软波表的时代也被人渐渐的遗忘了。 如今想要怀旧的话&#xff0c;只能够找一台老电脑…

LINUX的XEN和KVM到底区别在什么地方?

本文调研的是 Completely Fair Scheduler 算法, 它当前是 Linux 中 SCHED_NORMAL(非实时任务) 一类 task 的默认调度器. 实际上, 运行在 Guest OS 中的应用程序线程还受到 Guest OS 的调度, 分时运行在 vCPU 上, 但这不在本文调研范围内. 本文仅调研 vCPU 被如何调度到 pCPU 上…

WebDAV之葫芦儿·派盘+无聊笔记

无聊笔记 支持webdav方式连接葫芦儿派盘。 无聊笔记是一款深受用户认可的系统工具,随时都可以进行软件的操作,也可以在线进行笔记的记录,系统会进行智能的保存,满足了用户日常中的需求,可以把软件作为备忘录,笔记本,摘抄录等。 无聊笔记是一个功能强大的记录工具,您…

代码随想录算法训练营第四十二天| LeetCode416. 分割等和子集

一、LeetCode416. 分割等和子集 1&#xff1a;题目描述&#xff08;416. 分割等和子集&#xff09; 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 2&#xff1a;解题思路 本题需要使用01背包的…

合作动态 | 方正璞华与日立签订战略合作协议,加快推进数字化管理变革!

2022年10月27日&#xff0c;方正璞华PLM事业部负责人王志起先生与日立方代表正式签订“方正璞华PLM产品销售合作框架协议”。 根据协议&#xff0c;双方将围绕璞华PLM产品推广、客户拓展、全生命周期运营服务等领域&#xff0c;开展多元化、多层级的深度融合合作&#xff0c;共…

HTML制作一个介绍自己家乡的网站——贵阳,排版整洁,内容丰富,主题鲜明

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

CV:计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念)、早期/中期/近期应用领域(偏具体应用)、经典CNN架构(偏具体算法)概述、常用工具/库/框架/产品、环境安装、常用数据集、编程技巧

CV&#xff1a;计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念)、早期/中期/近期应用领域(偏具体应用)、经典CNN架构(偏具体算法)概述、常用工具/库/框架/产品、环境安装、常用数据集、编程技巧 导读&#xff1a;计算机视觉技最强学习路线&#xff0c;博主花了三个晚…

Class加载过程

文章目录java解释执行热点代码编译类生命周期加载&#xff08;Loading&#xff09;验证&#xff08;Verification&#xff09;准备&#xff08;Preparation&#xff09;解析&#xff08;Resolution&#xff09;初始化&#xff08;Initialization&#xff09;使用&#xff08;Us…

并发编程(三)原子性(2)

【 悲观锁与乐观锁 】&#xff1a; 【悲观锁】&#xff1a; 一定会被别人打断&#xff1b;我必须得上锁。synchronized就是悲观锁。 【乐观锁】&#xff1a; 乐观锁又称之为——无锁、自旋锁、CAS 。 厕所里的人认为不会有其他人来上厕所和我竞争。 【举例解释CAS操作】&a…

SOHO帮客户找新品,如何拿到最优价?要不要选择大型机械类产品?

做外贸&#xff0c;无论是贸易公司还是工厂&#xff0c;又或者是SOHO。都有机会帮助客户采购自己主打产品之外的其他产品&#xff0c;有些人就会问&#xff0c;对于客户咨询的新产品&#xff0c;我们本身没有熟悉的供应商&#xff0c;这个时候要怎么去找到好的供货商&#xff1…

世界技能大赛夺冠背后,亚马逊云科技如何培养云计算技能人才?

云计算相关专业的就业前景如何&#xff1f; 人社部数据显示&#xff0c;到2025年我国云计算人才缺口将高达近150万。另一方面&#xff0c;根据艾瑞咨询《中国云计算行业洞察与人才分析》报告&#xff0c;2019年云计算领域人才月均薪酬在1万元以上的占比达93.7%&#xff0c;3万元…

VK3606D抗电机马达干扰直接输出6键触摸芯片,电容式6通道触控检测IC低电平有效,无触摸4秒进入待机模式常用于工控面板/空调/风扇/家电等

VINKA/永嘉微电的VK3606D SOP16是一种具有自动校准功能&#xff0c;低待机电流&#xff0c;抗电压波动等特性的&#xff0c;6按键电容式触摸触控检测IC&#xff0c;适用于温控器&#xff0c;86面板触摸开关&#xff0c;智能家居等抗干扰场所 型号&#xff1a;VK3606D 封装形…

WebGL、GPU硬件加速、GLSL、光栅化

一、介绍 WebGL经常被当成3D API&#xff0c;人们总想“我可以使用WebGL和一些神奇的东西做出炫酷的3D作品”。 事实上WebGL仅仅是一个光栅化引擎&#xff0c;它可以根据你的代码绘制出点&#xff0c;线和三角形。 想要利用WebGL完成更复杂任务&#xff0c;取决于你能否提供合…

CentOS Stream 9 配置静态 IP

系统环境&#xff1a; OS&#xff1a;CentOS Stream 9 CentOS Stream 9 不同于以往版本的 CentOS&#xff0c;没有之前的网络设置相关的命令&#xff0c;如&#xff1a; service network start/restart/status systemctl start/restart/status network设置网卡 IP 的配置文件…

新媒体研究杂志社新媒体研究编辑部新媒体研究杂志2022年第18期目录

本期聚焦 出版学核心期刊自媒体运营状况与其学术影响力关系研究 程海燕;季佳乐; 1-5 理论研究 《新媒体研究》投稿&#xff1a;cnqikantg126.com 网络社群网民情绪感染研究综述 单悦影;祁凯; 6-922 基于CiteSpace的被遗忘权研究综述 徐怡; 10-14 应用研究 …