Kbuild 编译 Linux 内核系列(三)

By -

Author : Wei Yang
作者公众号:杨小伟的世界

王首富定过一个亿的小目标,虽然内核没有一个亿,却还是有不少有意思的小目标的。

这些小目标可以帮助我们:

  • 生成辅助资料。
  • 生成单个目标文件。
  • 节约时间。
  • 偶尔可以帮助调试。

那我们就一个个讲吧~

all 或者 空

当你在内核代码目录下执行 make 的时候,编译的目标默认就是 all 。

代码中的注释很好的解释了这个目标的意义。

这个目标在 x86 平台等价于 vmlinux + modules + bzImage

vmlinux

嗯,这个就是你编译完成后在 Linux 源代码目录下的那个 vmlinux 。

注意了,这是一个 ELF 文件,用处以后你会慢慢知道的。

modules

modules 就是编译内核模块。

所以整个内核,你可以理解为就是 vmlinux + modules

bzImage

那既然 vmlinux + modules 组成了整个内核,多出来了一个 bzImage 来插什么腿?

这个东西可以看作是 vmlinux 的衍生。可以看到 vmlinux 是 ELF 格式,首先在引导程序要加载的时候要看得懂这个格式,另外这个文件比较大。现在 4.9 的内核编译下来 vmlinux 就有 422M 这么大,直接放到启动分区实在太占地方。当然我这个没有裁剪,裁剪后应该可以相应减少,但是恐怕也不会小太多。

所以 bzImage 可以粗暴地理解为: ELF加载器 + 压缩了的 vmlinux 。
整个压缩完之后 bzImage 大小只有 7M 不到了,这压缩能力杠杠的。

M=drivers/xxx

这个可以看作是 modules 目标中的更小的一个目标了。

举一个栗子大家看了或许更明白:

这条命令只会去编译 ixgbe 这个驱动,而不会对其他无关驱动进行检测编译。对开发以及后期维护来说,节省了不少编译时间。

dir/file.o

这是单独编译某个文件,当你修改某个文件做开发的时候,你可以先单独编译你修改的文件确保没有语法错误,然后再编译内核或者是模块。

比如在 ixgbe 模块中,更改了 ixgbe_ethtool.o 文件,那么你可以先运行:

这样确保单个文件的语法没有错误,然后再去编译整个模块。

同样这也节省了编译时间,尤其是当遇到某个文件编译有错误的时候。

dir/file.i

这个目标是针对某个文件只做预处理,也就是把所有的头文件和宏定义都展开。

用法很简单:

就生成了 mm/memblock.i 文件,其结果是已经预处理完的,就是宏定义展开后的源文件。

感觉用处不是很多,能想到的就是在阅读内核源代码的时候可以确定到底这个宏定义的是啥。因为内核需要在不同的体系架构下都能运行,而且同一架构体系下又有不同的配置。所以同样一个函数或者宏会在不同情况下定义成不同的样子,有时候直接肉眼去看代码不一定能看得准。

这个时候就可以执行这个命令,直接看预处理后的文件,或许可以有助于你理解代码。

dir/file.s

这个作用是生成了指定文件的汇编代码。

用法类似:

这估计是要做汇编级的调试了,俺还从来没有整过。

cscope

这个目标特殊,已经不是代码了,是生成 cscope 的文件。嗯,这个文件是用来辅助阅读代码的。

懂得人秒懂,不懂的估计得重新开一个话题了。

isoimage

这个还是 Andi Kleen 告诉我的。这是一个包含内核的可以启动的 iso 文件。
用来调试用的,用得真的不多。

有兴趣的朋友或许可以在我其他的文章中见到它的身影。

help

最后的最后, kbuild 中提供了一个 help 目标。当你不确定如何使用或者还想知道哪些目标可以用时,那就执行:

然后你就可以知道都有哪些用法了。

好了,小目标们讲完了。现在是不是对内核编译又有了点了解?强烈建议没有编译过这些小目标的读者实践一下,看一看执行的结果能加深自己对内核编译过程的印象。

还是那句话:

纸上得来终觉浅,绝知此事须躬行!


本文是 LinuxStory 柴米油盐计划的投稿文章,由 LinuxStory 整理发布。
原作者署名为:Wei Yang 。
转载请注明出处,否则必究相关责任。
本文链接:https://linuxstory.org/kbuild-linux-3/

这里是柴米油盐计划投稿的发布账号。

发表评论

电子邮件地址不会被公开。