github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/Doc/evmm-init-notes.txt (about)

     1  Tboot of evmm and Linux single guest stack
     2  ===========================================
     3  
     4  
     5  Introduction
     6  ------------
     7  
     8  In order to provide authenticated boot, required by cloudProxy, we boot 
     9  evmm using tboot.  This document describes that process, which we refer 
    10  to as "TBooting evmm with a single Linux Guest".
    11  
    12  TBooting evmm with a single Linux Guest is accomplished using multiboot.  
    13  Tboot is the initial booted program but it loads six modules as indicated 
    14  in the grub.cfg file below.
    15  
    16  submenu "bootstrap.bin" "Tboot 1.7.0"{
    17  menuentry 'Ubuntu GNU/Linux, with bootstrap.bin, Tboot 1.7.0 and Linux 3.5.7.20' --class ubuntu --class gnu-linux --class gnu --class os {
    18          insmod part_msdos
    19          insmod ext2
    20          set root='(hd0,msdos1)'
    21          search --no-floppy --fs-uuid --set=root a1edf4f7-94e1-4c47-8573-0e3f54821ed3
    22          echo    'Loading Tboot 1.7.0 ...'
    23          multiboot       /boot/tboot.gz /boot/tboot.gz logging=serial,vga,memory
    24          echo    'Loading bootstrap.bin ...'
    25          module  /boot/bootstrap.bin /boot/bootstrap.bin placeholder   iommu=force
    26          echo    'Loading evmm.bin ...'
    27          module  /boot/evmm.bin /boot/evmm.bin placeholder   iommu=force
    28          echo    'Loading Linux 3.5.7.20 ...'
    29          module  /boot/vmlinuz-3.5.7.20 /boot/vmlinuz-3.5.7.20 placeholder root=UUID=a1edf4f7-94e1-4c47-8573-0e3f54821ed3 ro  quiet splash
    30          echo    'Loading initial ramdisk ...'
    31          module  /boot/initrd.img-3.5.7.20 /boot/initrd.img-3.5.7.20
    32          echo    'Loading sinit SINIT_67.BIN ...'
    33          module  /boot/SINIT_67.BIN /boot/SINIT_67.BIN
    34  }
    35  
    36  
    37  As is evident, tboot loads 5 modules:
    38      SINIT_67.BIN, which authenticates SMM handlers, checks configuration 
    39          information and prepares the machine for SMX(ENTER).
    40      bootstrap.bin is a 32-bit protected mode loader which loads evmm.bin,
    41          sets up a 64-bit environment for it, prepares arguments allowing
    42          evmm.bin to load and host under vmx, the linux image, prepares
    43          the AP's (using the SIPI initialization protocol), jumps to
    44          evmm's main routing, "vmm_main" and ensures that the AP's "wake up"
    45          in code that puts them in 64 bit mode running evmm.
    46      evmm.bin, which is the evmm image.  The evmm image consists of three 
    47          parts: a 32-bit protected mode loader called bootstrap.bin, a 
    48          header and the 64-bit evmm image.
    49      linux.gz, which is the linux image.  The linux image consists of 
    50          three parts: a 32-bit protected mode loader, a header and linux 
    51          image.
    52      initrd.gz, which is a small linux file system.  This file system 
    53          is measured as part of the linux.
    54  
    55  
    56  Tboot
    57  -----
    58  
    59  Tboot calls the evmm loader, called bootstrap.bin, contained in evmm.gz,
    60  in 32 bit protected mode.  To the bootstrap program, this appears as a 
    61  call into main.  Note that the entry point is main and NOT other 
    62  initialization code as is customary in a linux application.
    63  
    64  Upon entry, tboot provided bootstrap with:
    65      1. A protected mode 32 bit environment.
    66      2. In the recommended layout, tboot allocates 4K for stack+heap.
    67          Stack+heap at 0x8000-0x8fff
    68          Cmd arg at 0x9000
    69          Real mode kernel 0x0000-0x7fff
    70          real mode size is in real_mode_size
    71          protected mode size (linux_size-real_mode_size) is in 
    72             protected_mode _size.
    73          stack base is in bsp_stack
    74          idt descriptor is in idt_descr.
    75          heap size is in heap_size.
    76      3. An initialized GDT and IDT for 32 bit protected mode.
    77      4. Information obtained from BIOS including memory size, base address
    78          of tboot, size of tboot.
    79      5. e820 memory and apic information.
    80      6. the multiboot headers.
    81      
    82  tboot typically moves the linux protected mode base to 0x100000 when booting 
    83  a linux.  Tboot passes mbi address on stack (from %ebx) for begin_launch.  
    84  Memory layout to linux is 4GB limit, 4K page size.
    85  
    86      // address tboot will load and execute at
    87      #define TBOOT_START              0x0804000
    88      // start address of tboot MLE page table, beginning of tboot memory
    89      #define TBOOT_BASE_ADDR          0x0800000
    90  Tboot stack
    91      #define BSP_STACK_SIZE              4096
    92      #define AP_STACK_SIZE               1024
    93  
    94  
    95  
    96  Bootstrap.bin
    97  -------------
    98  
    99  The bootstrap program uses information from tboot to call vmm_main 
   100  after decompressing the 64-bit evmm image and relocating it to 
   101  evmm_start_address.  TODO: Change where Bootstrap gets loaded and
   102  put that information here.  bootstrap_start is the starting location of
   103  bootstrap and bootstrap_end is the end location.  These are selected
   104  by tboot.
   105  
   106  Bootstrap prepares the arguments for evmm and the primary linux guest.
   107  This include the 64 bit control and segment registers for evmm, an initial
   108  stack and heap and page tables in the case of evmm.  In the case of the 
   109  primary Linux guest, this includes the control and general purpose 
   110  registers, and the the entry parameters as well as a stack.  Bootstrap 
   111  ensures that all prior code is removed from the copy of the e820 table 
   112  received by the linux guest.  Bootstrap also constructs a new e820 table 
   113  which is included in the startup structure.
   114  
   115  TODO:  Currently, evmm protects itself by removing its code, heap and 
   116  stack from the primary guest's ept table.  We need to also remove tboot 
   117  and bootstrap.
   118  
   119  vmm_main is called in 64-bit protected mode with all the information 
   120  vmm_main needs to complete 64-bit initialization.
   121  
   122  Upon entry, vmm_main has
   123  
   124  1. A protected mode 64 bit environment with a 64K stack, 64-bit gdt and
   125  idt, have been initialized, and 64 bit identity mapped page tables are 
   126  present.  Boostrap calls vmm_main with a proper 64-bit call frame 
   127  with arguments properly set.  These arguments provide the information 
   128  cited below.  Bootstrap's 64 bit memory layout will include the address 
   129  space of tboot and bootstrap since vmm_main must interact with that data.  
   130  However, evmm must ensure that it never corrupts that area and it never 
   131  maps that area into a guest VM.  The 64-bit heap is prepared by evmm in 
   132  64 bit mode.  Bootstrap code should translate the 32-bit GDT and IDT 
   133  before jumping into vmm_main.  While tboot/bootstrap memory is visible 
   134  to vmm_main, but it should modify the e820 tables to make the 
   135  tboot/bootstrap memory, and its memory not accessbile from the guest.
   136  
   137  The initialized 64-bit GDT and IDT should have the following properties:
   138  
   139  2. Information obtained from BIOS (e820 map) and additional information
   140  from tboot including memory size, base address of tboot, the combined 
   141  size of tboot itself along with header information describing the size 
   142  and location of the bootstrap program so vmm_main can determine what memory 
   143  is available to it.
   144  
   145  3. Gets apic information, guest and memory map information in it's calling
   146  parameters.
   147  
   148  4. Gets the multiboot header for linux module and information
   149  required to obtain the 32 bit linux stub as well as 64 bit linux code.  
   150  
   151  5. Enters with correct PCR values in the TPM have been properly extended 
   152  for evmm by bootstrap.  [JLM to check this out.] 
   153  
   154  6. [LATER: SIPI initialization and call of AP's.]
   155  
   156  The NMI interrupt trap and the timer trap is handled by evmm.  For single 
   157  guest Linux, the timer trap is injected back into the Linux guest and
   158  all other interrupts are handled by the Linux guest.
   159  
   160  evmm does not require the fpu to be initialized prior to entry.  
   161  
   162  Upon exit, evmm clears all sensitive data 
   163  [JLM: unsure, low priority for now.]
   164  
   165  
   166  vmm_main
   167  --------
   168  
   169  vmm_main completes evmm's initialization by allocating its heap 
   170  and setting up the primary Linux guest.  The details on how it sets up 
   171  the Linux guest is below.  
   172  
   173  
   174  Details of bootstrap initialization
   175  -----------------------------------
   176  
   177  The remainder of this document describes in detail the environment provided 
   178  to evmm by bootstrap.
   179  
   180  
   181  Memory layout when bootstrap main is called for single Linux guest
   182  -------------------------------------------
   183  
   184      #define TBOOT_START              0x0804000
   185      // start address of tboot MLE page table, beginning of tboot memory
   186      #define TBOOT_BASE_ADDR          0x0800000
   187  Tboot stack
   188      #define BSP_STACK_SIZE              4096
   189      #define AP_STACK_SIZE               1024
   190  Tboot calls main of bootstrap in 32 bit protected mode.  The memory layout
   191  at the time of this call is:
   192  
   193  IVT                                             <-- 0x00000000
   194  RDBA (Bios data memory)                         <-- 0x00000400
   195  Partition table                                 <-- 0x000007be -->7ff
   196  Command line buffer                             <-- 0x00002000 -->7ff
   197  GRUB Stage 0                                    <-- 0x00007c00 -->7dff
   198  GRUB Stage 1                                    <-- 0x00008000
   199  32 bit scratch space
   200  EMPTY
   201  Extended BIOS, vram, video ROM and ROM BIOS     <-- 0x000a0000
   202  Tboot header                                    <-- 0x00800000
   203  Tboot start (boot.S)                            <-- 0x00804000
   204    Tboot ends at ~                                   0x00972e88
   205  Bootstrap.bin
   206    This is currently loaded at 0x0804a317 on John's machine
   207  Evmm.bin
   208     This is loaded from 0x12da000 and 0x01333247 on John's machine.
   209  Linux image package 
   210    linux file (uncompressed real mode execution header)
   211    This is loaded between 0x0097300 and 0x012d5d20 on John's machine.
   212  The uncompressed initramfs
   213    This is loaded between 0x01334000 and 0x017d9200 on John's machine.
   214  
   215  mystart: 0x080480f8, end: 0x0804ca6c, main: 0x0804933f
   216  Linux start BZIMAGE_PROTECTED_START 0x100000
   217  
   218  
   219  Memory setup when vmm_main is called (John's machine)
   220  --------------------------------------------------------------
   221  
   222                                                    Hex        Decimal
   223  IVT                                    <-- 0x00000000
   224  RDBA (Bios data memory)                <-- 0x00000400           1024
   225  Partition table                        <-- 0x000007be    1982-->2047
   226  Command line buffer                    <-- 0x00002000   8192-->10239
   227  GRUB Stage 0                           <-- 0x00007c00  31744-->32225
   228  GRUB Stage 1                           <-- 0x00008000          32768
   229  Kernel command line                    <-- 0x00009000          36864
   230  Extended BIOS,vram, video and ROM BIOS <-- 0x000a0000         655360
   231  1 Meg                                  <---0x00100000        1048576
   232  4 Meg                                  <---0x00400000        4194304
   233  8 Meg                                  <---0x00800000             
   234  Tboot header                           <-- 0x00800000        8388608
   235  Tboot start (boot.S)                   <-- 0x00804000        8404992
   236  Tboot ends at ~                        <---0x00972e88        9907848
   237  Linux start (real)                     <--- 0x0097300         619264
   238  16 Meg                                 <---0x01000000       16777216
   239  Linux protected                        <---0x012d5d20       19750176
   240  Linux end                              <---0x01333247       20132423
   241  initram start                          <---0x01334000       20135936
   242  initram end                            <---0x017d9200       25006592
   243  32 Meg                                 <---0x02000000       33554432
   244  512 Meg                                <---0x20000000      536870912
   245  1 Gig                                  <---0x40000000     1073741824
   246  linux arguments                        <---0x6fefc000     1877983232
   247  Initial initial linux stack            <---0x6fefe000     1877991424
   248  Bootstrap start                        <---0x60000000     1610612736 
   249  Bootstrap end                          <-- 0x60006e60     1610640992
   250  Evmm heap                              <-- 0x6ff00000     1877999616
   251  Evmm.bin                               <---0x70000000     1879048192
   252  4 Gig                                  <--0x100000000     4294967296
   253  8 Gig                                  <--0x200000000     8589934592
   254  
   255  Bootstrap has relocated evmm to evmm_start_address and has also
   256  relocated the primary linux guest image and initram to linux_start_address
   257  and initram_start_address.  The linux header has been adjusted to contain
   258  the new intiram address and linux entry points.
   259  
   260  
   261  vmm_main call
   262  -------------
   263  
   264  The call to vmm_main is:
   265  
   266  void vmm_main(UINT32 local_apic_id, UINT64 startup_struct_u, 
   267                UINT64 application_params_struct_u, 
   268                UINT64 reserved UNUSED)
   269  On entry, startup_struct_u is cast to VMM_STARTUP_STRUCT* type and
   270  application_params_struct_u is (eventually) interpreted as a pointer
   271  to a structure of type VMM_INPUT_PARAMS_S.  This second structure
   272  is not used for the primary guest.
   273  
   274  These structures are used both in 32-bit and 64-bit modes, therefore:
   275  - Structure sizes are 64-bit aligned
   276  - All pointers are defined as 64-bit, and must be set so their higher 
   277    32 bits are 0 (< 4GB).  This ensures their usability in both 32-bit 
   278    and 64-bit modes.
   279  - All pointers are in a loader virtual memory space (if applicable).
   280  
   281  The Primary guest is the guest that owns the platform and platform was
   282  booted originally to run this guest. The secondary guest is a guest that 
   283  is used to perform some dedicated tasks on behalf of the primary guest.
   284  The primary guest gets all memory except for the evmm area now.  Later
   285  we should remove tboot and bootstrap too.
   286  
   287  Here is the structure hierarchy (---> denotes a pointer) of these
   288  input structures to vmm_main.
   289  
   290  VMM_STARTUP_STRUCT
   291      +---- VMM_MEMORY_LAYOUT     vmm_memory_layout[]
   292      +---> INT15_E820_MEMORY_MAP physical_memory_layout_E820
   293      +---> VMM_GUEST_STARTUP     primary_guest_startup_state
   294      |     +---> VMM_GUEST_CPU_STARTUP_STATE cpu_states_array[]
   295      |     |     +---- VMM_GP_REGISTERS             gp
   296      |     |     +---- VMM_XMM_REGISTERS            xmm
   297      |     |     +---- VMM_SEGMENTS                 seg
   298      |     |     +---- VMM_CONTROL_REGISTERS        control
   299      |     |     +---- VMM_MODEL_SPECIFIC_REGISTERS msr
   300      |     +---> VMM_GUEST_DEVICE            devices_array[]
   301      +---> VMM_GUEST_STARTUP     secondary_guests_startup_state_array[]
   302      |     +... as above
   303      +---- VMM_DEBUG_PARAMS      debug_params
   304          +---- VMM_DEBUG_PORT_PARAMS       port
   305  VMM_APPLICATION_PARAMS_STRUCT
   306  
   307  The structure definitions are:
   308  
   309  typedef struct _VMM_STARTUP_STRUCT {
   310      UINT16   size_of_this_struct;
   311      UINT16   version_of_this_struct;
   312  
   313      // number of processors/cores at install time.
   314      // used to verify correctness of the bootstrap process
   315      UINT16   number_of_processors_at_install_time;
   316  
   317      number of cores in the system.
   318  
   319      // number of processors/cores as was discovered by vmm loader
   320      // used to verify correctness of the bootstrap process
   321      UINT16   number_of_processors_at_boot_time;
   322  
   323      //number of cores on which evmm will be run.
   324  
   325      /* 64-bit aligned */
   326      // number of secondary Guests
   327      UINT16   number_of_secondary_guests;
   328  
   329      // size of stack for VMM per processor. In 4K pages.
   330      UINT16   size_of_vmm_stack;
   331  
   332      // values to be used by VMM to hide devices if VT-d is not accessable
   333      // **** THIS FEATURE IS CURRENTLY NOT SUPPORTED ****
   334      UINT16   unsupported_vendor_id;
   335      UINT16   unsupported_device_id;
   336  
   337      /* 64-bit aligned */
   338      // set of flags, that define policies for the VMM as a whole
   339      UINT32   flags;
   340  
   341      // magic number of the guest, that owns all platform devices
   342      // that were not assigned to any guest
   343      UINT32   default_device_owner;
   344  
   345  
   346      /* 64-bit aligned */
   347      // magic number of the guest, that serves as OSPM.
   348      // SMM code is executed in the context of this guest
   349      UINT32   acpi_owner;
   350  
   351  
   352      // magic number of the guest, that process platform NMIs.
   353      UINT32   nmi_owner;
   354  
   355      /* 64-bit aligned */
   356      // vmm memory layout
   357      VMM_MEMORY_LAYOUT           vmm_memory_layout[uvmm_images_count];
   358  
   359      // pointer to the int 15 E820 BIOS table
   360      //  INT15_E820_MEMORY_MAP*
   361      // Loader must convert the table into the E820 extended format
   362      // (each entry 24 bytes long). If BIOS-returned entry was 20 bytes long
   363      // the extended attributes should be set to 0x1.
   364      UINT64   physical_memory_layout_E820;
   365  
   366      /* 64-bit aligned */
   367      // pointer to the primary guest state
   368      //   VMM_GUEST_STARTUP*
   369      UINT64   primary_guest_startup_state;
   370  
   371      /* 64-bit aligned */
   372      // pointer to the array of secondary guest states
   373      // size of array is number_of_secondary_guests
   374      //   VMM_GUEST_STARTUP*
   375      UINT64   secondary_guests_startup_state_array;
   376  
   377      /* 64-bit aligned */
   378      // Debug parameters
   379      VMM_DEBUG_PARAMS            debug_params;
   380          
   381      /* 64-bit aligned */
   382      // Active cpu local apic ids
   383      UINT8    cpu_local_apic_ids[ALIGN_FORWARD(VMM_MAX_CPU_SUPPORTED, 8)];
   384  
   385  }PACKED VMM_STARTUP_STRUCT;
   386  
   387  
   388  typedef struct _VMM_APPLICATION_PARAMS_STRUCT {
   389          UINT32   size_of_this_struct; // overall, including all params
   390          UINT32   number_of_params;    // number of params that will follow
   391  
   392          // random generated id to avoid vmm shutdown by others
   393          UINT64   session_id;
   394          // page entry list for the additional heap
   395      UINT64       address_entry_list;
   396      UINT64       entry_number;
   397  #ifdef USE_ACPI
   398      UINT64       fadt_gpa;
   399  #ifdef ENABLE_VTD
   400      UINT64       dmar_gpa;
   401  #endif
   402  #endif //ifdef USE_ACPI
   403  } VMM_APPLICATION_PARAMS_STRUCT;
   404  
   405  
   406  typedef struct _VMM_GUEST_CPU_STARTUP_STATE
   407  {
   408      UINT16       size_of_this_struct;
   409      UINT16       version_of_this_struct;
   410      UINT32       reserved_1;
   411  
   412      /* 64-bit aligned */
   413  
   414      // there are additional registers in the CPU that are not passed here.
   415      // it is assumed that for the new guest the state of such registers is
   416      // the same, as it was at the VMM entry point.
   417  
   418      VMM_GP_REGISTERS                gp;
   419      VMM_XMM_REGISTERS               xmm;
   420      VMM_SEGMENTS                    seg;
   421      VMM_CONTROL_REGISTERS           control;
   422      VMM_MODEL_SPECIFIC_REGISTERS    msr;
   423  }PACKED VMM_GUEST_CPU_STARTUP_STATE;
   424  
   425  
   426  Setup of e820 tables by bootstrap
   427  ---------------------------------
   428  
   429  e820 is the facility by which the BIOS reports the memory map to the 
   430  operating system and boot loader.  The E820 table has range of address 
   431  and types. The table is part of vmm_memory_layout struct passed to 
   432  vmm_main by bootstrap.  bootstrap should copy and modify the e820 table 
   433  to protect it's memory region.
   434  
   435  
   436  Stack setup
   437  -----------
   438  
   439  Bootstrap.bin prepares a 64K stack for 64-bit evmm.  The 64K stack is 
   440  based at EVMM_HEAP_BASE by default.
   441  
   442  
   443  Heap setup
   444  ----------
   445  
   446  The inital heap for evmm is done by bootstrap.  This contains evvm's 
   447  initial stacks and page tables.  The final 64-bit heap initialization 
   448  for evmm is done in 64 bit evmm.  
   449  
   450  
   451  64-bit address translation
   452  --------------------------
   453  
   454  Bootstrap creates initial page tables to enter vmm_main in 64 
   455  bit protected mode.  This initial map is the identity map page table 
   456  structure.  64 bit evmm redoes them mostly.
   457  
   458  
   459  Multiprocessor rendezvous for evmm
   460  ----------------------------------
   461  
   462  Describe how BSP/AP rendezvous happens.  It looks like bootstrap needs
   463  to do it but it's unclear what address the AP's are supposed to wake up 
   464  at an what they expect to have happened.  Clarify the purpose, and what
   465  code the BSP and AP's should wake up at after.
   466  
   467  
   468  Linux Primary Guest initialization
   469  --------------------------
   470  
   471  Evmm sets up its Linux guest so that at startup, the Linux wakes up 
   472  in the call to code32_start in 32 bit protected mode just as it would 
   473  after TBOOT.  All information used to configure the Linux guest is
   474  passed in the parameters to vmm_main documented above.  
   475  
   476  The startup structure passed to evmm ensures that its general registers 
   477  and control registers are set so that linux has a small stack (at 
   478  linux_stack_address).  The argument to code32_start is in edi and points 
   479  to a copy of the original boot information.  Prior to the setup of the 
   480  startup structure, bootstrap relocates linux and initram as tboot would 
   481  have.
   482  
   483  Linux never accesses BIOS.  evmm can host Windows "out of the box."
   484  
   485  
   486  Bootstrap control flow
   487  ----------------------
   488  
   489  Tboot jumps to start32_evmm (which is Bootstrap's "main" program in 
   490  bootstrap_entry.c) in 32 bit protected mode.
   491  
   492  start32_evmm
   493       1. Initializes VGA printing by calling bootstrap_partial_reset().
   494          Print routines are in bootstrap_print and the init routine
   495          ensures continuous scrolling of existin TBOOT VGA output.
   496       2. Initializes bootstrap's start (load) address in bootstrap_start
   497          and its end address in bootstrap_end.  As noted above,
   498          bootstrap is loaded at 0x60000000.
   499       3. Checks the mbi passed by tboot.  The mbi should have 3
   500          module entries, of not, bootstrap halts. The 3 modules, 
   501          are: (1) the 64-bit evmm image, (2) the linux kernel image and,
   502          (3) theinitramfs image.  These image's have been loaded into 
   503          memory and start32_evmm collects their image start and end addresses
   504          as well as command line arguments from the mbi module entries.
   505          These are:
   506              For evmm: evmm_start, evmm_end and evmm_command_line.
   507              For linux: linux_start, linux_end and linux_command_line.
   508              For initram: initram_start and initram_end  
   509                   (initram has no command line).
   510       4. Determines the number of real processors and stores the number of
   511          Application Processors (total number of processors minus 1) in 
   512          evmm_num_of_aps.
   513       5. Sets the low_memory_page (at low_mem = 0x8000).  QUESTION: What for?
   514       6. Set ups evmm's initial  heap.  The heap is located at evmm_heap_base.
   515          It has size evmm_heap_size.  The heap is located where the evmm 
   516          executable will be relocated minus its size.  The load address of 
   517          the relocated evmm is at evmm_start_address and is typically 0x70000000.
   518       7. Relocates evmm to evmm_start_address and gets the entry point for
   519          evmm which is stored in vmm_main_entry_point.
   520       8. Sets up an IDT by calling SetupIDT.  QUESTION: Hasn't tboot done this?
   521       9. Sets up 64 bit mode by calling setup_64bit_paging().  This procedure
   522          is described below.
   523      10. Sets up an initial stack of 64KB (located in evmm's heap) by calling
   524          setup_evmm_stack().
   525      11. Relocates the linux image and initram as if it were the designated
   526          system software by calling prepare_linux_image_for_evmm(mbi).  This 
   527          procedure is described below.
   528      12. Copies the e820 table from mbi and reserves memory for bootstrap itself,
   529          the linux parameters, the initial linux stack and the initial evmm heap.
   530      13. Prepares the environment for evmm's primary guest and builds
   531          the data structures passed to vmm_main to describe the primary guest 
   532          (the startup structure and application structure) by calling 
   533          prepare_primary_guest_environment(mbi).
   534          prepare_primary_guest_environment must build the environment (control
   535          registers, stack, initial heap and argument list for the primary
   536          guest whose image was prepared by prepare_linux_image_for_evmm.
   537      14. Prepares the 64 bit stack for evmm entry, pushes the arguments to
   538          vmm_main, sets cr0 and cr3 to enable paging for 
   539          64 bit mode and does a retf to go into long mode.  Finally,
   540          in long mode, it pops the vmm_main arguments into the correct 
   541          registers (rsi,rdi,rcx,rdx)and jumps to vmm_main_entry_point.
   542  
   543  
   544  setup_64bit_paging
   545      mallocs page (in evmm_heap) for the segment descriptors (evmm_descriptor_table)
   546            and zeros page (mallocs and additional page for BSP stack)
   547      reads the existing (32 bit) gdtr
   548      copies the exiting gdtr table starting at .base into evmm_descriptor_table
   549      sets up the 64 bit code segment at the end of the 32 bit descriptor table
   550      sets gdtr_64.base to evmm_descriptor_table
   551      resets the gdtr table extent to reflect new entry
   552      writes the new table descriptor extent into evmm64_cs
   553  
   554      copies the 32 bit gdtr to init64.i64_gdtr
   555      sets up an identity map from 0 to TOTAL_MEM for 64 bit paging.
   556      copies the 32 bit cr3 to init64.i64_cr3 ans writes it again
   557      reads cr4 and resets it with PAE and PSE bits enabled
   558      writes p_init64_data->i64_efer into msr 0xC0000080
   559      writes evmm64_cs (end of code segment descriptor) into init64.i64_cs
   560      resets init64.i64_efer to 0
   561      saves init64.i64_cr3 into evmm64_cr3
   562  
   563  
   564  prepare_linux_image_for_evmm(mbi).
   565      expand_linux_image(mbi, linux_start, linux_end-linux_start,
   566                         initrd_start, initrd_end-initram_start,&linux_entry_address);
   567      prepare_primary_guest_args
   568  
   569  
   570  expand_linux_image
   571      linux_original_boot_parameters
   572      linux_real_mode_start, linux_real_mode_size
   573      linux_protected_mode_start, linux_protected_mode_size
   574      relocates linux
   575      sets linux_entry_address
   576  
   577  prepare_primary_guest_environment(mbi)
   578      linux_setup
   579      Fills startup and application structure elements.
   580  
   581  linux_setup
   582      sets guest's gdt table 
   583      sets up guests control registers MISSING
   584      allocates and sets up linux stack (is ss properly set?)
   585      sets up 32 bit descriptors for guest
   586      sets RIP so that guest wakes up in code32_start
   587      sets guests stack pointer (esp)
   588      set's guest entry argument pointer (esi)
   589  
   590  prepare_primary_guest_args(multiboot_info_t *mbi)
   591      allocates a one page stack for linux and sets 
   592  	linux_esp_register
   593      allocates boot parameter area at linux_boot_params
   594      copies command line arguments
   595      copies the original boot parameters to linux_boot_params.
   596      set_e820_copy_location(linux_e820_table, E820MAX);
   597      copy 820 pages for linux [copy_e820_map(mbi)]
   598      get_num_e820_ents();
   599      sets linux_esi_register= linux_boot_params, which
   600        is the argument to code32_start in linux.
   601  
   602  
   603  
   604  Notes 
   605  -----
   606  
   607  tboot:  min_hi_ram: 0x100000000, max_hi_ram: 0x33ee00000
   608  
   609  bootstrap control registers
   610  
   611  cr0: 0x00000033
   612  cr3: 0xb9f1f000
   613  cr4:   00004240
   614  gdtr: 0x00805000, 003f
   615  
   616  Final relocation
   617  code32_start: 0x61000000
   618  initrd:       0x1fb5a000, size: 4870656
   619  headers correct
   620  linux protected mode contents: 0x1186f6fc 40000002 0xb8fa0c75
   621  
   622  selector: 0x00000008
   623  (selector): 0x00000000 0x00a09e00
   624  stack base: 0x6ff07000 stack top: 0x6ff11000
   625  
   626  50000000 00000080
   627  00000000 00a09e00
   628  00000000 00a09200
   629  
   630           00000000 00a09e00
   631  
   632  00000000 00000000 00209A00 00000000
   633  
   634  
   635  TODO: Get interrupt code and vt-d code the evmm team offered.
   636  
   637  Compiling with Debug
   638  --------------------
   639  
   640  
   641  Check for serial com port 0x3f8, 0x3008
   642  debug_port=0x3f8
   643  look at readme instructions
   644  baud rate= 115200
   645  
   646  may need to bump heap
   647