编译Guest Kernel和rootfs
rootfs编译
- 创建rpm数据库。
建议在“/tmp”目录下创建“rootfs”。
mkdir -p /tmp/rootfs/var/lib/rpm rpm --root /tmp/rootfs/ --initdb
- 下载openEuler发布包。
手动下载openEuler发布包,指定在“rootfs”目录中安装,安装完成后,在“rootfs”下会生成etc、usr、var子目录。
rpm -ivh --nodeps --root /tmp/rootfs/ https://repo.openeuler.org/openEuler-24.03-LTS-SP1/everything/aarch64/Packages/openEuler-release-24.03LTS_SP1-55.oe2403sp1.aarch64.rpm cd /tmp/rootfs ll
安装成功如下(error报错忽略)。
图1 安装成功(1)
图2 安装成功(2)
- 安装yum、dnf包管理程序。
- 创建包管理源。
mkdir /tmp/rootfs/etc/yum.repos.d curl -o /tmp/rootfs/etc/yum.repos.d/openEuler-24.03-LTS-SP1.repo https://gitee.com/src-openeuler/openEuler-repos/raw/openEuler-24.03-LTS-SP1/generic.repo
通过添加-k命令选项可以在进行HTTPS请求时不验证服务器的SSL证书,此操作可以规避自签名证书问题,但存在安全绕过风险,建议默认不使用-k命令选项。
- 下载dnf、yum等安装包。
dnf --installroot=/tmp/rootfs/ install -y dnf yum vim net-tools iproute iputils NetworkManager openssh-server passwd hostname ntp

- 创建包管理源。
- 添加配置文件,设置DNS。
- 打开“/tmp/rootfs/etc/resolv.conf”文件。
vi /tmp/rootfs/etc/resolv.conf
- 按“i”进入编辑模式,在文件中添加如下内容。
nameserver 8.8.8.8 nameserver 114.114.114.114
- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。

- 打开“/tmp/rootfs/etc/resolv.conf”文件。
- 配置网络。
- 打开ifup-eth0文件。
vi /tmp/rootfs/etc/sysconfig/network-scripts/ifup-eth0
- 按“i”进入编辑模式,在文件中添加如下内容。
TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=eth0 UUID=851a6f36-e65c-3a43-8f4a-78fd0fc09dc9 ONBOOT=yes AUTOCONNECT_PRIORITY=-999 DEVICE=eth0
- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。
- 打开ifup-eth0文件。
- 设置rootfs。
- 挂载必要的路径。
mount --bind /dev /tmp/rootfs/dev mount -t proc /proc /tmp/rootfs/proc mount -t sysfs /sys /tmp/rootfs/sys

- 进入文件系统。
chroot /tmp/rootfs/ /bin/bash
- 设置root密码。
passwd root

- 可选:添加mirror用户并自定义IMA策略(使能ima容器镜像度量时配置)。
useradd mirror
- 打开IMA策略文件。
vi /etc/ima/ima-policy
- 按“i”进入编辑模式,在文件中添加以下内容。
measure func=FILE_CHECK mask=MAY_READ fowner=1000
- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。
- fowner的值为mirror用户的uid,可通过cat /etc/passwd命令查看UID的值。
- 若配置了“/etc/ima/ima-policy”文件,系统启动时会默认加载此文件的IMA配置,IMA策略只能修改一次,虚拟机启动后无法再修改IMA策略。
- 打开IMA策略文件。
- 设置主机名。
echo openEuler > /etc/hostname exit
主机名openEuler用户可自定义。
- 取消临时挂载目录。
umount -l /tmp/rootfs/dev umount -l /tmp/rootfs/proc umount -l /tmp/rootfs/sys
- 挂载必要的路径。
- 编译内核模块。
- 准备内核代码。
请参见编译Guest Kernel准备内核代码并生成配置。
- 编译rootfs内核模块的内核配置需要和编译guest image时的内核配置保持一致。
- 使能机密容器特性时,务必完成guest kernel编译后再完成rootfs的make modules等操作,否则机密容器无法启动。
- 编译内核代码。其中LOCALVERSION指定了内核版本后缀,影响驱动安装的目录“/lib/modules/${LOCALVERSION}/”,内核版本需与编译Guest Kernel里指定的版本保持一致。
export LOCALVERSION= make include/config/kernel.release make modules -j32

- 安装内核模块到“rootfs”。
make modules_install INSTALL_MOD_PATH=/tmp/rootfs

- 准备内核代码。
- 执行以下命令创建rootfs镜像。
- 创建空白镜像文件。
dd if=/dev/zero of=/tmp/rootfs.img bs=1M count=5000
其中bs表示块大小,对应的rootfs.img大小为bs*count,即5000MB,用户可根据实际情况自定义容量大小。

- 创建EXT4类型的文件系统。
cd /tmp mkfs.ext4 rootfs.img

- 将1到7准备好的文件系统内容拷贝到文件系统镜像中。
mkdir -p rootfs1 mount rootfs.img rootfs1 cp -rfp /tmp/rootfs/* rootfs1/ umount rootfs1

- 对文件系统映像文件rootfs.img进行自动化的文件系统完整性检查和修复操作。
e2fsck -p -f rootfs.img

- 最小化文件系统大小。
resize2fs -M rootfs.img

可以通过执行以下命令扩展一个已有的rootfs.img的容量。
qemu-img resize rootfs.img +50G e2fsck -f rootfs.img resize2fs rootfs.img
- 创建空白镜像文件。
编译Guest Kernel
- 安装编译依赖。
yum install ncurses-devel openssl-devel yum groupinstall "Development Tools"
- 下载openEuler-24.03-LTS-SP1 Kernel源码。
yum install kernel-source-6.6.0-72.0.0.76.oe2403sp1.aarch64 -y

目标版本Kernel源码位于“/usr/src”目录下。

- 完成安装openEuler-24.03-LTS-SP1镜像包后,OS默认为openEuler-24.03-LTS-SP1的yum源,也可以参见软件部署手动添加openEuler-24.03-LTS-SP1的yum源。
- 可执行以下命令查看源码安装位置。
rpm -ql kernel-source
- 生成默认配置。
- 进入“kernel”目录并修改defconfig。
cd /usr/src/linux-6.6.0-72.0.0.76.oe2403sp1.aarch64/ vim arch/arm64/configs/openeuler_defconfig
内核版本号取决于用户kernel-source的安装版本,因此这里的kernel目录应参考用户实际安装的版本所在目录。
- 确保编译选项修改为如下形式。
CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y CONFIG_VIRTIO_BLK=y CONFIG_SCSI_VIRTIO=y CONFIG_VIRTIO_NET=y CONFIG_VIRTIO=y CONFIG_VIRTIO_PCI_LIB=y CONFIG_VIRTIO_PCI=y CONFIG_EXT4_FS=y # CONFIG_DEBUG_INFO_BTF is not set
- 修改Kconfig。
- 修改/block/Kconfig文件。
- 打开drivers/block/Kconfig文件。
vim drivers/block/Kconfig
- 按“i”进入编辑模式,修改tristate“Virtio block driver”为如下。
bool "Virtio block driver"

- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。
- 打开drivers/block/Kconfig文件。
- 修改drivers/net/Kconfig文件。
- 打开drivers/net/Kconfig文件。
vim drivers/net/Kconfig
- 修改tristate“Virtio network driver”为如下。
bool "Virtio network driver"

- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。
- 打开drivers/net/Kconfig文件。
- 修改drivers/virtio/Kconfig文件。
- 打开drivers/virtio/Kconfig文件。
vim drivers/virtio/Kconfig
- 按“i”进入编辑模式,将config VIRTIO_PCI_LIB下的tristate改为bool。

- 修改tristate“PCI driver for virtio devices”为如下。
bool "PCI driver for virtio devices"

- 按“Esc”键退出编辑模式,输入:wq!,按“Enter”键保存退出文件。
- 打开drivers/virtio/Kconfig文件。
- 修改/block/Kconfig文件。
- 生成.config配置文件。
make openeuler_defconfig
- 进入“kernel”目录并修改defconfig。
- 编译Guest Kernel。其中LOCALVERSION指定了内核版本后缀,影响虚拟机内执行“uname -r”显示的值,需与rootfs编译里指定的版本保持一致。
export LOCALVERSION= make include/config/kernel.release make -j32
编译完成生成的Guest Kernel镜像位于“arch/arm64/boot/Image”路径下。Image文件即机密虚拟机启动时所需镜像文件。
父主题: 编译流程