# 环境准备
# 下载项
# 下载 Linux 内核源码
从官方网站下载 linux 内核源码
点击 [tarball],你会得到一个 linux-5.4.272.tar.xz
格式的打包文件,后续会用到。
# 下载 Ubuntu Server
从官方网站下载 Ubuntu Server 的镜像文件
# 必要配置
# 虚拟机配置共享文件夹
由于采用的是没有图形化界面的 Server 版本,所以我们最好配置一下共享文件夹来方便在宿主机和虚拟机之间共享文件,配置过程如下:
找到「设置」=> 「共享」
创建一个文件夹用于共享,并将其权限改为「读与写」,点击「启用共享文件夹」(我这里共享文件夹命名为
share
)。将刚刚下载的内核文件放入文件夹中,并在虚拟机中执行如下指令:
cd /mnt/hgfs/share
ls
如果一切顺利,你将会看到
linux-5.4.272.tar.xz
就在这里。「 所有共享文件夹会自动被挂载在/mnt/hgfs
下,如果你的共享文件夹命名为其他的名字,请替换成自己的名字:) 」🙅 如果没有找到
share
文件夹,可以参考这篇博客。
❗️linux虚拟机中无法写共享文件夹
笔者使用的是 MacOS,权限相对控制比较严格,共享文件夹的默认权限是只读,所以想让 linux 虚拟机可以向共享文件夹写入内容需要更改文件夹的权限,在 “share” 文件夹上点击「显示简介」,将本用户的权限改成「读与写」即可,如下图所示。
# apt 换源
构建内核需要依赖大量工具,建议先更换一下 apt 源,方便下载。
# 备份之前的 sources.list | |
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak |
然后替换 /etc/apt/sources.list
为以下内容并保存:
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
完成后使用 sudo apt update
来重新获取一下软件包缓存。
# 编译工具安装
安装编译内核时所需的工具,这里假设你使用的是一个纯净的 ubuntu 系统。
sudo apt install gcc g++ make git libncurses5-dev build-essential kernel-package libssl-dev libelf-dev dwarves flex bison |
# 编译内核
# 解压 Linux 内核
# 将 Linux 内核从共享文件夹中复制到家目录下 | |
sudo cp /mnt/hgfs/share/linux-5.4.272.tar.xz ~/ | cd ~ | |
# 解压 | |
xz -d linux-5.4.272.tar.xz | |
tar -xvf linux-5.4.272.tar | |
cd linux-5.4.272 |
# 配置 Linux 内核
Linux 内核的构建过程会查找 .config
文件,这是一个配置文件,用于指定 Linux 内核的所有可能的配置选项。这是必需的文件。
获取 Linux 内核的 .config
文件有两种方式:
- 使用你的 Linux 发行版的配置作为基础(推荐做法)
- 使用默认的,通用的配置
💡 也有第三种方法,也就是从零开始,手动配置每一个选项,但注意,这需要配置超过 12,000 个选项。并不推荐这种方式,因为手动配置所有选项将花费大量的时间,并且你还需要理解每个启用和禁用选项的含义。
以下是第一种方式:
cd linux-*/ | |
# 复制你的 Ubuntu 的配置文件 | |
sudo cp /boot/config-"$(uname -r)" .config |
# 更新 config 配置
由于我们使用的是 “旧的配置文件”(当前保存为 .config
,这是发行版配置的一个副本),所以需要检查从上一版本以来 Linux 代码库中新加的任何配置选项。如果找到任何「新的、未配置」 的选项,该选项的默认配置值会被使用,并会对 .config
文件进行更新。
原来的 .config
文件将被重命名为 .config.old
进行备份,并将新的更改写入至 .config
文件。
make olddefconfig |
# 添加必要配置
构建内核时内核模块会使用一个签名证书,默认情况下,你的计算机并不包含这个证书。我们可以用以下命令告诉编译器,自行生成一个签名证书并在编译时使用。
./scripts/config --file .config --set-str SYSTEM_TRUSTED_KEYS '' | |
./scripts/config --file .config --set-str SYSTEM_REVOCATION_KEYS '' |
我们还可以为自定义内核构建添加一个标签。我使用字符串 -gality
作为标签。这样当运行 uname -r
命令时,就会显示 5.4.272-gality
了:)
./scripts/config --file .config --set-str LOCALVERSION "-gality" |
# 编译
实际的编译很简单,也很漫长(可能 1~3 小时,如果顺利的话~
# -j 参数指定使用多个核心来加速编译过程 | |
make -j$(nproc) |
如果很不幸,你出现了 No space left on device
的错误,那么意味着你并没有好好阅读之前的内容,不过,你可以参考这篇文章来让解决问题。
# 安装内核
# 安装模块
将已经编译好的模块安装到内核中
sudo make modules_install |
# 安装 Linux 内核头文件 (可选)
如果打算尝试自行编写模块,可能会需要 Linux 内核提供的头文件。可使用如下命令来安装头文件:
sudo make headers_install |
这些头文件会被安装到 /usr
目录。同时还会在 /usr
目录内创建子目录 include/linux
,然后将头文件安装到 /usr/include/linux
内
# 安装内核
安装内核,这个过程会更新 boot 和 grub
sudo make install |
此时,可以重启 reboot
来测试新内核是否成功安装:
$ uname -r | |
5.4.272-gality # Yeah~ |
# 安装失败报错
如果在安装内核时出现类似如下报错:
... | |
update-initramfs: Generating /boot/initrd.img-5.4.0.52-generic | |
Error 24 : Write error : cannot write compressed block | |
E: mkinitramfs failure cpio 141 lz4 -9 -I 24 | |
update-initramfs: failed for /boot/initrd.img-5.4.0-52-generic with 1. | |
... |
代表写入 /boot
失败,可以按如下步骤确定原因:
- 判断是否有
/boot
目录的权限(是否用sudo
了?/boot
和所有文件是否属于root
?) /boot
目录是否有足够剩余空间(/boot
可能被过时的内核填满了)?- 是否是驱动的问题(能否在别的位置写入文件)?
如果是全新的 ubuntu 系统用于安装内核,大概率不会出现问题,笔者本身遇到这个问题是因为之前手动编译安装过一次内核,第二次安装时出现这个问题,解决方法如下:
sudo apt list --installed | grep linux-image # 列出所有安装过的内核 | |
sudo apt remove linux-image-5.4.0-54-generic # 删除过时的内核 | |
sudo apt autoremove # 自动删除过时内核的依赖 |
重复上述操作,直到 sudo apt list --installed | grep linux-image
后没有出现任何版本内核。然后重新 sudo make install
即可成功安装内核。