CentOS6-Linux内核编译 详细步骤
背景
Win10用VMwareWorkstation搭的虚拟机
CentOS6.5,内核版本2.6.32-431.el6.x86_64
在该环境下升级至4.9.195版本(版本随便选的一个),并且编译版本信息(版本信息里面加上我的学号_姓名)
确定内核以及版本信息
[root@ymhadoop ~]# uname -r
2.6.32-431.el6.x86_64
[root@ymhadoop ~]# cat /etc/centos-release
CentOS release 6.5 (Final)
搭建编译环境
#逐条运行命令
sudo yum groupinstall "Development Tools"
sudo yum install ncurses-devel
sudo yum install qt-devel
sudo yum install openssl-devel //后文全部默认在root权限下输入命令(即省略sudo)
-
如果使用sudo命令报错:
xxx is not in the sudoers file.This incident will be reported.
解决办法见后文[1] -
Development Tools" :是用于更新编译环境,确保内核源码编译的时候拥有编译时所需的一切工具
-
ncurses-devel:确保让make config系列指令正确地执行
-
qt-devel、openssl-devel同上
下载内核
- Linux内核的官方网址:https://www.kernel.org。这个网站只列出了所有的longterm版、最新的stable版、当前的mainline版。
- 我是从另外一个网址上下载的,存放了Linux内核的所有版本,十分方便:https://www.kernel.org/pub/linux/kernel。
下载的源码包是:linux-4.9.195.tar.gz。 - 从windows移动文件到虚拟机中,有些文件可以直接从windows拖进虚拟机桌面上。一般选择用SSH或者Winscp。源码压缩包直接放在桌面上就行。
解压内核
CentOS6的源码放在/urc/src/kernels/文件夹下,所以我也直接将压缩包解压至该路径下,得到文件夹linux-4.9.195。
cd /usr/src/kernels/
tar -zxvf ~/installer/linux/src/linux-4.9.195.tar.gz
配置源码
-
由于我的上机任务是需要在源码的版本信息中加入我的学号_姓名,则只需要用make menuconfig指令 —> 这个指令能让你的源码配置在可视化界面上操作。
-
make menuconfig指令与之前配置编译环境时候的后三条语句息息相关,否则会报错误:
Makefile:546: recipe for target \'menuconfig\' failed
解决办法见后文[3] -
看到menu菜单后,进入General setup;进入setup后,再找到 Local version - append to kernel release 表示在内核版本后面加上自定义的版本字符串(小于64字符),可以用"uname -a/-r"命令看到
-
回车后键入:_xxxxxxxx_ym
编译源码
- 进入源码根目录,即/usr/src/kernels/linux-4.9.195/,执行make编译语句
cd /usr/src/kernels/linux-4.9.195/
make -j 4
- 4表示4线程编译,据说编译速度会稍快一点,结果编译还是用了将近一个小时。
- make出现问题大部分原因可能是编译器与内核版本不兼容,报错:
make[1]: *** [scripts/kconfig/mconf.o] ERROR
解决方法见后文[2] - 如果是多核cpu,可以选择多核编译;使用
cat /proc/cpuinfo
查看cpu信息。
找到其中“processor : [数字]”表示对CPU的编号,这个编号从0开始,所以找到最后一个“processor : [数字]”,[数字]+1就是你的CPU数。我的机器最后一个CPU编号为“processor : 0”,所以我的电脑是单核。 - 编译时间一般而言将近一个小时,要注意待机的情况下虚拟机貌似不会在后台继续编译。
安装源码
- 安装内核模块
make modules_install
- 安装完内核模块后内核模块的可执行文件就会出现在/lib/modules/文件夹下,进入该目录下就可以看到我们安装内核版本的文件夹
- 注册启动项
make install
- 这个命令是将该内核注册给引导程序,当开机启动的时候,引导程序会调用注册给它的内核来启动系统,如果有多个内核,用户可以选择从哪个内核启动
- 运行到这一步,很容易出现报错:
ERROR: modinfo: could not find module XXX
解决方法和具体原因见后文[4]
但是不管如何,该报错并不会影响内核安装,对于进行后续操作完全没有任何问题。
- 安装完之后修改默认内核启动项:打开/etc/grub.conf 查看系统内核的情况,修改grub引导顺序,让新安装的内核作为默认内核。
- 从命令行查看文本出现的数字中可以看出存在两个内核版本,
- 在 grub.conf 文件中决定开机使用哪个内核版本做启动的参数是 default,默认为 0(代表从最新的内核启动,代表的内核版本从上往下依次是 0,1, 2 等)
- 在这个例子中,如果要选择从旧版内核即系统最开始的内核启动,则把 default 值改为 0 ,然后重启服务器从新的内核进行引导
vi /etc/grub.conf
#boot=/dev/sda
default=0 //此处需要将1修改成0;一般新安装的内核在第一个位置,所以设置default=0。
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (3.10.58)
root (hd0,0)
......
- 此处需要注意:CentOS 7.0 系统更改内核启动顺序与CentOS 6.X 系统更改内核启动顺序的方式截然不同, CentOS 7 使用 grub2 作为引导程序,而CenOS6.x是修改 /etc/grub.conf 来修改启动项。所以两者修改进行内核启动顺序的步骤完全不一样,CenOS7与6.x进行操作做具体区别如此:[点击此处]
- 重启电脑即可查看新内核版本
reboot //重启命令
uname -r //查看内核版本信息
4.9.195_xxxxxxxxx_ym //显示内核版本信息
可能遇到问题
1.xxx is not in the sudoers file.This incident will be reported.
sudo命令报错是因为用普通用户权限使用root级别命令
简单解决就直接su命令切换到root用户下进行原来操作即可,但是要把原命令中的sudo去掉
其他能够允许普通用户使用sudo命令的解决方法 [点击这]
2.make[1]: *** [scripts/kconfig/mconf.o] 错误
make[1]: *** [scripts/kconfig/mconf.o] 错误 1
make: *** [menuconfig] 错误 2
一般是由于gcc和内核版本不兼容导致的。
3.Makefile:546: recipe for target \'menuconfig\' failed
make[1]: *** [scripts/kconfig/mconf.o] Error 1
Makefile:546: recipe for target \'menuconfig\' failed
make: *** [menuconfig] Error 2
该错误是因为make menuconfig需要安装(Ubuntu)libssl-dev / (CentOS)openssl-devel
4.ERROR: modinfo: could not find module *
- 详细可以看这篇文章[ERROR: modinfo: could not find module * ]。
- 简要来说有三种原因:
- 确实是缺少了某个module
- 新编译的kernel已经将该选项编译进kernel了
- 模块的名称变了
- 大部分情况是属于第三种原因。什么module报错找不到,都可以用lsmod命令查找当前内核中该module的运行情况,可以通过find指令大致检查出该module是改名了,还是在后续版本中没再使用了
[root@ymhadoop ~]# lsmod | grep [module_name] //For example :lsmod | grep sco
[root@ymhadoop ~]# find /lib/ -name "*sco.ko"
参考资料
[ERROR: modinfo: could not find module * ]
[CentOS 6.x 内核升级(2.6.32 -> 3.10.58)过程记录]
[Linux CentOS 修改内核引导顺序]
[CentOS7编译内核 详细步骤]
[CentOS系统安装libssl-dev时No package libssl-dev availab]
[CentOS 6.X 系统更改内核启动顺序]
[CentOS 7.3 手动编译安装最新版本Linux Kernel ]