文章目录[隐藏]
说起内核编译,很多人都会觉得应该会很难,毕竟涉及到一个系统的核心文件。其实对于内核,在《Grub Legacy 简介》中已经有过接触,就是那个 vmlinuz-2.6.32-431.el6.x86_64
文件。对于交叉编译,进行其他主机系统的内核编译,确实比较麻烦;但是如果只是为了升级当前系统的内核,而不改变其他配置的话,还是相对简单的。下面说的也主要是升级内核所进行的内核编译步骤。
准备工作
要进行内核编译,得提前做好以下准备工作:
- 准备好开发环境;
- 获取目标主机上硬件设备的相关信息;
- 获取到目标主机系统功能的相关信息,例如要启用的文件系统;
- 获取内核源代码包;
准备开发环境
若要编译内核,需要在编辑机上安装开发套件。
sudo yum groupinstall "Development Tools";
sudo yum groupinstall "Server Platform Development";
sudo yum install ncurses ncurses-devel;
获取主机硬件信息
获取主机硬件信息是至关重要的一步,关系到所编译成的内核是否与硬件兼容,是否能发挥硬件的最大效用。如果是本机升级内核并且之前保存有内核编译配置的话(一般系统安装时都会存有一份),可以直接覆盖使用。
CPU
cat /proc/cpuinfo;
lscpu;
Memory
内存不需要具体型号参数,只需要知道空间大小即可。
free;
PCI
lspci;
lsusb;
(需安装 usbutils
)
lsblk;
查看全部硬件信息
hal-device;
(需安装 hal
)
获取系统功能信息
这个跟定制化系统相关,比如是否需要 IPV6
,甚至于是否需要网卡驱动之类的。
获取内核源代码包
访问 https://www.kernel.org/pub/linux/kernel/
获取想编译的内核源码包。
开始编译
本机内核为 2.6.32
,现在要升级为 2.6.39
。
[hzz@magedu ~]$ uname -r
2.6.32-431.el6.x86_64
[hzz@magedu ~]$ ls
linux-2.6.39.tar.gz
[hzz@magedu ~]$
解压源码包
下载源码包后,将源码包解压到 /usr/src/
目录。
[hzz@magedu ~]$ sudo tar zxf linux-2.6.39.tar.gz -C /usr/src/
[hzz@magedu ~]$ cd /usr/src/
[hzz@magedu src]$ sudo ln -s linux-2.6.39 linux
[hzz@magedu src]$ cd linux
[hzz@magedu linux]$
配置内核选项
输入 make help
可以得到很多配置选项,抽取一些常用的进行说明:
Configuration targets:
config - Update current config utilising a line-oriented program
- 基于命令行以遍历的方式去配置内核中可配置的每个选项;
nconfig - Update current config utilising a ncurses menu based program
- 基于 cureses 的文本配置窗口; * 表示编译进内核, M 表示编译进模块;
menuconfig - Update current config utilising a menu based program
- 文本配置窗口; * 表示编译进内核, M 表示编译进模块;
xconfig - Update current config utilising a QT based front-end
- 基于 QT 开发环境的窗口界面;
gconfig - Update current config utilising a GTK based front-end
- 基于 GTK 开发环境的窗口界面;
oldconfig - Update current config utilising a provided .config as base
- 基于旧的 .config 文件来更新当前配置;
defconfig - New config with default from ARCH supplied defconfig
- 基于内核为目标平台提供的默认配置为模板进行配置;
allnoconfig - New config where all options are answered with no
- 创建一个所有选项都是 no 的配置文件(适用于想完全自定义内核的操作);
allyesconfig - New config where all options are accepted with yes
- 创建一个所有选项都是 yes 的配置文件(编译出来的内核会非常大);
* Update 开头的都是基于旧配置或当前配置进行修改, New 开头的则是重新创建新配置文件。
* 配置完成后会在当前目录生成一个 .config 文件,可直接进行编辑,或用系统安装时所生成的 config 配置重命名后进行替换。
* CentOS 安装时保存的内核编译配置文件路径为:/boot/config-2.6.32-431.el6.x86_64 。
比如,执行 sudo make menuconfig
后,便会弹出一个图形化的菜单编辑界面,可以自定义内核参数。
由于此次主要是为了升级内核,其他不作什么大的改变,故基于系统安装时保存的配置文件进行修改。为了更好地识别新旧内核,添加 Local version
的参数为 -magedu-hzz
。
[hzz@magedu linux]$ sudo cp /boot/config-2.6.32-431.el6.x86_64 /usr/src/linux/.config
[hzz@magedu linux]$
编译内核
编译内核其实很简单,就一条命令的事,其实最麻烦的还是配置内核选项阶段,若想了解每一个选项的作用及影响,是需要不少时间的。
由于编译花费时间较长,推荐使用 screen
命令进行编译,以避免终端超时退出导致编译失败的情况。
先简单说说 screen
命令的用法:
# screen :打开一个与终端无关的窗口,终端断开后还依旧运行。
# 安装 screen
sudo yum install screen
# 打开 screen
screen
# 拆除 screen
Ctrl+a,d
# 列出 screen
screen -ls
# 连接至 screen
screen -r SCREEN_ID
# 关闭 screen
screen 内执行 exit
或
kill SCREEN_ID
下面开始编译内核:
[hzz@magedu linux]$ sudo make && sudo make modules_install && sudo make install
编译完成后,会在 /boot
目录下看到新的内核镜像,以及在 grub.conf
中看到新添加的内核启动选项:
[hzz@magedu ~]$ ls -ltr /boot/|grep magedu-hzz
lrwxrwxrwx. 1 root root 31 10月 31 19:59 vmlinuz -> /boot/vmlinuz-2.6.39-magedu-hzz
-rw-r--r--. 1 root root 2364066 10月 31 19:59 System.map-2.6.39-magedu-hzz
lrwxrwxrwx. 1 root root 34 10月 31 19:59 System.map -> /boot/System.map-2.6.39-magedu-hzz
-rw-r--r--. 1 root root 3931776 10月 31 19:59 vmlinuz-2.6.39-magedu-hzz
-rw-------. 1 root root 5977054 10月 31 19:59 initramfs-2.6.39-magedu-hzz.img
[hzz@magedu ~]$ more /boot/grub/grub.conf |grep magedu-hzz
title CentOS (2.6.39-magedu-hzz)
kernel /vmlinuz-2.6.39-magedu-hzz ro root=/dev/mapper/vg_magedu-lv_root rd_NO_LUKS rd_LVM_LV=vg_magedu/lv_swap rd_NO_MD rd_LVM_LV=vg_magedu/lv_root crashkernel=auto LANG=zh_CN.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.39-magedu-hzz.img
[hzz@magedu ~]$
启用新内核
重启系统,选择新内核启动:
启动完成后,使用 uname -r
命令,可以看到当前使用的已经是最新的内核了:
[hzz@magedu ~]$ uname -r
2.6.39-magedu-hzz
[hzz@magedu ~]$
其他
多线程编译
如果编译机的性能够强悍,可以在编译时使用多线程同时编译,以节约时间。
# 四个线程同时编译
[hzz@magedu linux]$ sudo make -j 4
编译内核中的一部分代码
只编译某子目录中的相关代码:
[hzz@magedu linux]$ sudo make path/to/dir/
只编译一个特定模块
[hzz@magedu linux]$ sudo make path/to/dir/file.ko
交叉编译
如果需要为其他主机编译内核,可以到 arch
目录下查看支持的平台,然后使用 ARCH
变量指定目标主机的平台进行设置:
[hzz@magedu linux]$ ls arch/
alpha avr32 cris h8300 Kconfig m68k mips parisc s390 sh tile unicore32 x86_64
arm blackfin frv ia64 m32r microblaze mn10300 powerpc score sparc um x86 xtensa
[hzz@magedu linux]$ sudo make ARCH=arm menuconfig
执行清理
如果需要在同一个源码中对不同的平台的内核进行编译,则在编译前需清理上一次编译产生的文件:
# make clean :清理编译生成的绝大多数文件,但会保留 config ,及编译外部模块所需要的文件;
# make mrproper :清理编译生成的所有文件,包括配置生成的 config 文件及某些备份文件;
# make distclean :相当于 mrproper ,额外清理各种 patches 以及编辑器备份文件;