CentOS7编译内核

下面记录了我在CentOS7上编译新内核的过程。

背景

实验室的一台服务器上装且仅装了CentOS7,内核版本为3.10.0-327.el7.x86_64。
我要在当前系统上,编译、安装内核4.1.16。

搭建编译环境

sudo yum install gcc g++ gdb make

如果这些程序已经安装了,则什么都不会做;否则,会安装相应工具。

下载内核

内核官方的网址为:https://www.kernel.org。这个页面只列出了所有的longterm版、最新的stable版、当前的mainline版。
还有一个网址:https://www.kernel.org/pub/linux/kernel。这里存放了linux内核的所有版本。
下载的源码包名称为linux-4.1.16.tar.gz,所在路径为:~/installer/linux/src/。当然,这个路径是随意指定的。

解压内核

CentOS7的内核源码都放在了/usr/src/kernels/下,所以我也将下载的源码解压到该路径下:

cd /usr/src/kernels/
sudo tar -zxvf ~/installer/linux/src/linux-4.1.16.tar.gz

解压之后会在/usr/src/kernels/下有一个linux-4.1.16的文件夹。

配置编译参数

进入源码根目录:

cd /usr/src/kernels/linux-4.1.16/

内核的编译参数非常多,配置的方式也有很多种,为了保持对当前系统的兼容,我选择了在已有内核编译参数的基础上进行配置。
把已有内核的编译配置copy过来:

sudo cp /boot/config-3.10.0-327.el7.x86_64 ./.config

在已有内核基础上进行配置:

make oldconfig

这个命令的意思是:.config中有的就不再配置了,只列出这里面没有的让用户选择。输入这条命令后,就会有一个接一个的选项让你选择,懒得看就一路回车就行了,此时会按默认配置。敲回车大约敲个两三分钟的样子,然后配置就完成了,在源码根目录下会生成一个.config文件,这就是这次编译的参数配置,之前copy过来的.config文件变成了.config.old。

查看CPU信息

这里查看CPU信息主要是看CPU核的个数,一会儿编译的时候可以让多个CPU同时工作,这样编译比较快。

cat /proc/cpuinfo

这时屏幕会打印出所有CPU的信息,找到其中“processor : [数字]”表示对CPU的编号,这个编号从0开始,所以找到最后一个“processor : [数字]”,[数字]+1就是你的CPU数。我的机器最后一个CPU编号为“processor : 15”,所以我有16个核。

编译源码

进入源码根目录:

cd /usr/src/kernels/linux-4.1.16/

执行编译:

sudo make -j16 all

其中,“make all”是编译所有选择的模块,“-j16”是可选参数,表示允许16个任务同时进行,这样比较快,16是我机器中CPU核的个数。
这个过程通常比较慢长,跟选择编译的项目、硬件性能有关,由于我是用16个CPU同时编译的,所以比较快,十几分钟吧。如果是单CPU,呵呵哒。。。

安装内核

编译只是把源码变成可执行文件,但目前为止,这些可执行文件并没有被放置到相应的目录下,新内核也没有注册给引导程序。
安装模块:

sudo make modules_install

执行完这条命令,内核模块的可执行文件会被copy到/lib/modules/下,进入这个目录可以看到有一个名为4.1.16的文件夹,这里面便是这个内核模块的可执行文件。
注册启动项:

sudo make install

这个命令是将该内核注册给引导程序,当开机启动的时候,引导程序会调用注册给它的内核来启动系统,如果有多个内核,用户可以选择从哪个内核启动。
到这里,理论上就可以重启机器、从新内核进入系统了,但是,我遇到了一些问题。当然,你不一定会遇到。

可能遇到的问题

问题一:/boot分区空间不足

这个问题出现在执行“sudo make install”的时候,因为这个命令要往/boot/下写东西,而我的/boot挂载的分区又已满。没有找到动态扩容的好办法,重装系统、自定义分区,给/boot分了1GB的空间,再执行到这一步的时候,问题解决了。

问题二:/dev/disk/by-uuid/XXXX does not exist

这个问题出现在重启、选择新内核启动的时候,XXXX是一串字符串。很明显,机器认为启动分区的UUID是XXXX,但是找不到这个UUID的分区。
新内核是进不去了,强行关机,重启,选择之前的内核进入系统。
查看/boot挂载的分区:

df

通过这条命令看到了挂载在/boot的设备是/dev/sda1。然后再看/dev/sda1的UUID是啥:

ls -l /dev/disk/by-uuid/

可以看到/dev/sda1的UUID不是XXXX(表示一串字符串),而是YYYY(表示另一串字符串),所以,是注册启动项的时候出了错。那就手动注册一下吧。
先到/boot/下删除之前“sudo make install”时生成的文件(如果有),有关4.1.16的文件、文件夹全删掉。
将内核的镜像文件copy到启动分区:

sudo cd /usr/src/kernels/linux-4.1.16/arch/x86_64/boot/
sudo cp ./bzImage /boot/vmlinuz-4.1.16

将内核的编译配置copy到启动分区:

sudo cd /usr/src/kernels/linux-4.1.16/
sudo cp ./.config /boot/config-4.1.16

使用dracut生成该内核的启动文件:

sudo dracut --kver 4.1.16 -k /lib/modules/4.1.16/ --kernel-cmdline root=UUID=[启动分区的UUID] initramfs-4.1.16.img

重启,选择新的内核进入系统。

(该文由回忆写成,所以没有配图,请谅解。)

你可能感兴趣的:(Linux)