IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux kernel中.o文件的编译过程 -> 正文阅读

[系统运维]Linux kernel中.o文件的编译过程

前言

在嵌入式Linux的开发过程中,内核编译是一个永远也绕不开的话题。

对内核编译系统的清晰把握,至少可以:

  • 了解整个内核的构造
  • 节省编译时间
  • 在编译报错时快速定位问题
  • 进一步了解内核的启动

本文从Linux kernel中.o文件的编译探索kbuild机制。

日期内核版本架构
2022-9-13Linux5.4.200arm

实验

目标log展开

我们以page_alloc.o的编译为例开始本次实验。

make mm/page_alloc.o

在kernel根目录下的Makefile中有:

https://elixir.bootlin.com/linux/v5.4.200/source/Makefile#L1733

# Single targets
...
$(build-dirs): prepare
    $(Q)$(MAKE) $(build)=$@ \
    single-build=$(if $(filter-out $@/, $(single-no-ko)),1) \
    need-builtin=1 need-modorder=1

直接看不是很直观,kernel version 2.6的Makefile中语句较为清晰:

%.o: %.c prepare scripts FORCE
	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)

逻辑比较清晰,.o的文件依赖于同名的.c文件,然后执行一个命令来生成。

Tip:这里有个小技巧,注释掉构建语句,通过error log来逆向观察语句展开的结构

$(build-dirs): prepare
    #$(Q)$(MAKE) $(build)=$@ \
    single-build=$(if $(filter-out $@/, $(single-no-ko)),1) \
    need-builtin=1 need-modorder=1

再次执行编译命令,则有:

#@make -f ./scripts/Makefile.build obj=mm \
single-build=1 \
need-builtin=1 need-modorder=1

从log可知,执行make mm/page_alloc.o又调用了一次make,使用script/Makefile.build这个规则文件,传入的参数是obj=mm。

build

由第一节的log我们知道$(build)展开后是:

-f ./scripts/Makefile.build obj

在哪定义的呢?全局搜索后,答案是scripts/Kbuild.include,类似头文件的东西。

https://elixir.bootlin.com/linux/v5.4.200/source/scripts/Kbuild.include#L160

###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj

好,将注意力转移到scripts/Makefile.build这个文件,寻找和编译.o相关的语句。

$(obj)/%.o: $(src)/%.c $(recordmcount_source) $$(objtool_dep) FORCE
	$(call if_changed_rule,cc_o_c) #调用if_changed_rull这个变量
	$(call cmd,force_checksrc)  #代码检查

重点关注$(call if_changed_rule,cc_o_c),这里调用了if_changed_rull变量,该变量同样定义在scripts/Kbuild.include

# Usage: $(call if_changed_rule,foo)
# Will check if $(cmd_foo) or any of the prerequisites changed,
# and if so will execute $(rule_foo).
if_changed_rule = $(if $(any-prereq)$(cmd-check),$(rule_$(1)),@:)

这是一条逻辑判断语句,当条件为真,执行逗号之前的动作。当条件为假,则执行后面的@:。这里的@:为的是减少一些log输出,具体可以看提交:kernel/git/torvalds/linux.git - Linux kernel source tree

而如果条件为真,rule_$(1)展开就是rule_cc_o_c

好,现在回到scripts/Makefile.build,寻找rule_cc_o_c的定义:

define rule_cc_o_c
	$(call cmd_and_fixdep,cc_o_c)
	$(call cmd,gen_ksymdeps)
	$(call cmd,checksrc)
	$(call cmd,checkdoc)
	$(call cmd,objtool)
	$(call cmd,modversions_c)
	$(call cmd,record_mcount)
endef

OK,离故事接近真相还差最后一步,$(call cmd_and_fixdep,cc_o_c)语句是我们重点关注的。同样是call函数,所以在此回到头文件scripts/Kbuild.include寻找定义:

cmd_and_fixdep =                          \
	$(echo-cmd) $(cmd_$(1));              \
	...

根据经验,再次展开就是cmd_cc_o_c了,它还是在scripts/Makefile.build文件定义。

cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<

终于,真相大白!

总结

.o文件的编译一共分为如下四个步骤:

    Makefile
    ---------------
    1: %.o: %.c
    	make -f scripts/Makefile.build obj=mm 

    scripts/Makefile.build
    ---------------
    2: $(obj)/%.o: $(src)/%.c
    	$(call if_changed_rule,cc_o_c)

    scripts/Makefile.build
    ---------------
    3: rule_cc_o_c
    	$(call cmd_and_fixdep,cc_o_c)

    scripts/Makefile.build
    ---------------
    4: cmd_cc_o_c
		$(CC) $(c_flags) -c -o $@ $<

这里重点强调下前面反复提到的两个文件:

  • scripts/Makefile.build:包含了几乎所有的重要规则
  • scripts/Kbuild.include:类似于头文件,包含很多重要函数
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 21:17:28  更:2022-10-08 21:19:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 3:27:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计