In the previous post in this series, we dove deep into container technology and looked at how to implement some functionality into containers applicable to embedded devices. In this post, we will look at type-2 hypervisors and dive deep into practical ways to use them for embedded systems. This post will be light on content as I am quite busy currently, but wanted to wrap up this series. I will try to circle back and dive deeper into this topic later.
Note: all the code, scripts, etc. are archived in a git repo at GitHub.
Diving In
As a refresher from the Types of Virtualization post, type-2 hypervisors are virtualization systems in which a Host OS sits between the Guest OS and the hardware. Sometimes, especially when the Guest OSes instruction set differs from the Host OSes instruction set, this type of hypervisors are called emulators. In this context, this type of hypervisor is well-suited for embedded systems development and test. For this deep dive, I will be focusing on the emulation side of type-2 hypervisors. (The other side of type-2 hypervisors are more like VirtualBox and are not particularly useful for embedded systems development).
QEMU as a Development Platform
QEMU is an open-source emulator which has broad community support and contains libraries for emulating a large number of targets of many different instruction sets and peripherals. This makes it a particularly useful tool for developing code for a target for which you don’t have real hardware.
Setting up a QEMU Target
Luckily, QEMU has prebuilt packages for most platforms you can simply install using the package manager of your choice. I’m going to be targeting the aarch64 (also referred to as arm64 in Linux land) architecture for emulating a virtual platform similar to the Raspberry Pi 3 (and newer). I have installed the package on my Linux Mint machine which provides qemu-system-aarch64
. With this emulator available, I can invoke the emulator with the following command:
qemu-system-aarch64 -m virt -M 1G -kernel kernel.elf
This command will start up an ARMv8-A-based virtual machine, with 1GB of RAM, and load the code in kernel.elf.