Linux札记:2.编译内核

其实严格来说,标题应该是编译linux内核与相关模块。因为linux的内核中可以把一些项目编译成模块,从而减少内核本身的大小,也方便了定制。
总的来说 ,编译过程可以分为如下几步:

1.下载源码包,这步就不用多说了。从官网下载是个不错的选择:http://www.kernel.org

2.将下载到的内核包解压
如果下下来的是个bz2包,那么可以使用命令 tar  -xjf  *****.tar.bz2来解压.当然了,如果有图形界面的话,你也可以右键单击压缩包,点extract here.

3.编译源码
解压后的一堆东西就是linux内核的源码了。但是编译内核的过程中,我们并不会用他所有的代码,因为linux的可定制性极高。在编译内核之前,我们首先得搞清楚一个”make”指令。习惯了IDE环境编程的同学可能从没想象过离开了IDE后,该怎么编译一个大工程。如果你要编译一个由两个c文件组成的工程,那么你也许会这样写  gcc  1.c   2.c  。但要是有几百几千个c文件怎么办呢?这个时候makefile文件就派上用场了。在这里,你可以不知道makefile该怎么写,但是你要懂得,makefile是一个编译脚本,哪些代码该在哪些代码之前编译,哪个c文件依赖于哪几个c文件,都是在makefile文件中指定的。这样一来,我们只要在根文件夹(不是说系统的根,而是代码的根)下,轻松敲入一个“make”后回车,便能实现自动化的编译了。

linux内核的编译则更多了一层 :.config 文件。这是内核的配置项,什么东西该编进内核,该不该以模块形式编译都是由它指定的。但是我们常常不是直接以文本方式修改这个文件。而是使用了make localmodconfig , make localyesconfig ,make menuconfig等工具来完成这一修改。

make localmodconfig  :检测你从开机到现在依赖到了哪些东西,写入.config文件
make localyesconfig:与localmodconfig差不多,但是不会编译成模块,也不依赖于initrd.img
make menuconfig : 以一个图形界面的菜单形式手动修改.config文件。

如果你只是想编译个可以用的新版本内核出来, localmodconfig已经足够。但对localyesconfig,要保持足够的警惕。由于过份相信localyesconfig,多花了我一天半的时间才成功将内核编译出来。原因是localyesconfig在我的虚拟机环境下,多选了一个声卡驱动(因环境而异,不一定在你的机器上也会遇到这个问题,我只是想提醒一下不要过相信这个自动config)。同时,也不要寄希望于loacalmodeconfig能把你的内核精简到什么程度,因为你localmodeconfig之后进menuconfig一看,才发现它连Macintosh的device driver 都给你配进内核了,囧…..

具体的操作一搬是,先执行一下localmodconfig 或localyesconfig,在执行的过程中会让你回答一些问题,你可以一路回车下去,也可以直接ctrl + z(强制退出),然后再用menuconfig来修改一下。

改好了配置文件后,剩下的操作就是make了。这里友情提醒一下,如果你的环境是多核的话make -j 3这个带参的make可以让你的编译速度极大的提高。接下来就等着吧,编译内核还是要一点时间的。

等编译完后,执行make install。这个指令是把编译出来的几个包,分别放到相应的文件夹下,如果你看到/boot下多了个内核包的话,基本上可以说明编译过程是成功的了。如果你设定了某些选项是编译成模块的话(默认情况下,如果是localmodconfig会编译模块,而localyesconfig则没有,具体的你得到menuconfig里去看看,有没有项目前面标的是M的以及那个允许模块编译选项是否开启),你还得执行make modules编译模块,再执行make modules_install安装模块。这样一来,在代码文件夹下的操作就基本结束了。

4.生成initrd.img(可选)
initrd.img是用作内核加载的初期,帮助内核寻找磁盘目录下的其他模块驱动的。也就是说,如果你把所有东西都编进了内核(没有编译模块),其实可以不做这一步。如果你用老的img其实大多数情况下也没有关系。想自动生成与当前内核配套的img的话,可以在/boot下执行如下命令:
sudo mkinitramfs    -k  -o initrd.img-版本号  版本号
在我的环境下即:sudo mkinitramfs    -k  -o initrd.img-2.6.37.1  2.6.37.1

5.修改grub
grub是linux最新的os loader。即你开机时看到的那个选择操作系统的界面。现在一般使用的是grub2。为什么要配grub呢?因为刚刚的操作仅仅是把相应的文件放到相应的位子,而并没有告诉grub我们安装了一个新内核。配置grub的方法也分为手动和自动两种。自动的话执行sudo update-grub或 sudo update-grub2即可。手动的话,你可以找到/boot/grub/grub.cfg文件,仿照已经存在的项目进行添加。但是如果仅仅是这种程度的修改的话,开机是看不到让你选择操作系统的界面的,但是这样你可能仍然能够进入新内核(因为新内核已经被顶到上面去,成为默认项了)。看不到选择界面是因为默认情况下,那个界面只出现了0秒,你可以在开机一直按着shift键进入选择画面。如果不想老按shift的话,你可以把grub.cfg文件中,有关timeout =0 的项改掉。

5.重启验证
如果成功登陆,先别急着高兴。输入uname -r 看看内核版本,如果为刚刚安装的新内核,那么恭喜了,大功告成矣。

最后我们大致梳理一下编译流程:

  1. 下载源码
  2. 解压源码
  3. make localmodconfig    / make localyesconfig          (localyesconfig可能有bug)
  4. make menuconfig
  5. make                     (或make  -j  数字)
  6. make install
  7. make modules  (可选)
  8. make modules_install  (可选)
  9. boot 目录下:sudo mkinitramfs    -k  -o initrd.img-版本号  版本号
  10. sudo update-grub     /  sudo update-grub2
  11. 重启 uname -r

555,前前后后差不多搞了两天,关键是那天杀的localyesconfig,欺骗了我幼小纯真的心灵。在此再次膜拜钟sir大神,帮我们找出了localyesconfig中声卡驱动加载的 bug。

4 Responses

  1. 怎么搞的 啊 我编内核编了无数次, 开机都看不见我的 新内核!!!!!!!!!!!!!!!!!问题出在哪里了?????一步一步来的啊 !!!!!!先解压缩,再清理,然后config 保存,就编译,等了一个小时编译成功了 就重启,,,但是看不见 内核啊 看不见内核啊 看不见内核啊 ~!~~~!!!!!!!!!

  2. /bin/sh: line 1: 25793 Killed
    make: *** [_modinst_post] Error 137

    以上是我遇到的 问题,install完成后 显示上面的 error 错误,然后重启就看不见我的新版内核,哭了 ,,,折腾了我两周了。。。。马上感恩节了,,,求救啊 大神!!!!!!!

发表评论

电子邮件地址不会被公开。 必填项已用*标注