From host files to guest execution
A kernel image is not a whole machine image. The loader combines a Linux bzImage, an optional initrd, a command line, and the VM's device layout into guest physical memory. The disk supplies the root filesystem; it does not have to contain a bootloader.
- Read the bzImage setup header, check its magic and 64-bit entry flag, and copy the protected-mode payload to guest address 0x100000.
- Install the GDT, initial page tables, E820 memory map and multiprocessor table. Place the command line and optional page-aligned initrd in RAM.
- Configure the bootstrap vCPU's segment and control registers for long mode. Its instruction pointer targets the kernel's 64-bit entry; RSI points at the zeropage.
- The vCPU run loop enters the guest. Linux discovers virtio-MMIO devices from command-line entries and mounts the root filesystem according to your boot arguments.
The boot contract lives in memory
Zeropage and command line
The Linux boot-parameter structure is placed at 0x010000; the NUL-terminated command line is at 0x020000. The loader adds a virtio_mmio.device=SIZE@ADDRESS:IRQ argument for each device, followed by the configured user arguments.
A map, not just a byte count
The E820 map tells Linux which guest addresses are RAM. The x86 layout reserves the MMIO hole from 0xd0000000 to 0x100000000; large-memory VMs map additional RAM above it. Initial page tables establish the identity mapping needed to enter the kernel.
The bootstrap processor starts the rest
The Linux loader initializes vCPU 0's entry registers. The multiprocessor table describes the configured processors so the guest can bring up additional vCPUs. kube-vm supplies virtual interrupt-controller and timer state through KVM.
Choose what becomes PID 1
From the repository root, after make build, a direct initrd boot can look like this. Supply your own compatible kernel and initrd:
./bin/kube-vm -server=false \
-kernel ./bzImage \
-initrd ./initrd.cpio.gz \
-mem 1024 -cpu 2 \
-cmdline "console=hvc0 reboot=t"
An initrd normally supplies /init. For a raw ext4 root disk, attach it with -block or -cow-block and configure a root such as root=/dev/vda rw. The Docker disk chapter explains why this is vda, not vda1, for disks built by the Make target.