编译Guest Kernel和rootfs

rootfs编译

  1. 创建rpm数据库。

    建议在“/tmp”目录下创建“rootfs”

    mkdir -p /tmp/rootfs/var/lib/rpm
    rpm --root /tmp/rootfs/ --initdb

  2. 下载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)

  3. 安装yum、dnf包管理程序。

    1. 创建包管理源。
      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命令选项。

    2. 下载dnf、yum等安装包。
      dnf --installroot=/tmp/rootfs/ install -y dnf yum vim net-tools iproute iputils NetworkManager openssh-server passwd hostname ntp

  4. 添加配置文件,设置DNS。

    1. 打开“/tmp/rootfs/etc/resolv.conf”文件。
      vi /tmp/rootfs/etc/resolv.conf
    2. “i”进入编辑模式,在文件中添加如下内容。
      nameserver 8.8.8.8
      nameserver 114.114.114.114
    3. “Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。

  5. 配置网络。

    1. 打开ifup-eth0文件。
      vi /tmp/rootfs/etc/sysconfig/network-scripts/ifup-eth0
    2. “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
    3. “Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。

  6. 设置rootfs。

    1. 挂载必要的路径。
      mount --bind /dev /tmp/rootfs/dev
      mount -t proc /proc /tmp/rootfs/proc
      mount -t sysfs /sys /tmp/rootfs/sys

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

    4. 可选:添加mirror用户并自定义IMA策略(使能ima容器镜像度量时配置)。
      useradd mirror
      1. 打开IMA策略文件。
        vi /etc/ima/ima-policy
      2. “i”进入编辑模式,在文件中添加以下内容。
        measure func=FILE_CHECK mask=MAY_READ fowner=1000
      3. “Esc”键退出编辑模式,输入:wq!,按“Enter”键保存并退出文件。
        • fowner的值为mirror用户的uid,可通过cat /etc/passwd命令查看UID的值。
        • 若配置了“/etc/ima/ima-policy”文件,系统启动时会默认加载此文件的IMA配置,IMA策略只能修改一次,虚拟机启动后无法再修改IMA策略。
    5. 设置主机名。
      echo openEuler > /etc/hostname
      exit

      主机名openEuler用户可自定义。

    6. 取消临时挂载目录。
      umount -l /tmp/rootfs/dev
      umount -l /tmp/rootfs/proc
      umount -l /tmp/rootfs/sys

  7. 编译内核模块。

    1. 准备内核代码。

      请参见编译Guest Kernel准备内核代码并生成配置。

      • 编译rootfs内核模块的内核配置需要和编译guest image时的内核配置保持一致。
      • 使能机密容器特性时,务必完成guest kernel编译后再完成rootfs的make modules等操作,否则机密容器无法启动。
    2. 编译内核代码。其中LOCALVERSION指定了内核版本后缀,影响驱动安装的目录“/lib/modules/${LOCALVERSION}/”,内核版本需与编译Guest Kernel里指定的版本保持一致。
      export LOCALVERSION=
      make include/config/kernel.release
      make modules -j32

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

  8. 执行以下命令创建rootfs镜像。

    1. 创建空白镜像文件。
      dd if=/dev/zero of=/tmp/rootfs.img bs=1M count=5000

      其中bs表示块大小,对应的rootfs.img大小为bs*count,即5000MB,用户可根据实际情况自定义容量大小。

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

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

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

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

      可以通过执行以下命令扩展一个已有的rootfs.img的容量。

      qemu-img resize rootfs.img +50G
      e2fsck -f rootfs.img
      resize2fs rootfs.img

编译Guest Kernel

  1. 安装编译依赖。

    yum install ncurses-devel openssl-devel
    yum groupinstall "Development Tools"

  2. 下载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

  3. 生成默认配置。

    1. 进入“kernel”目录并修改deconfig。
      cd /usr/src/linux-6.6.0-72.0.0.76.oe2403sp1.aarch64/
      vim arch/arm64/configs/openeuler_defconfig

      内核版本号取决于用户kernel-source的安装版本,因此这里的kernel目录应参考用户实际安装的版本所在目录。

    2. 确保编译选项修改为如下形式。
      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
    3. 修改Kconfig。
      1. 修改/block/Kconfig文件。
        1. 打开drivers/block/Kconfig文件。
          vim drivers/block/Kconfig
        2. “i”进入编辑模式,修改tristate“Virtio block driver”为如下。
          bool "Virtio block driver"

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

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

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

        4. “Esc”键退出编辑模式,输入:wq!,按“Enter”键保存退出文件。
    4. 生成.config配置文件。
      make openeuler_defconfig

  4. 编译Guest Kernel。其中LOCALVERSION指定了内核版本后缀,影响虚拟机内执行“uname -r”显示的值,需与rootfs编译里指定的版本保持一致。

    export LOCALVERSION=
    make include/config/kernel.release
    make -j32

    编译完成生成的Guest Kernel镜像位于“arch/arm64/boot/Image”路径下。Image文件即机密虚机启动时所需镜像文件。