This is about QEMU

Qemu is VMM ( virtual machine monitor. That means QEMU helps to run your virtual machine. This can be a full visualization in software or a hardware assisted one( VT ). KVM (Kernel-based Virtual Machine) is a visualization infrastructure for the Linux kernel that turns linux into a hypervisor. KVM comes in form of a kernel module. QEMU can use this kernel module to avail the visualizationfunctionalists of processor. QEMU avails them thru ioctl calls to kernel.

I referred kvm-76 source code to make this doc. I picked up an older version to understand KVM better.

I have copy/pasted source code from kvm-76 to here and used C style syntax for better code flow understanding. Those who are familiar with C language can understand it better. I have colored functions to understand the nesting better

  • BLACK , RED, ORANGE , GREEN, BLUE

main() {

 layer_0 () {
         layer_1 () {
                 layer_2 () {
                         layer_3() 
                               layer_4()    

/ main() function is in file qemu/vl.c /

main() {

/* If you have seen manual page of qemu, you might be aware of various

* types of machines that qemu can emulate. This can be selected using a
* command line option to qemu executable. All these different machine types 
* are stored as QEMUMachine in the qemu source code. All these machines needs
* to be stored in a linked list. register_machine() routine does that job.

*/                 
register_machines();

/ if we have KVM defined & kvm is supported; Let us initialise KVM /

if USE_KVM

kvm_qemu_init() {

       /* kvm_init() function malloc memory for kvm_context_t structure. This
        * structure important data structure like  below.
        *          struct kvm_context {
        *             /* Filedescriptor to /dev/kvm */
        *             int fd;
        *             /* file descriptor to virtual machine */   
        *             int vm_fd;
        *             /* file descriptor to no of vcpus */ 
        *             int vcpu_fd[MAX_VCPUS];
        *             struct kvm_run *run[MAX_VCPUS];
        *             /* Callbacks that KVM uses to emulate
        *              * various unvirtualizable functionality
        *              * 
        *               struct kvm_callbacks *callbacks;
        *           }
        *
        *    

        *  /dev/kvm device file is opened in read-write mode. 
        *  /dev/kvm device node is created upon insmod of kvm kernel module. 
        *  The file handle ( of /dev/kvm ) that opened in last step is 
        *  assigned to fd member in kvm_context_t. kvm_context_t has got an
        *  interesting member called "callback" (which is of type 
        *  structure "kvm_callbacks").
        *  This structure holds pointers to various functions that KVM will
        *  call them when it encounters something that cannot be virtualised,
        *  such as accessing hardware devices via MMIO or regular IO.
        *  This structure contains  routines like (*inb)(),(*outb)(),
        *  (*mmio_read)(), (*halt)(), (*io_window)(),    
        *  (*try_push_interrupts)(), (*post_kvm_run)(), (*pre_kvm_run)(). 

i * This structure is statically initialized and passed to vm_init()

        * and the same is assigned to kvm->callbacks member. 
        */

        kvm_init( ) {
           kvm_context_t kvm;
           fd = open("/dev/kvm", O_RDWR);
           kvm->fd = fd;
           kvm->vm_fd = -1;
           kvm->callbacks = callbacks;
           kvm->opaque = opaque;
        }


        /* chapter 3 is dedicated to talk about kvm_callbacks. please refer 
         * that chapter for more info.
         */



         /* We got handle to /dev/kvm in previous code snippet. we can 
          * create  a VM thru ioctl call to this file handle.  There will be 
          * a file handle for each vm created. The same is stored in vm_fd 
          * member of kvm_context 
          */

          kvm_qemu_create_context() {
             kvm_create() {
                  kvm_create_vm() {
                    /* we will explain more on VM creation and running 
                    * in next chapter. As you can see VM creation is thru
                    * an ioctl call to /dev/kvm.
                    */
                    fd = ioctl(kvm_context->fd, KVM_CREATE_VM, 0);
                    kvm_context->vm_fd = fd; 
                  }

          }
 }                 


 /* We can specify "how much memory a VM machine should use" as 
  * a parameter to qemu executable.  The same is allocated and stored in 
  * phy_ram_base. I did not plan to explore more on the ram 
  * allocation. Is anybody out there to help me ? i will add it then.
  */        
  phys_ram_base = qemu_alloc_physram(phys_ram_size);


 /* QEMUMachine structure has a function called .init() . 
  * This is different for each machine type.
  * 
  *  Lets take the case of pc_machine.
  *  QEMUMachine pc_machine = {
  *                        .name = "pc",
  *                        .desc = "Standard PC",
  *                        .init = pc_init_pci,
  *                         .ram_require = VGA_RAM_SIZE + PC_MAX_BIOS_SIZE,
  *   };
  *  .init() routine is the one who actually loads os , bootloader etc.  
  *    
  */   

  machine->init(ram_size, vga_ram_size, boot_devices, ds,
              kernel_filename, kernel_cmdline, initrd_filename, cpu_model) {

        pc_init_pci() {
                pc_init1() {

                    /* allocate memory and register */
                    ram_addr = qemu_ram_alloc(0xa0000);
                    cpu_register_physical_memory(0, 0xa0000, ram_addr) {
                          kvm_register_phys_mem() {
                                /* KVM_SET_USER_MEMORY_REGION is covered 
                                 * little bit more in datail in
                                 * in chapter 4
                                 */
                              r = ioctl(kvm->vm_fd, 
                                        KVM_SET_USER_MEMORY_REGION, &memory);
                            }


                    }

                }

        }

        /* Load linux kernel image if we have specified qemu to load
         * a linux image as a command line parameter to qemy
                 */
        load_linux(kernel_filename, initrd_filename, kernel_cmdline);  

  }  

  /* sleep for events */                
main_loop() {

    kvm_main_loop() {
          while (1) {
                main_loop_wait(1000);

results matching ""

    No results matching ""