Linux Kernel 编译安装
Linux Kernel 编译安装
1. 什么是Linux Kernel
- Linux内核是一种开源的类Unix操作系统宏内核。实际上就是系统上面的一个文件,这个文件文件包含了硬件的检测程序和驱动模块,负责了整个硬件的驱动,以及各种系统所需要的内核功能,是操作系统的最底层最核心的部分
- 在Linux的启动流程中,当系统读取完BIOS并加载MBR内的启动引导程序后,就加载内核文件到内存中,然后系统依据该文件来检测并驱动各种硬件资源,挂载根目录,调用
$systemd
来启动操作系统所需要的服务 - 内核文件一般情况下置于
/boot/
目录下,一个Linux系统可以存在多个内核,但是同一时间只能运行一个
2. 什么是Linux Kernel Module
- 为了避免硬件的快速迭代而带来的内核支持不足的问题,Linux Kernel将一些不常用 / 不普遍的类似驱动的东西做成了内核模块,使之可以在系统运行中装载,也可以后期再不更换内核的情况下自行添加
- 一般Module文件都位于
/lib/modules/$(uname -r)/kernel
文件目录下面
3. Linux Kernel 目录用途
arch
: 与硬件平台相关的项目,大部分与CPU相关,例如架构 / 虚拟化支持block
: 与块设备相关的设置数据,块数据一般指大容量储存媒介,还包括是否支持ext3
文件系统crypto
: 内核支持的加密技术,像md5
/md4
Documentation
: 说明文件,类似于内核附带的官方文档吧drivers
: 硬件驱动程序firmware
: 比较老的硬件的固件文件fs
: 内核所支持的文件系统,像vfat
/reiserfs
/nfs
include
: 可以让其他程序调用的一些头文件init
: 内核的初始化功能,包括挂载与init
程序的调用ipc
: 定义Linux操作系统内部各程序间的通信kernel
: 定义内核的进程、内核状态、线程、进程的调度、进程的信号等lib
: 函数库mm
: 与内存相关的各项数据,也包括了swap
和 虚拟内存net
: 与网络相关的各项协议数据,也包括net
/ipv4
/netfilter
等防火墙模块security
: 包括SELinux
等在内的安全设置sound
: 和音效相关的模块virt
: 与虚拟化有关的信息,一般是支持KVM
虚拟技术
4. 几个重要的内核文件概述
-
.config
: 使用make menuconfig
命令,经过个性化设置后生成的文件,决定了内核各个功能的编译与否,与编译的方式(编译进入内核还是编译成模块),查看该文件的使用建议使用more
命令,因为,这个文件有九千多行 -
vmlinuz
&vmlinux
:vm
是Virtual Memory
的缩写,意味这两个东西都是可以引导的内核,Linux支持使用硬盘空间作为虚拟内存vmlinuz
: Virtual Memory LINUx gZip = Compressed Linux kernel Executablevmlinuz
是可执行的Linux内核,vmlinuz
的建立有两种方式- 编译时使用
make zImage
创建,zImage
的存在是为了兼容小内存设备 - 编译时使用
make bzImage
创建,bzimage
是压缩的内核镜像,此处的bzImage
并非使用bzip2
压缩,其bz
前缀的含义为big zImage
,其与zImage
相同,都是使用gzip
压缩的
- 编译时使用
bzImage
/zImage
不单单是压缩文件这么简单,其文件头部都有gzip
解压缩代码,所以用户不应该使用gunzip
/gzip -dc
来解压缩vmlinuz
。在内核文件中包含着一个专用的gzip
来处理解压缩内核并引导的过程
vmlinux
: Virtual Memory LINUX = Non-compressed Linux Kernel Executablevmlinux
是 未经压缩的内核,经过特殊压缩后可以变为vmlinuz
-
vmlinux.bin
: 该文件除了是可引导的原生二进制文件格式外,与vmlinux
相同 -
initrd.img
:initrd,img
是inttial ramdisk
的缩写。initrd
一般用于临时性的引导硬件到实际内核vmlinuz
能够接管并继续引导的状态。 -
System.map
: 该文件是一个特定内核的内核符号表,由nm vmlinux
产生并且不相关的符号会被滤除,内核本身可能并不直接使用System.map
但是其他程序例如说ps
/lsof
/klogd
等需要使用正确的System.map
文件
5. 内核的编译
5.1. 内核的下载
5.1.1. 获取内核文件的渠道
- Linux Kernel有着自己的官方网站,开发人员可以在该网站下载,当然,首页可能并非包含所有Kernel存档,你可以在该存档网址找到所有Linux发布的内核版本
- 由于Linux Kernel的服务器位于国外,所以载国内的用户体验可能不好,甚至无法下载,为此,几大机构建立了Linux Kernel的官方镜像库,定时与官方仓库同步,常用的几个Mirror如下
5.1.2. 将内核文件下载到Linux
-
如果是虚拟机系统的话,一种方式是直接在Linux中下载内核压缩包,另一种就是下载 / 复制该压缩包到宿主机,再通过介质或者
vmtool
的方式拷贝到Linux,笔记采用第一种方式记录,欲编译的内核版本号为5.0 -
打开一个
Terminal
,键入命令获取内核压缩包,这里使用阿里云的CDN镜像wget https://mirrors.aliyun.com/linux-kernel/v5.x/linux-5.0.tar.gz
-
将该内核压缩包文件拷贝复制到
/usr/src/
目录下cp ./linux-5.0.tar.gz /usr/src/
-
切换工作目录到
/usr/src/
cd /usr/src/
-
解压Linux Kernel压缩包文件
tar xzvf ./linux-5.0.tar.gz
-
[可选] 删除该目录下暂时无用的tar压缩包文件
rm -rf ./linux-5.0.tar.gz
-
最后,工作文件夹下的文件应显示下述截图的红色划线部分,其余文件目录可能与截图不同
5.2. 内核的配置
-
首先应进入欲编译内核的文件目录下
cd /usr/src/linux-5.0/
-
如果我们并不清楚该内核源码是否经过了编译,产生了目标文件,那么我们首先要将文件还原到最初始的版本
make mrproper
-
上一条命令也会清除掉可能存在的配置文件,如果你并非第一次编译,并且不想重新生成配置文件,那么可以退而执行
make clean
-
下面要生成欲编译内核的配置文件
.config
,这里我使用的是menuconfig
make menuconfig
-
menuconfig
的交互还是很简单的,其手册在上方截图 1 区有官方文档- 左右箭头表示对 3 区域的操作
- 上下箭头表示对 2 区域的操作,2 区域的异色条选中行若存在
--->
表示当前选中项有子选项可以设置,此时若 3 区域异色条位于select
区域,可以回车进入子选项 - 当异色条所在行前部有
[]
/<>
符号存在时,表明当前项可以选中 / 不选中,空格键切换状态 - 可选项显示为
[*]
/<*>
时,表示该项编译进内核,如显示为<M>
则表示该项作为模块被编译 Esc
连续按两次表示从当前菜单退回到上一层- 所有配置选项都设置完毕后,应将 3 区域异色条移动至
Save
,保存当前文件到.config
,保存成文件之后,就可以退出该界面了
-
我的内核配置选择项
- 选中 :`
Enable loadable module support -> Forced module loading & Force module unloading
- 选中 :`
FileSystem->DOS/FAT/NT FileSystems -> NTFS write support
- [可选] :
General setup -> Local version - append to kernel release
追加字符-fancyking
- 选中 :`
-
前面的操作做完后,如果保存成功,
linux-5.0/
下应该如图所示
5.3. 内核文件的编译安装
5.3.0 替换软件安装源 [可选] / [强烈建议]
-
因为Linux默认的官方安装源位于国外,所有有时候下载速度很慢,或者根本连接不上,这里建议更换成国内的镜像软件源
-
各大开源镜像站的 help 页面大都会告诉用户应该如何更改文件来使用户的系统使用该镜像,类似于USTC Mirror,这里省去这一部分,代替为记录一键换源工具
-
下列指令对 Ubuntu 有效,其余系统未经测试,下述语句完成后,会使用阿里的镜像仓库
wget git.io/superupdate.sh && \ chmod +x superupdate.sh && \ bash superupdate.sh aliyun
5.3.1. 简易版内核编译安装(直接替换本机内核)
-
首先,应先安装编译安装内核所需要的依赖,这里我经过实验,Ubuntu 16.04 / 14.04 / 18.04 基本需要安装下述依赖
apt install libc6-dev \ make \ dpkg-dev \ linux-libc-dev \ libssl-dev kernel-package \ libncurses5-dev \ fakeroot \ bc xz-utils \ ca-certificates \ ncurses-dev \ libncurses5-dev \ bison \ flex \ libelf-dev -y --fix-missing && \ apt upgrade -y && \ apt autoclean -y && \ apt clean -y && \ apt autoremove --purge -y
-
执行make,使生成内核模块 /
vmlinuz
/initrd.img
/System.map
文件make -j 4
执行上述语句时应注意,
-j
选项的意思是,允许参与编译的内核数目,该选项不应该大于虚拟机拥有的内核数目,如果不使用-j
选项意味单内核编译,自然速度会比四核慢些。缺省值为不限制,如果资源紧张有可能出现死机 / 负载极高的情况,所以尽量填写的话就正确填写,否则可能像下面一样该语句执行成功的标志是在没有
Error
的情况下结束运行,类似显示下述信息 -
执行make modules_install 和 make install
make modules_install -j 4 make install -j 4
这一步操作会复制模块文件到
/lib/modules/
目录下,复制config
/vmlinuxz
/initrd.img
/System.map
文件到/boot/
目录,并且会自动更新grub
引导项语句执行成功的标志是在没有
Error
的情况下结束运行,类似显示下述信息下图为
modules_install
的完成状态图下图为
install
的完成状态图 -
执行完上述命令之后,grub应该会自动更新的,所以可以重启验证一下,我的显示如下
-
如果在重启过程中遇到了下图所示的报错,可以临时性的增加自己的内存,当引导进入系统之后,再把内存降下来也没事
-
至此,该方式的内存编译安装完成
5.3.2. 打包替换
- 先挖坑,以后再写