利用 GitHub Actions 自动构建 Linux 内核为 deb 包
在上一篇中,我记录了如何通过源码直接编译并安装 Linux 内核,这一篇将介绍如何将内核编译为 deb 包,使我们可以方便地利用系统包管理工具对编译好的内核进行安装和删除等管理操作,以及如何利用 GitHub Actions 帮我们自动化编译。
本地编译
主要参考 debian 的官方文档:编译内核源代码:Debian 内核团队推荐
相比于前篇介绍的步骤,主要区别如下:
- 使用
sudo apt-get build-dep linux
的方式即可自动安装编译内核所需的全部依赖 - 可以用
wget
直接从http://www.kernel.org/pub/linux/kernel/
这个位置下载所需源码包 - 使用
make deb-pkg
命令编译,即可生成内核的 deb 安装包。
利用 KVM 虚拟机隔离编译环境
为了不污染工作机的系统环境,我编译软件一般都是先用 KVM 开一个虚拟机进行编译,然后将产物拷贝到物理机使用,下面记录完整流程
- 下载系统镜像 iso 文件,我下载的是 UOS 系统的安装镜像,放置于
~/Downloads/uniontechos-desktop-21.0-home-beta6-amd64.iso
- 创建编译所需的虚拟硬盘,完整编译大约需要 40G 左右空间
1
2cd ~/Qemu/uos/
qemu-img create -f raw disk 64G - 用 KVM 引导安装镜像,进入
Live-CD
系统,参考:建议Linux用户尝试下kvm虚拟机: 最简单的使用场景——试用-Linux-LiveCD1
2这里配置了端口转发,用于内核编译好之后可以方便地拷贝出来
kvm -cpu host -smp 4 -m 16G -cdrom ~/Downloads/uniontechos-desktop-21.0-home-beta6-amd64.iso -hda ~/Qemu/uos/disk -nic user,hostfwd=tcp::8000-:8000ps.UOS 系统的安装镜像默认是没有进入
Live-CD
模式的选项的,需要通过如下方式进入:1. 在启动项选择界面,按 `Tab` 键进入编辑模式 2. 将下图所示原本启动参数中的 `livecd-installer` 改错或者删除,然后回车启动
- 进入系统后,开启终端,首先用
fdisk
命令为虚拟磁盘创建分区
a. 输入命令sudo fdisk /dev/sda
b. 按n
新建分区,然后一直默认值,输入四次回车
c. 输入w
,将变更写入硬盘 - 格式化硬盘分区并挂载
1
2sudo mkfs.ext4 /dev/sda1
sudo mount /dev/sda1 /mnt/
之后就可以在 /mnt/
路径下进行编译操作了
编译步骤
为 apt 开启源码仓库
为了可以使用apt build-dep linux
自动安装编译所需的依赖,需要先为 apt 配置源码仓库
参考 移植一个软件包到 stable 系统,编辑/etc/apt/sources.list
,有些发行版(如 debian)默认是将deb-src
开头的源码仓库注释掉的,只要取消注释即可;而 UOS 是没有的,所以如下方式添加:1
echo "deb-src https://home-packages.chinauos.com/home plum main contrib non-free" >> /etc/apt/sources.list
安装所需依赖
1
2
3
4
5
6编辑 /etc/apt/sources.list 后首先需要更新 apt
sudo apt update
安装 wget 用于下载内核源码包
sudo apt install -y wget
自动下载编译所需的所有依赖
sudo apt build-dep -y linux下载源码、应用 .config、编译 deb 包
1
2
3
4
5
6下载需要的源码,可以用 uname -r 查看系统内核版本号
wget http://www.kernel.org/pub/linux/kernel/v5.x/linux-5.10.41.tar.xz
tar -xf linux-5.10.41.tar.xz
cd linux-5.10.41/
cp /boot/config-"$(uname -r)" .config
make deb-pkg -j4
编译结束后,会在 解压的源码包的上级目录下
生成几个 deb 包:
- 拷贝出需要的 deb 包,在物理机安装测试
比较方便的从 kvm 虚拟机中拷贝文件到物理机的方法是,在虚拟机中利用 python 开一个文件下载服务器。
由于我们开启虚拟机的时候已经设置了虚拟机 8000 端口到物理机 8000 端口的映射,所以直接在虚拟机的/mnt/
目录下执行:然后在物理机打开浏览器,访问1
python3 -m http.server
http://127.0.0.1:8000/
即可访问下载虚拟机中的文件。
我们只需要下载 linux-headers
和 linux-image
开头的两个 deb 文件即可,不用下载名字中带有 dbg
,大小 1G 左右的包,那个是调试内核使用的。
下载完成后,双击 deb 文件安装,或用 sudo dpkg -i *.deb
安装即可。
自动编译脚本
针对上面的操作,我写了一个自动化的脚本,可以在这里得到:
https://github.com/debuggerx01/kernel_deb_builder/blob/main/build_on_uos.sh
注意,只能在 UOS 系统上使用该脚本。
利用 GitHub Actions 自动编译
GitHub Actions 是 GitHub 的持续集成服务,于2018年10月推出。
简单入门可以参考:GitHub Actions 入门教程—— 阮一峰
编译脚本
由于 GitHub Actions 提供的 Linux 运行环境是 Ubuntu
,所以需要针对这个系统来编写编译脚本
build_action.sh
1 | !/usr/bin/env bash |
创建 action
1 | name: Build kernel deb packages |
如下图,经过 2 小时 40 分钟的编译,最终生成了 70 MB左右的内核 deb 包,点击 artifact
下载解压安装即可 🐕
如何使用
如果您想要利用我的这个自动化脚本根据自己的需求编译内核,请参考如下步骤:
Fork 仓库
访问 https://github.com/debuggerx01/kernel_deb_builder ,点击右上角的Fork
按钮,并 clone 到本地更新 config 文件
在本地将您获取的 config 文件替换根目录下的config
,可以从您系统的/boot/config*
文件复制,或者手动编辑编写自定义修改脚本
当前/patch.d/
目录下的修改脚本是只针对我自己的需求编写的,建议您先将其删掉,然后编写自己的脚本放在这个目录下,在脚本执行过程中会自动应用该目录下的所有脚本推送修改
推送后,action 自动触发,可以在您的仓库页面的Actions
选项卡查看进度详情。
Enjoy~ 😁
更新
卧槽,偶然发现原来可以通过禁用 .config
的 DEBUG_INFO
选项来大幅减少编译时所需的磁盘空间,同时耗时也会减少很多!!😯
只要在解压后的源码根目录,确保 .config
已存在,执行:
1 | scripts/config --disable DEBUG_INFO |
这样一来,编译所需的空间从接近 40 G 直线减少到大约 4 G,actions 脚本中的扩容系统空间的部分就完全不需要了,而且生成的 deb 包也没有那个 1 G 多的 dbg 包,编译时间更是减少了一个多小时 😆
而如果是在 kvm 虚拟机中编译,如果内存分配得足够大,甚至可以完全在内存中编译,而不用额外挂载一个虚拟磁盘了~
如上图,我给 kvm 分配了 16 G内存,那么其一半 8 G 会自动以 tmpfs 挂载到 \tmp
,所以只要切换到这个目录下执行编译脚本即可!