Linux is one of the most common OS for embedded applications, it is widely available, highly performing, reliable, inexpensive, well supported while having a vast feature set.
It has out-of-the-box support for many architectures including x86, mips, arm, powerpc, etc. Linux has rich networking stack including ipv4, ipv6, firewalls, bridging, routing, wireless, bluetooth and many commercial applications. All possible features ranging from video, and sound, encryption, file systems and MMU are supported. It's becoming the operating system of choice in a wide array of embedded applications, and it even has support for real-time.
For the past two years, Linux has its own hypervisor.
The Kernel Virtual Machine hypervisor is supplied with every standard kernel today. Its foot print is minimal and mainly composed of a kernel module and some hooks for integrating into the Linux scheduler and the Linux memory manager (see Figure 2). Virtual machines are standard processes and can be managed as such, i.e., They can be prioritized using 'nice', killed using 'kill', paused using stop signal, etc.
KVM uses virtualization hardware extensions of the modern CPU. In order to virtualize the complete server/desktop/development-board environment all of the hardware components must be virtualized/emulated. Emulated components are fully emulated in software, examples are the various interrupt controllers (pic, apic, ioapic), cdrom, usb bus, pci bus, ide drivers, scsi drivers, real time clock, etc. All of them (expect for some performance critical components) are implemented in userspace. KVM uses the QEMU emulator for that.
The performance critical emulated components are implemented within the KVM kernel module, currently the shadow mmu (Memory Management Unit) and the interrupt controllers reside within the kernel. Virtualized components are such that have specific support of the hypervisor. The CPU itself is virtualized by empowering the physical CPU's hardware extensions. Except for the cpu other components are virtualized (or para-virtualized) like the network I/O, block I/O and memory (ballooning).
Every virtual cpu (vcpu) is implemented using a Linux thread. The threads are scheduled using the standard, yet sophisticated Linux scheduler. The thread can be in one of the following modes:
Standard execution consist of userspace preparing the emulated environment and call the 'run' ioctl. The KVM module executes the ioctl by switching from host mode into guest mode. Guest mode begins native instruction execution. The guest (Virtual Machine) is automatically switched out of guest mode when certain events occur, examples for such events are: physical interrupt, execution of privileged instruction like port io or changing cr3 register content, etc. Then, the KVM module tests the event nature and decides whether it can continue executing the guest code or need to exit to userspace in order to complete device emulation (see Figure 3).
Virtual machine memory is allocated the by KVM userspace process using standard mmap mechanism.
KVM processes has slightly larger virtual memory range in order to keep the hypervisor device state and memory mapped range for the virtual machine devices.
By using standard mechanism the VM memory may be swapped, shared by other guests/processes, backed by large pages or a disk file and even copy-on-write for memory over commit.