跳转至

虚拟机中以pid1运行

概述

本教程基于openEuler LTS 22.03版本进行实践,理论上适用于其他Linux发行版本。首先通过dracut命令制作剔除了systemdinitramfs镜像,然后基于该镜像添加新的grub启动条目,并在该启动条目中以sysmaster-init作为一号进程实现虚拟机环境的启动初始化。

部署和使用

initramfs镜像制作

  1. 为了避免initrd阶段systemd的影响,需要制作一个剔除systemdinitramfs镜像,并以该镜像进入initrd流程。使用如下命令:
# dracut -f --omit "systemd systemd-initrd systemd-networkd dracut-systemd" /boot/initrd_withoutsd.img
  1. 得到上述initramfs后,在grub.cfg中增加新的启动项,aarch64下的路径为/boot/efi/EFI/openEuler/grub.cfgx86_64下的路径为/boot/grub2/grub.cfg
...
### BEGIN /etc/grub.d/10_linux ###
menuentry 'openEuler (5.10.0-60.18.0.50.oe2203.aarch64) 22.03 LTS' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-60.18.0.50.oe2203.aarch64-advanced-53b0b401-a14c-43f1-9d96-9a66143bbb17' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt2'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2  2a438da5-a305-4682-a45f-5cee6f02c3c6
        else
          search --no-floppy --fs-uuid --set=root 2a438da5-a305-4682-a45f-5cee6f02c3c6
        fi
        echo    'Loading Linux 5.10.0-60.18.0.50.oe2203.aarch64 ...'
        linux   /vmlinuz-5.10.0-60.18.0.50.oe2203.aarch64 root=/dev/mapper/openeuler-root ro rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me console=tty0 crashkernel=1024M,high smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 video=efifb:off
        echo    'Loading initial ramdisk ...'
        initrd  /initramfs-5.10.0-60.18.0.50.oe2203.aarch64.img
}
### 新增如下启动项 ###
menuentry 'Boot with sysmaster' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-60.18.0.50.oe2203.aarch64-advanced-53b0b401-a14c-43f1-9d96-9a66143bbb17' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt2'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2  2a438da5-a305-4682-a45f-5cee6f02c3c6
        else
          search --no-floppy --fs-uuid --set=root 2a438da5-a305-4682-a45f-5cee6f02c3c6
        fi
        echo    'Loading Linux 5.10.0-60.18.0.50.oe2203.aarch64 ...'
        linux   /vmlinuz-5.10.0-60.18.0.50.oe2203.aarch64 root=/dev/mapper/openeuler-root rw rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap video=VGA-1:640x480-32@60me console=tty0 crashkernel=1024M,high smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 video=efifb:off init=/init
        echo    'Loading initial ramdisk ...'
        initrd  /initrd_withoutsd.img
}
...
  1. 增加启动项时,拷贝一份原有启动项,并做以下四处修改:

  2. 新增启动项需要避免和原启动项重名,例如上述案例中设置为Boot with sysmaster

menuentry 'Boot with sysmaster'
  • 内核启动参数需要修改root=/dev/mapper/openeuler-root roroot=/dev/mapper/openeuler-root rw。因为目前sysmaster并未实现在切根后重新挂载根分区的功能,所以小系统中的根分区需要挂载成rw

  • 启动参数中需要显示指定一号进程init=/init,在安装脚本install_sysmaster.sh中,我们会生成/init软链接指向sysmaster-init,从而避免内核以systemd作为1号进程启动。

  • initrd项需要对应修改为initrd /initrd_withoutsd.img,此img为步骤1生成。

安装sysmaster

  1. 构建sysmasterdebugrelease二进制版本:
# cargo build --all [--release]
  1. 在源码根目录下使用安装脚本install_sysmaster.shsysmaster的二进制文件、系统服务、配置文件等安装到系统中,执行以下命令:
# sh -x tools/run_with_vm/install_sysmaster.sh [debug|release]

可以指定安装debugrelease版本,未指定时默认安装debug二进制版本。

  1. 启动串口登陆服务:

根据体系结构启动对应的串口登陆服务,aarch64对应serial-getty-ttyAMA0.servicex86_64对应serial-getty-ttyS0.service。此服务主要针对有console串口的情况,例如virsh console进入串口,私人笔记本创建的虚拟机,默认应该都是只有tty1

开机启动后手动执行sctl start命令启动串口登陆服务,或者将该服务添加到multi-user.target配置的Requires字段中实现开机自启。

# sctl start <serial-getty-ttyAMA0.service|serial-getty-ttyS0.service>

系统启动

虚拟机重启,在grub引导启动界面选择对应的启动项。启动后,可以通过tty1或者ssh登陆。

卸载sysmaster

执行以下命令,可以从系统中卸载sysmaster

# rm -rf /lib/sysmaster
# rm -rf /etc/sysmaster
# unlink /init

最后更新: November 6, 2023
创建日期: April 20, 2023