Arm Linux 内核构建

姓名:殷晨阳

转载自中国电子网技术论坛,有改动。

【嵌牛导读】:本文讲述了Linux的内核是如何进行构建的,其中,详细介绍了构建VmLinux,并给出了部分的源代码。

【嵌牛鼻子】:Linux内核,VmLinux

【嵌牛提问】:源码是如何选择性地参与内核的构建的?

哪些源码参与了内核的构建?而Vmlinux是如何控制的?

【嵌牛正文】:

一、概述

本文基于Linux Kernel 4.10版本讲解。Linux内核采用类似于GNU Make的kbuild构建而成。

Kbuild结构简介

arm linux内核的构建分为三次编译链接,一次组合。三次链接的中间结果分别是:

1.arch/arm/boot/compressed/vmlinux

2.arch/arm/boot/vmlinux.bin

3.arch/arm/boot/setup.bin

最后的组合就是将vmlinux.bin和setup.bin组合成arch/arm/boot/zImage:

二、vmlinux的构建

vmlinux的构建在顶层的Makefile中:

cmd_link-vmlinux =                                         \

$(CONFIG_SHELL) $<$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ;      \

$(if $(ARCH_POSTLINK), $(MAKE) -f$(ARCH_POSTLINK) $@, true)

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

+$(callif_changed,link-vmlinux)

其中,call是make的内置函数,用于调用用户自己定义的带有参数的函数,这里调用的是if_changed,参数是link-vmlinux。

if_changed是scripts/Kbuild.include里定义的一个函数,定义如下:

if_changed = $(if $(strip $(any-prereq) $(arg-check)),   \

@set -e;                                                                                  \

$(echo-cmd) $(cmd_$(1));                                                 \

echo 'cmd_$@ :=$(make-cmd)' > $(dot-target).cmd)

any-prereq检查是否有依赖比目标新,或者依赖还没有创建;arg-check检查编译目标的命令相对上次是否发生变化。set–e命令表示make出错时直接退出,加个@符号表示不显示该set命令。cmd_$(1)中的1表示传给if_changed的第一个参数。嵌入式物联网智能硬件企鹅意义气呜呜吧久零就易,在这里传给if_changed的实参是link-vmlinux,所以cmd_$(1)展开后为cmd_link-vmlinux。

注意cmd_link-vmlinux中的$<表示规则中的第一个依赖,即scripts/link-vmlinux.sh。这个脚本用于vmlinux的链接,内容如下:

# Link of vmlinux

# ${1} - optionalextra .o files

# ${2} - output file

vmlinux_link()

{

locallds="${objtree}/${KBUILD_LDS}"

local objects

if [ "${SRCARCH}" !="um" ]; then

if [ -n"${CONFIG_THIN_ARCHIVES}" ]; then

objects="--whole-archivebuilt-in.o ${1}"

else

objects="${KBUILD_VMLINUX_INIT}   \

--start-group                                           \

${KBUILD_VMLINUX_MAIN}             \

--end-group                                           \

${1}"

fi

${LD} ${LDFLAGS}${LDFLAGS_vmlinux} -o ${2}      \

-T ${lds} ${objects}

else

... ...

fi

}

如果平台不是“um”,就将变量KBUILD_VMLINUX_INIT和KBUILD_VMLINUX_MAIN中的目标文件链接为vmlinux;否则就直接编译为vmlinux,也就是式中的${2}。

接下来以core-y来分析变量KBUILD_VMLINUX_MAIN:

Linux-4.10/Makefile:

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

exportKBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y) $(virt-y)

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

… …

core-y                := usr/

… …

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

… …

core-y                := $(patsubst %/, %/built-in.o,$(core-y))

make的内置函数patsubst用于查找模式匹配的字符串,并进行替换。在上面这句语句里,就是将所有‘/’替换成‘/built-in.o’。因此core-y最终变为:

core-y :=user/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.osecurity/ built-in.o crypto/ built-in.o block/ built-in.o

再看其他几个类似的赋值语句:

init-y                   := $(patsubst %/,%/built-in.o, $(init-y))

drivers-y           :=$(patsubst %/, %/built-in.o, $(drivers-y))

net-y                  := $(patsubst %/,%/built-in.o, $(net-y))

libs-y1                := $(patsubst %/, %/lib.a,$(libs-y))

libs-y2                := $(patsubst %/, %/built-in.o,$(libs-y))

libs-y                  := $(libs-y1) $(libs-y2)

virt-y                  := $(patsubst %/,%/built-in.o, $(virt-y))

不难看出,vmlinux就是由这些目录下的built-in.o和lib.a链接而成。

vmlinux的另一个依赖是vmlinux-deps,其构建规则也在顶层Makefile中定义:

Linux-4.10/Makefile:

vmlinux-dirs     := $(patsubst %/,%,$(filter %/, $(init-y)$(init-m) \

$(core-y) $(core-m) $(drivers-y)$(drivers-m) \

$(net-y) $(net-m) $(libs-y) $(libs-m)$(virt-y)))

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

… …

# The actual objectsare generated when descending,

# make sure noimplicit rule kicks in

$(sort$(vmlinux-deps)): $(vmlinux-dirs) ;

… …

$(vmlinux-dirs):prepare scripts

$(Q)$(MAKE) $(build)=$@

目标vmlinux-deps的构建规则下没有命令可执行,只依赖于另外一个目标vmlinux-dirs,该变量的赋值语句里的filter表示过滤掉不以‘/’结尾的字符串。而filter的这些输入变量,如core-y,其子目录都是以‘/’结尾。因此vmlinux-dirs是一个多目标规则,相当于:

init: prepare scripts

$(Q) $(MAKE) $(build) =$@

kernel: preparescripts

$(Q) $(MAKE) $(build) =$@

… …

规则中的命令展开为:

Make–f script/Makefile.buildobj=$@

Make的自动变量$@表示规则的目标,这里就是要构建的子目录init,kernel等。

总结一下,kbuild依次构建Makefile中指定的子目录,生成built-in.o、lib.a等文件,然后链接为vmlinux。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 说明本次redis集群安装在rhel6.8 64位机器上,redis版本为3.2.8,redis的gem文件版本为...
    读或写阅读 14,660评论 3 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 当太阳落下远山,天色渐暗 纱窗,地毯 看,湖上是空旷的深蓝 蔷薇花金黄 咖啡尚暖 空气里独少了爆炒的蒜香 阿城,你...
    时光蜜糖阅读 681评论 4 51
  • 1.冥想曾是乔布斯的灵感来源 稍微深究乔布斯人都知道,他受到了禅宗和印度瑜伽两派思想的深厚影响。日本的铃木俊隆,将...
    Kisa_Wu阅读 10,972评论 1 10
  • 【谈情说爱专题周刊稿】 1 青,你在吗? 不知道你是否能听到看到想到我将要写给你的话,不知道人们说的心有灵犀时空无...
    婴儿看世界阅读 657评论 16 12