编译 CentOS/Redhat 内核

好记性不如烂笔头…不经常和内核代码打交道,偶尔工作需要要定位、追踪内核代码还是会忘记编译内核的具体方法,做个笔记方便日后回顾。

由于工作都是基于 CentOS/Redhat 系列,本文针对该系列内核进行说明。

编译内核

安装依赖包

首先安装依赖包:

1
yum install -y gcc ncurses-devel

获取内核源码

从 Linux 主干分支获取源码

Linux 主干分支代码均可从官方网站下载获取。

从红帽获取源码

红帽系列的内核源码是在 Linux 主干分支上经过定制的,无法从 Linux Kernel 的代码仓库获取。详细获取方法参见官方文档

文档中提供了获取kernel-develkernel-source两种内核包的方法。其中,kernel-devel包只包含用于内核开发环境所需的内核头文件以及Makefile,而kernel-souce包含所有内核源代码。如果仅仅是用于你自己编写的模块开发的话,只需引用相应的内核头文件,仅安装kernel-devel包即可;如果要修改现有的内核源代码并重新编译,那必须是kernel-souce

编译源码

将获得的源码放在/usr/src/下面。

配置内核

内核目录下配置内核参数可以根据需求使用两种方法:

  • 命令make menuconfig:使用菜单项配置内核。使用图形界面配置内核参数,可以将各个模块编译进内核、编译成模块或选择不编译;
  • 直接拷贝现有内核配置:在现在操作系统的/boot路径下,名称格式为config-<kernel version>,内核版本同uname -r命令的输出。

编译安装内核

设置完内核选项之后可以在内核目录下按顺序执行一下命令对内核进行编译和安装。

1
2
3
4
5
6
# 编译内核,可用-j指定编译线程数
make
#安装内核模块,这时候可以在/lib/modules看到对应版本的内核模块
make modules_install
#安装内核 ,可以在/boot文件下中看到对应版本的system.map和对应的内核文件(initramfs/vmlinuz)
make install

修改内核启动顺序

CentOS/Redhat 7 使用grub2来做内核启动。在安装完内核之后,新安装的内核启动项会自动写入/boot/grub2/grub.cfg文件中。每次安装完新内核,如果不修改内核启动项,必须在开机时手动选择新内核,很是麻烦。

下文介绍两种修改内核启动顺序的方法:

  • 使用启动项编号启动;
  • 使用内核名称启动;

想看当前机器有哪些内核启动项可以使用如下脚本。其中,输出结果前的数字表示启动项编号,后面字符串表示内核启动项名称。

1
2
3
4
[root@host ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
0 : CentOS Linux (3.10.0-229.14.1.el7.x86_64) 7 (Core)
1 : CentOS Linux (3.10.0-229.4.2.el7.x86_64) 7 (Core)
2 : CentOS Linux (Linux 3.10.0-229.el7.x86_64) 7 (Core)

特别的,不要尝试手动编辑该文件,想修改 grub2的配置,请修改/etc/default/grub文件。

使用内核启动项编号

编辑/etc/default/grub文件,修改GRUB_DEFAULT选项,将值设为上文脚本输出的想使用的内核启动项编号。

1
2
3
# 默认值为 saved
# 如GRUB_DEFAULT=1,使用 CentOS Linux (Linux 3.10.0-229.el7.x86_64) 这个内核
GRUB_DEFAULT=<menuentry number>

执行如下命令使配置生效:

1
grub2-mkconfig -o /boot/grub2/grub.cfg

使用内核启动项名称

使用内核启动项编号的缺点是如果安装新内核,则内核启动项顺序会被修改,如仍然想使用当前内核作为默认内核则需要再次修改配置。

如果/etc/default/grub文件中GRUB_DEFAULT=saved,则默认内核启动项信息保存在 grub2的环境变量文件/boot/grub2/grubenv的变量saved_entry 中,文件内容如下。

1
2
# GRUB Environment Block
saved_entry=CentOS Linux (3.10.0-229.14.1.el7.x86_64) 7 (Core)

修改该变量的值可以使用命令grub2-set-default:

1
2
# 该命令也可接启动项编号,如 grub2-set-default 2
grub2-set-default 'CentOS Linux (Linux 3.10.0-229.el7.x86_64)'

执行如下命令使配置生效:

1
grub2-mkconfig -o /boot/grub2/grub.cfg