Chapter 135: DomU Linux on i.MX6ULL¶
What: start a tiny DomU Linux guest on the real i.MX6ULL board after Xen and Dom0 are working.
Why: QEMU proved the mechanics. The i.MX6ULL proves the real constraints: one CPU, small RAM, real storage, real serial logs, and no room for vague boot assumptions.
Focus: success is isolation, not performance. A tiny DomU that can die without killing Dom0 is the goal. DomU: an unprivileged Xen guest domain. Dom0: the privileged Xen control domain that creates and manages DomU guests.
135.1 Starting point¶
Do not begin here until Chapter 134 works:
U-Boot -> Xen -> Dom0 Linux -> shell
Minimum Dom0 proof:
# uname -a
# cat /proc/cmdline
# ls /sys/hypervisor
# dmesg | grep -i xen
If Dom0 is unstable, adding DomU only hides the bug.
135.2 What changes from QEMU¶
QEMU gave us comfort:
easy reset,
plenty of fake RAM,
configurable CPU count,
no SD-card wear,
easy file injection.
i.MX6ULL gives us reality:
one Cortex-A7 core,
512 MiB RAM on the reference board,
real U-Boot environment,
real SD/eMMC,
real serial console,
real DTB,
real memory pressure.
So the first DomU must be modest:
memory = 32 or 64 MiB
vcpus = 1
initramfs root
Xen console only
no networking
no block device
no passthrough
135.3 Upgrade Dom0 from “proof shell” to “control domain”¶
Chapter 134’s smallest Dom0 may not include xl. For DomU, Dom0 needs:
Xen toolstack,
xenstore,
xenfs,
event channel support,
enough filesystem to hold DomU kernel/initramfs/config.
Check:
# which xl
# xl info
# xl list
If xl is missing, rebuild Dom0 rootfs with Xen tools, or use an NFS rootfs while developing.
135.4 Dom0 kernel options¶
Dom0 should have:
CONFIG_XEN=y
CONFIG_XEN_DOM0=y
CONFIG_HVC_XEN=y
CONFIG_XEN_DEV_EVTCHN=y
CONFIG_XENFS=y
CONFIG_XEN_SYS_HYPERVISOR=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_NETDEV_BACKEND=y
For this chapter, block and net backend are not strictly needed, but enabling them avoids rebuilding immediately in the next experiment.
135.5 Prepare transfer path¶
You need a way to place DomU files into Dom0:
/boot/domu-zImage
/boot/domu-initramfs.cpio.gz
/etc/xen/imx6ull-domu.cfg
Good options:
NFS mount from host,
TFTP fetch into Dom0,
copy to SD card boot partition,
include files in Dom0 rootfs image.
For iteration, NFS is easiest:
# mkdir -p /mnt/host
# mount -t nfs -o nolock 192.168.7.1:/srv/nfs/imx6ull /mnt/host
# mkdir -p /boot /etc/xen
# cp /mnt/host/domu-zImage /boot/
# cp /mnt/host/domu-initramfs.cpio.gz /boot/
# cp /mnt/host/imx6ull-domu.cfg /etc/xen/
If NFS is not working yet, use the SD card. Do not debug NFS and DomU at the same time.
135.6 Build DomU kernel¶
Use the same Linux source as Chapter 133 or the Part IV kernel tree.
Configure a DomU build:
$ make ARCH=arm O=../linux-domu-imx6ull imx_v6_v7_defconfig
Enable:
$ scripts/config --file ../linux-domu-imx6ull/.config \
-e XEN \
-e HVC_XEN \
-e XEN_DEV_EVTCHN \
-e XENFS \
-e BLK_DEV_INITRD \
-e DEVTMPFS \
-e DEVTMPFS_MOUNT
$ make ARCH=arm O=../linux-domu-imx6ull olddefconfig
Build:
$ make ARCH=arm O=../linux-domu-imx6ull \
CROSS_COMPILE=arm-none-linux-gnueabihf- -j$(nproc) zImage
Copy:
$ cp ../linux-domu-imx6ull/arch/arm/boot/zImage /srv/nfs/imx6ull/domu-zImage
135.7 Build DomU initramfs¶
Use static BusyBox. DomU /init:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
echo
echo "======================"
echo " i.MX6ULL DomU alive"
echo "======================"
echo
uname -a
cat /proc/cmdline
head -5 /proc/meminfo
echo
echo "Try killing me from Dom0 with: xl destroy imx6ull-domu"
exec /bin/sh
Pack:
$ find rootfs-domu -print0 | cpio --null -ov --format=newc | gzip -9 \
> /srv/nfs/imx6ull/domu-initramfs.cpio.gz
Keep it small:
$ ls -lh /srv/nfs/imx6ull/domu-initramfs.cpio.gz
If it is large, stop and shrink it. This board has no RAM to waste.
135.8 Domain config¶
Create imx6ull-domu.cfg:
name = "imx6ull-domu"
kernel = "/boot/domu-zImage"
ramdisk = "/boot/domu-initramfs.cpio.gz"
memory = 64
vcpus = 1
extra = "console=hvc0 rdinit=/init"
on_crash = "preserve"
If 64 MiB is too much for your Dom0 memory budget, try 32 MiB. If 32 MiB is too small for your kernel/initramfs, reduce the initramfs before raising memory.
135.9 Start DomU¶
In Dom0:
# xl create -c /etc/xen/imx6ull-domu.cfg
Expected:
i.MX6ULL DomU alive
/ #
Detach:
Ctrl-]
List:
# xl list
Expected shape:
Name ID Mem VCPUs State Time(s)
Domain-0 0 ... 1 r----- ...
imx6ull-domu 1 64 1 r----- ...
135.10 Prove there are two Linux systems¶
In Dom0:
# uname -a
# cat /proc/cmdline
# xl list
In DomU:
# uname -a
# cat /proc/cmdline
# head -5 /proc/meminfo
Record both. The kernels may be built from the same source, but they are not the same running system.
135.11 Restart DomU¶
From Dom0:
# xl shutdown imx6ull-domu
# xl list
If graceful shutdown is not supported by the tiny guest:
# xl destroy imx6ull-domu
Start again:
# xl create -c /etc/xen/imx6ull-domu.cfg
The restart is important. A domain that boots only once is not an understood domain.
135.12 Prove failure isolation¶
Inside DomU:
# kill -SEGV 1
or from Dom0:
# xl destroy imx6ull-domu
Now prove Dom0 survived:
# date
# xl list
# dmesg | tail -40
The board must not reset. Dom0 must remain responsive.
This is the core result of the chapter.
135.13 Memory pressure check¶
In Dom0:
# free -m
# xl info | grep -i memory
Start DomU and run again:
# xl create /etc/xen/imx6ull-domu.cfg
# free -m
# xl list
Write down:
Dom0 memory before:
Dom0 memory after:
DomU assigned:
Free memory remaining:
This keeps the experiment honest. The i.MX6ULL is small.
135.14 What this proves¶
This chapter proves:
Xen can create a second Linux domain on real i.MX6ULL hardware.
Dom0 and DomU have separate assigned memory.
DomU has a separate kernel command line.
DomU can be destroyed without resetting the board.
The serial log can show real HYP-mode virtualization, not only QEMU.
135.15 What this does not prove¶
It does not prove:
good performance,
hard real-time behavior,
safe device passthrough,
production-ready update flow,
that single-core i.MX6ULL is a good multi-guest product platform.
One Cortex-A7 means one physical execution engine. Xen can schedule domains. It cannot create another core.
135.16 Failure cases on the physical platform¶
A guest allocation that exceeds the available whole-system budget can fail or starve Dom0. A missing initramfs or unusable /init breaks the guest’s runtime contract. Selecting the physical UART as its console does not grant DomU ownership of that device.
A failure in guest user space may be contained while Dom0 remains operational, but that outcome must be observed for the actual setup. It does not establish recovery from a shared-device or control-domain failure.
135.17 Key Notes¶
Dom0 and DomU have separate kernel and memory views while sharing the i.MX6ULL’s one physical CPU. Scheduling capacity and failure containment are different objectives.
Guest memory consumes a whole-platform budget alongside Dom0, Xen and supporting allocations. A small nominal guest size is not a complete memory account.
Virtual console and managed guest interfaces avoid assuming that a physical UART or peripheral belongs to DomU.
Destroying a guest can contain a workload failure, but differs from an orderly shutdown that protects persistent data.
Guest survival tests do not establish DMA isolation, real-time guarantees or recovery from a failing control domain.
135.18 Pitfalls¶
Using a giant Dom0. The board has limited RAM.
Using a giant DomU. Start with 32 or 64 MiB.
Expecting physical UART in DomU. Use
hvc0.Debugging DomU before
xl infoworks. Toolstack first.Forgetting this is one physical CPU. Do not expect parallel throughput.
Treating destroy as production shutdown. It is fine for initial example, not for a product.
Skipping memory accounting. Small boards punish optimism.
135.19 Going deeper¶
Xen
xltoolstack documentation.Xen ARM DomU documentation.
Xen console documentation.
Chapter 136 for device assignment and DMA boundaries.