Skip to content

QEMU Virtual Armory

ckuethe edited this page Mar 16, 2015 · 27 revisions

Introduction

It is often useful to have a test environment independent of hardware. This environment is based on a Versatile Express board with a Cortex-A9 cpu; this hardware was chosen for Trustzone support in QEMU-tz which requires either and A9 or A15, and Versatile Express with A9 support in uBoot. This should provide a low risk way to test Secure Boot, for example. (Trustzone, EL3, etc. support seems to be new and a working example configuration has not yet been developed)

Compile Kernel

$ wget https://www.kernel.org/pub/linux/kernel/v3.x/testing/linux-3.19-rc2.tar.xz
$ tar xf linux-3.19-rc2.tar.xz
$ export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
$ make vexpress_defconfig
    # add "console=ttyAMA0,115200 panic=5" to kernel args
    # enable Block Layer > Large Files
    # enable dm-verity
$ make menuconfig
$ make -j4 zImage dtbs modules
$ mkdir -p /tmp/linux-trustzone/boot
$ cp arch/arm/boot/{,z}Image arch/arm/boot/dts/vexpress*ca9*dtb /tmp/linux-trustzone/boot/
$ make modules_install INSTALL_MOD_PATH=/tmp/linux-trustzone

Compile uBoot

Coreboot has some discussion about building a bios image for qemu. Select board type vexpress_ca9x4.

$ make vexpress_ca9x4_config
$ vi include/configs/vexpress_common.h
    # add CONFIG_RSA, CONFIG_FIT_SIGNATURE, CONFIG_CMD_EXT2
    # change the environment config to point to MMC
    # fix compiled-in config
    # maybe disable environment manipulation?
    # maybe change TEXT_BASE, or use mkimage to allow loading by "qemu -bios"?
$ make oldconfig # or menuconfig
$ env CROSS_COMPILE=arm-linux-gnueabihf- make -j4
$ tools/mkimage -A arm -a 0x4000000 -n "uBoot_BIOS" -d u-boot.bin u-boot.rom
$ D=/tmp/linux-trustzone/boot
$ mkdir -p $D
$ cp u-boot* $D
$ mv $D/u-boot $D/u-boot.elf
$ env CROSS_COMPILE=arm-linux-gnueabihf- make env

Prepare Disk Images

Disabling huge file support on the file system is necessary unless the kernel has been built with CONFIG_LBDAF, which is not the default for the Versatile Express.

$ truncate --size 1G Q_sbarmory.img
$ L=$(losetup --find --show Q_sbarmory.img) # assuming this returns "/dev/loop0"
$ parted $L --script mklabel msdos
$ parted $L --script mkpart primary ext4 4M 100%
$ mkfs.ext4 -O ^huge_file -L usbarmory ${L}p1
$ mount ${L}p1 /mnt
$ qemu-debootstrap --arch=armhf wheezy /mnt https://mirrors.kernel.org/debian/
$ rsync -rv /tmp/linux-trustzone/ /mnt
$ cp $UBOOTDIR/tools/env/fw_printenv /mnt/sbin
$ ln -fs fw_printenv /mnt/sbin/fw_setenv
$ chroot /mnt # do stuff like configuring software sources, setting hostname and root password
$ umount /mnt

Compile QEMU-Trustzone

TrustZone is supported by QEMU's vexpress_ca9x4 model as of c0ccb02d.

$ git clone https://github.com/qemu/qemu.git
$ cd qemu
$ ./configure --target-list=arm-softmmu --enable-seccomp --extra-ldflags="-fPIC" --extra-cflags="-fPIC"
$ make -j4
$ cp arm-softmmu/qemu-system-arm ~/bin/qemu-system-arm-trustzone

To test the new qemu binary without using trustzone

$ ~/bin/qemu-system-arm-trustzone -machine vexpress-a9,secure=on -nographic -kernel /tmp/linux-trustzone/boot/zImage -dtb /tmp/linux-trustzone/boot/vexpress-v2p-ca9.dtb -append 'console=ttyAMA0 panic=5'

To test the new qemu with trustzone (Genode is supported on vexpress_ca9x4)

$ ~/bin/qemu-system-arm-trustzone -machine vexpress-a9,secure=on -nographic -bios u-boot.rom

Run it!

Once the storage has been prepared, it can be booted with the command below. The vexpress model will not load boot code from a disk image (but this might not be an issue once I figure out how to convert uboot into a bios image).

$ qemu-system-arm-trustzone -machine vexpress-a9,secure=on -sandbox enable=on -no-reboot -net user -net nic,model=lan9118 -nographic -drive format=raw,media=disk,if=sd,file=usbarmory_rootfs.img,index=0 -kernel linux-trustzone/boot/u-boot

Once in uBoot commands are required for QEMU to be able to load and boot the kernel

setenv loadaddr 0x60008000
setenv fdt_addr 0x67f00000
setenv bootargs "root=/dev/mmcblk0p1 rw verbose console=ttyAMA0 panic=5 vmalloc=256M"
setenv bootdisk "ext2load mmc 0:1 ${fdt_addr} /boot/vexpress-v2p-ca9.dtb; ext2load mmc 0:1 ${loadaddr} /boot/zImage ; bootz ${loadaddr} - ${fdt_addr};"
env save

run bootdisk

uBoot has trouble interacting with the flash device presented by QEMU, but it can be patched to use the sdcard for storage. Once Linux has booted, the fw_setenv tool can be used to manipulate the NVRAM. The following configuration is required:

#device      offset   envsize  sectorsize
/dev/mmcblk0 0xfc000  0x4000   0x4000
Clone this wiki locally