Linux 内核编译
在学习Linux内核的过程中,编译Linux内核可能是个或早或晚都要走的步骤。这里只对Linux内核编译过程做个记录。因为我只是学习用,所以对内核的版本并没有明确的需求。
编译环境的搭建
我用的是Virtualbox6.0,下载了一个Centos6.5的镜像,进行安装,安装的时候需要注意的事项:
- 预分配的硬盘大小不要太小,默认8G是不够的,第一次编译内核的时候,编译过程中报错磁盘空间用光了。我直接分了64G,网上说20-30G也是足够的。
- 安装的时候Centos会提示安装选项,选择software server development方式安装,这样的话,gcc等编译需要用到的工具就全部安装了。
Linux源码下载
源码下载网站: https://cdn.kernel.org/pub/linux/kernel/
源码版本的选择
具体使用哪个版本的内核取决于大家的需要,因为我只是学习用,最方便的版本就是跟当前Centos一样的版本。Centos6.5用到的版本是2.6.32。
编译不同版本内核时的相应gcc版本是不同的,我们需要根据自己需要编译的内核版本安装对应的gcc版本。
Linux 2.6.32 使用的gcc版本是gcc 4.4.7。
因为我安装的时候选择了安装相应的开发工具,gcc 4.4.7已经安装了。
cat /proc/version
Linux version 2.6.32 (root@johnsonz) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #3 SMP Thu Dec 1 16:47:03 CST 2022
[root@johnsonz log]# gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Linux 源代码的解压
将下载的软件安装包解压到随意的一个目录,一般情况下家目录就可以。具体的解压命令根据不同的压缩格式自行百度。
Linux 的预配置
[root@johnsonz linux-2.6.32]# pwd
/root/linux-2.6.32
[root@johnsonz linux-2.6.32]# cp -v /boot/config-xxx .config
cp: overwrite `.config'? y
`/boot/config-2.6.32-431.el6.i686' -> `.config'
make menuconfig
make menuconfig 提供了一个图形化的界面对于Linux提供的一些feature手动的打开或者关闭。可以根据需要修改,也可以采用默认值。直接Exit退出。
Linux 内核编译
install的时候需要使用root权限。make的时间是比较长,取决于设备的性能,我编了将近1小时。没有报错,如果报错的话,可能是gcc的版本跟当时Linux2.6.32编译的版本不同。最简单的方式就是用Linux版本对应的gcc版本,如果不使用对应的gcc版本的话,可以去网上看看,应该也有一些解决方法。gcc版本差异太大的话,估计就有点麻烦了。
make -j 4
make modules_install
make install
遇到的错误
install的时候是有报错的,也在网上查了一下,大概意思就是说,Linux内核在install的时候会对比当前环境的加载的ko跟新Linux image中ko,如果有缺失会报错。不过有些ko比如下面的几个网络相关的ko,如果不启动也不会产生太大的影响。虽然有报错,实际上已经安装成功了的。
[root@johnsonz linux-2.6.32]# make install
sh /root/linux-2.6.32/arch/x86/boot/install.sh 2.6.32 arch/x86/boot/bzImage \
System.map "/boot"
ERROR: modinfo: could not find module xt_CHECKSUM
ERROR: modinfo: could not find module nf_defrag_ipv6
调整系统启动顺序
在参考文献中并没有提到启动顺序的问题,可能比较新的内核版本在安装的时候会把新安装的版本设置为默认启动系统。不过Linux2.6.32 的安装过程看起来并不是。
我新安装的是第一个系统,default = 1,就是说默认还是启动的旧的系统,把default改成0.
[root@johnsonz linux-2.6.32]# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/vg_johnsonz-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32)
root (hd0,0)
kernel /vmlinuz-2.6.32 ro root=/dev/mapper/vg_johnsonz-lv_root rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_NO_DM rd_LVM_LV=vg_johnsonz/lv_swap rd_LVM_LV=vg_johnsonz/lv_root rhgb quiet
initrd /initramfs-2.6.32.img
title CentOS (2.6.32-431.el6.i686)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.i686 ro root=/dev/mapper/vg_johnsonz-lv_root rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_NO_DM rd_LVM_LV=vg_johnsonz/lv_swap rd_LVM_LV=vg_johnsonz/lv_root rhgb quiet
initrd /initramfs-2.6.32-431.el6.i686.img
系统验证
如果新版本和旧版本版本不同,新系统起来之后还是比较好验证的。
[root@johnsonz linux-2.6.32]# cat /proc/version
Linux version 2.6.32 (root@johnsonz) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) ) #3 SMP Thu Dec 1 16:47:03 CST 2022
因为我的新旧两个版本是一样的,我就是加了一些自己的log,反正也是要学习Kernel,在/var/log/messages 的启动log里面找到了对应的log,验证成功。