Linux KVM as a Learning Tool

Low-level system programming is a difficult task, but with Linux KVM, it's a whole lot easier.

the guest will exit from guest mode, and the configured outb() callback function is called in user mode (with values 0xf1 and 0x0a for its second and third parameters, respectively).

Initially, use dummy callbacks. Create and reference them in a variable called my_callbacks, as shown in Listing 2. Most field names are self-explanatory, but for a brief description of each of them, refer to the comments in the structure definition in libkvm.h.

To create the virtual machine itself, use kvm_create(), whose second argument is the amount of RAM in bytes desired for it, and the third argument is the address of a location that will in turn contain the address of the beginning of the memory space reserved for the virtual machine (the “guest memory” box in Figure 1). Note that kvm_create() does not allocate memory for the virtual machine.

To create the first virtual CPU, use kvm_create_vcpu() with a value of 0 for the slot parameter—versions less than 65 create the first virtual CPU during the call to kvm_create().

There are several methods to allocate memory for the virtual machine—for example, kvm_create_phys_mem(). The second argument of kvm_create_phys_mem() is the starting physical address of the requested region in the guest memory (in the pseudo-“physical memory” of the virtual machine, not in the physical memory of the host). The third argument is the length, in bytes, of the region. The fourth indicates whether dirty page logging should be activated in the requested region, and the fifth argument indicates whether the pages may be written. On success, it returns the location of the allocated memory area as an address in the virtual address space of the calling process.

Invoke the functions of Listing 1 within the same KVM context to create your first virtual machine, and execute it with kvm_run(). This function will return only if an I/O handler pointed in my_callbacks returns a nonzero value or an exception occurs that neither the guest OS nor KVM can handle.

Listing 3 contains the code for the launcher, including the load_file() function to copy the guest kernel image from a file to the virtual machine's memory space. Why is this image copied at offset 0xf0000 of the guest's memory space? Because of the way real-mode works, as explained in the next section.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Exit instead of hlt

Curious's picture

Thanks for this excellent article. I've tested out the sample but the program never returns after the kvm_run() call. I guess this is because the vcpu is halted in the last instruction of the test program. But how do I exit the KVM altogether and resume execution from kvm_run() onwards? Is there any documentation for libkvm somewhere I can consult?

This appears to be the libkvm in question, no?

Ben Scherrey's picture

See the userspace git tree. Is this the lib we need to be building to follow this article? I've been looking to do something like this with KVM for a while to create my own forth-like environment without having to screw around with low level hardware (or at least put it off til something interesting already works). Look forward to the follow up article. When is it scheduled?

-- Ben Scherrey

LibKVM on Ubuntu? Nonesuch...

basicman's picture

My attempt to follow this tutorial died on page 2, when it announced that all of the examples would be using the LibKVM library. Several hours of searching on Google and I've found nothing; no way to install or use the LibKVM library unless I'm on BSD.

If anyone has a workaround for this, I'd love to hear it. I was really looking forward to following the tutorial.

Different libkvm

Mitch Frazier's picture

That's a different library. You need to install the qemu-kvm-devel package. Note you will probably have to get it directly from sourceforge since it does not appear to be in the Ubuntu repos. I don't use Ubuntu much so maybe I'm overlooking something, however, I know that openSUSE does not have a package for it either (at least in the standard places at 11.0). Make sure that you get the version that corresponds to the version of kvm that you have installed. For example, here is a link to the -devel package for release 88.

If you have to install it from sourceforge some fiddling around will probably be required. First, you'll have to build it, then install it, and then potentially modify your include/library paths to find the needed items.

Mitch Frazier is an Associate Editor for Linux Journal.

I used REHL5.5 installed devel package for release 88

jniu's picture

I used REHL5.5 installed devel package for release 88, but still cannot find libkvm.h and libkvm.a, the installation was successful, can you give me some suggestion? thanks.