To verify Linux booting in SVM, we need the following components:
-
SVM components (in guest VM)
- Linux kernel
- RAM Disk image
- Device tree
-
HOST HLOS components
- Linux kernel with Gunyah Hypervisor linux drivers
- crosvm user space app as VMM
- rootfs disk image containing all host related tools and SVM image files
Following sections describe details on the images. These are already generated into mounted volumes as part of the docker image building process. If any of the images need to be rebuilt, the same script build-docker-img.sh can be used to create the tools, it will only re-create any image that's missing. If the sources need to be retained, then rm -rf command in the build scripts can be commented off.
The linux kernel image generated during docker build process to test qemu/aarch64 functionality should work for this purpose.
The RAM Disk image (based on busybox) generated during docker build process to test qemu/aarch64 functionality should work here as well.
Device tree will be generated by crosvm (VMM) running in Host HLOS (PVM) based on the command line arguments passed while launching it. Resource Manager will patch the DT before its passed on to the SVM Linux kernel.
Note: Following details are provided only as information if anything need to be changed for experimentation purposes. All these following images have already been generated during the
build-docker-img.shstep. So if you do not wish to change anything, proceed to step Test SVM loading
The linux kernel image generated during docker build process already patches the linux kernel sources with Gunyah hypervisor linux drivers. These details can be examined in the provided script clone-linux.sh which is used to build linux image.enables to test qemu/aarch64 functionality should work for this
A VMM is required to interact with Gunyah hypervisor to create, configure and launch the SVM and execute any OS in it. For the demo, crosvm user space app is built to handle this task. The details can be found in the included scripts clone-crosvm.sh and build-crosvm.sh.
Since crosvm sources and build can be really huge, sources and build output are deleted after copying the output binary image. This output binary is included in the rootfs disk image which is built after.
NOTE: Either a newer version of the Docker or a newer ubuntu distro (22.04 and later) has been encountering the following error..!! Observation was that the build works on host machine but doesn't in docker environment or vice versa. Currently we do not have a workaround for this problem, but if an older version of ubuntu distro (20.04) is available should work fine.
Trying to pull gcr.io/crosvm-infra/crosvm_dev:r0040...
Error: parsing image configuration: Get "https://storage.googleapis.com/artifacts.crosvm-infra.appspot.com/containers/images/sha256:6b0c28f5c282c677cc50a927e2227e5d89209ae3c6fa15db10593f7837a644fb": x509: certificate signed by unknown authority
Crosvm generated here will have a dependency on libgcc_s.so.1, which will be generated later during the rootfs disk image generation.
Since the SVM linux kernel/ramdisk images and other host HLOS components need significant amount of storage space, we cannot just use ramdisk for host HLOS running in PVM. Instead we have to prepare the extfs formatted rootfs disk image that can be mounted as virtio disk. This method will provide the storage space for host HLOS without consuming the valuable RAM space.
Since generation of rootfs image also consumes huge space to generate, source and build files will be deleted after the binaries are copied to reference folder. If needed to retain source/build files, comment off the rm -rf command in the build shell scripts.
At a high level, this process does the following:
- Downloads the stock linaro rootfs extfs disk image (tiny initramfs to keep the size small)
- Downloads the Linaro OpenEmbedded Reference Platform Build (OE RPB) repo and generates the disk image
- This step is taken only for the purpose of getting libgcc_s.so.1 file which is dependency for crosvm
- This step takes significant amount of time
- A potential optimization to avoid this huge build burden is a TODO later, but provides a potential if any useful components from this build can be utilized
- Prepare
referencefolder for the filesystem - Prepare an empty extfs disk image of required size
- Copy all the required files into the rootfs extfs disk image
- File tree from stock Linaro rootfs
- All kernel .ko files from the kernel build
- crosvm (VMM)
- ramdisk, kernel image (for SVM)
After the rootfs reference folder is created at the path ~/mnt/workspace/rootfs/reference, any additional file changes can be performed there. To make a new rootfs image with this modified rootfs reference folder, perform the following operations.
delete the generated rootfs file
rm -f ~/mnt/workspace/rootfs/rootfs-extfs-disk.imgand then run the rootfs generating script
cd ~/mnt/workspace/rootfs
build-rootfs-img.shThis will add the environment variable into ~/mnt/workspace/.wsp-env make sure to remove the duplicates and retain only the relevant ones.
Alternately build-docker-img.sh can be run on host machine again to generate this image.
If any modifications to the reference tree is done that exceeds the disk size created, or if more free disk space needed in the PVM, the disk size value in the script build-rootfs-img.sh can be adjusted to any other value (say 1G)
Before:
. ~/utils/bldextfs.sh -f ${WORKSPACE}/rootfs/reference -o ${WORKSPACE}/rootfs/rootfs-extfs-disk.img -s 800MAfter:
. ~/utils/bldextfs.sh -f ${WORKSPACE}/rootfs/reference -o ${WORKSPACE}/rootfs/rootfs-extfs-disk.img -s 1GNow all the components needed to test linux running in SVM are ready. Run qemu with the following commands, note that dtb need to be generated again (When any size changes that can potentially move around stuff in the memory map/dt).
Note that the rootfs disk image is mounted RW, so any changes made will be persistent from HLOS running in PVM. So even the command history or any changes to .rc files would be available. But then it also means if the image gets corrupted it needs to be re-generated as mentioned above from the reference folder. If reference folder is deleted to reclaim space, keep a backup copy of the rootfs-extfs-disk.img file in order to avoid download/build time and space consumption.
cd ~/mnt/workspace
run-qemu.sh dtbAfter dtb is generated, run the command to launch qemu
run-qemu.shThis should result into booting to much complete linux environment in PVM via systemd init. Ignore the errors shown (unless those are fatal errors or crashes), if things went well, then a login prompt and a shell prompt should be seen
.
.
[ OK ] Started User Login Management.
[ OK ] Reached target Multi-User System.
Starting Record Runlevel Change in UTMP...
Reference-Platform-Build-X11 3.0+linaro qemuarm64 ttyAMA0
qemuarm64 login: root (automatic login)
.
.
root@qemuarm64:~#Once on the prompt, verify if the hypervisor related nodes showup
cd /sys/firmware/devicetree/base/hypervisor
find .Now launch crosvm using the following command to create a SVM and run Linux OS in it. A shell script has been provided at /usr/gunyah/svm.sh to make it easier to launch.
/usr/gunyah/crosvm --no-syslog run --disable-sandbox \
--serial=type=stdout,hardware=virtio-console,console,stdin,num=1 \
--serial=type=stdout,hardware=serial,earlycon,num=1 \
--initrd /usr/gunyah/initrd.img --no-balloon --no-rng \
--params "rw root=/dev/ram rdinit=/sbin/init earlyprintk=serial panic=0" \
/usr/gunyah/ImageOR
/usr/gunyah/svm.shThe following shows the console logs of SVM. This could be pretty slow since each uart IO is going through the crosvm virtio-console (ie the control needs to switch from SVM back to PVM crosvm app to output the char to the actual console).
root@qemuarm64:~# /usr/gunyah/crosvm --no-syslog run --disable-sandbox --serial=type=stdout,hardware=virtio-console,console,stdin,num=1
--serial=type=stdout,hardware=serial,earlycon,num=1 --initrd /usr/gunyah/initrd.img --no-balloon --no-rng --params "rw root=/dev/ram rd
init=/sbin/init earlyprintk=serial panic=0" /usr/gunyah/Image
[2023-09-15T21:44:00.904189296+00:00 INFO crosvm] crosvm started.
[2023-09-15T21:44:00.935025408+00:00 INFO crosvm] CLI arguments parsed.
[HYP] Emulated RAZ for ID register: ISS 0x36002f
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x000f0480]
[ 0.000000] Linux version 6.5.0-00025-gd9af2a6a5a22 (yvasi@buildkitsandbox) (clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a), LLD 15.0.7) #1 SMP PREEMPT Fri Sep 15 10:13:26 PDT 2023
[ 0.000000] KASLR enabled
[ 0.000000] random: crng init done
[ 0.000000] Machine model: linux,dummy-virt
[ 0.000000] earlycon: uart8250 at MMIO 0x00000000000003f8 (options '')
[ 0.000000] printk: bootconsole [uart8250] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] NUMA: No NUMA configuration found
[ 0.000000] NUMA: Faking a node at [mem 0x0000000080000000-0x000000008fffffff]
[ 0.000000] NUMA: NODE_DATA [mem 0x8ff709c0-0x8ff72fff]
[ 0.000000] Zone ranges:
This script svm.sh can take additional arguments and pass on to crosvm app. As an example, we can provide the number of cpu's as additional argument to create SVM with more CPU cores. Note that adding more cores to SVM linux session might make console logs even slower..!!
/usr/gunyah/svm.sh --cpus 4This should show that the Linux kernel is running in the SVM. Once verification of this linux environment is complete, issue poweroff command in the SVM linux shell to go back into the PVM linux environment. SVM can be launched again to verify a different configuration.
/ # poweroff
/ # umount: can't unmount /: Invalid argument
swapoff: can't open '/etc/fstab': No such file or directory
The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes
Requesting system poweroff
[ 7204.608721] reboot: Power downNote: Current latset version of Gunyah freezes on second time launch after SVM power off. This is working fine in the original version of gunyah before the updates, SVM relaunch feature can be verified on that original version of Gunyah/RM sources.
Press ctrl-a and x to exit Qemu
Follow-up TODO's:
The following areas require work, any help on these is appreciated:
- Enable
ssh_serverin PVM Linux OS image, so that we can connect multiple ssh sessions and test multiple SVM sessions simultaneously. - Fix poor performance of the SVM Linux console, for example using the Gunayh RM Console driver.