/* * GeekOS C code entry point * Copyright (c) 2001,2003,2004 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth * Copyright (c) 2004, Iulian Neamtiu * $Revision: 1.1.1.1 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* static inline unsigned int cpuid_ecx(unsigned int op) { unsigned int eax, ecx; __asm__("cpuid" : "=a" (eax), "=c" (ecx) : "0" (op) : "bx", "dx" ); return ecx; } */ extern void Get_MSR(ulong_t msr, unsigned int *val1, unsigned int *val2); extern void Set_MSR(ulong_t msr, ulong_t val1, ulong_t val2); extern uint_t Get_EIP(); extern uint_t Get_ESP(); extern uint_t Get_EBP(); int foo=42; #define SPEAKER_PORT 0x61 void Buzz(unsigned delay, unsigned num) { volatile int x; int i,j; unsigned char init; init=In_Byte(SPEAKER_PORT); for (i=0;ientry_ip, vm->exit_eip, vm->guest_esp); SerialPrintLevel(100,"VM_Thread: You should see nothing further from me\n"); ret = VMLaunch(vm); SerialPrintLevel(100,"VM_Thread: uh oh..."); switch (ret) { case VMX_SUCCESS: SerialPrintLevel(100,"Normal VMExit Occurred\n"); break; case VMX_FAIL_INVALID: SerialPrintLevel(100,"Possibile invalid VMCS (%.8x)\n", ret); break; case VMX_FAIL_VALID: SerialPrintLevel(100,"Valid VMCS, errorcode recorded in VMCS\n"); break; case VMM_ERROR: SerialPrintLevel(100,"VMM Error\n"); break; default: SerialPrintLevel(100,"VMLaunch returned unknown error (%.8x)\n", ret); break; } SerialPrintLevel(100,"VM_Thread: Spinning\n"); while (1) {} } int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte) { uint_t address; for (address=start;address"); SerialPrintLevel(100,"Initializing VMX\n"); PrintBoth("Initializing VMX\n"); VmxOnRegion * vmxRegion = InitVMX(); if (vmxRegion==NULL) { PrintBoth("VMX Cannot be turned on. Halted.\n"); while (1) {} } SerialPrintLevel(1000,"Launching Noisemaker and keyboard listener threads\n"); key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false); // Enable this to run the simple buzzer VM #if 0 // Put the entry around 0x10000, where the geekos kernel used to live vm.entry_ip=(uint_t)0x10000; vm.exit_eip=0; // Put the stack as the last thing in the VM partition vm.guest_esp=(uint_t)START_OF_VM+VM_SIZE-1; memcpy(vm.entry_ip,MYBUZZVM_START,MYBUZZVM_LEN); SerialPrintLevel(1000,"VM-Launching MyBuzzVM after copy to 0x10000\n"); vm_thread = Start_Kernel_Thread(VM_Thread, (ulong_t)&vm,PRIORITY_NORMAL,false); #else #if 0 // write the hello VM down to where we would usually put // vmxassist, and see if it can talk to us vm.entry_ip=(uint_t)START_OF_VM+0xd000000; vm.exit_eip=0; // Put the stack as the last thing in the VM partition vm.guest_esp=(uint_t)START_OF_VM+VM_SIZE-1; memcpy((void*)(vm.entry_ip),Hello,200); // 200 should be plenty SerialPrintLevel(1000,"VM-Launching HelloVM after copy to 0xd000000\n"); vm_thread = Start_Kernel_Thread(VM_Thread, (ulong_t)&vm,PRIORITY_NORMAL,false); #else // Try to launch a real VM // First we will copy down VMXAssist, then we'll launch that // and see if it can handle the system bios // We now map pages of physical memory into where we are going // to slap the vmxassist, bios, and vgabios code pte_t template_pte; template_pte.present=1; template_pte.flags=VM_WRITE|VM_READ|VM_USER|VM_EXEC; template_pte.accessed=0; template_pte.dirty=0; template_pte.pteAttribute=0; template_pte.globalPage=0; template_pte.kernelInfo=0; SerialPrintLevel(1000,"Allocating Pages for VMXASSIST, BIOS, and VGA BIOS\n"); #define SEGLEN (1024*64) AllocateAndMapPagesForRange(START_OF_VM+0xd0000, SEGLEN, template_pte); AllocateAndMapPagesForRange(START_OF_VM+0xf0000, SEGLEN, template_pte); AllocateAndMapPagesForRange(START_OF_VM+0xc0000, SEGLEN, template_pte); // Now we should be copying into actual memory SerialPrintLevel(1000,"Copying VMXASSIST code from %x to %x (%d bytes)\n", VMXASSIST_START, START_OF_VM+0xd0000,VMXASSIST_LENGTH); memcpy((char*)(START_OF_VM+0xd0000),(char*)VMXASSIST_START,VMXASSIST_LENGTH); SerialPrintLevel(1000,"Copying BIOS (2nd copy) code from %x to %x (%d bytes)\n", BIOS2_START, START_OF_VM+0xf0000,BIOS_LENGTH); memcpy((char*)(START_OF_VM+0xf0000),(char*)BIOS2_START,BIOS_LENGTH); SerialPrintLevel(1000,"Copying VGA BIOS code from %x to %x (%d bytes)\n", VGA_BIOS_START, START_OF_VM+0xc0000,VGA_BIOS_LENGTH); memcpy((char *)(START_OF_VM+0xc0000),(char*)VGA_BIOS_START,VGA_BIOS_LENGTH); // jump into vmxassist vm.entry_ip=(uint_t)0xd0000; vm.exit_eip=0; // Put the stack at 512K vm.guest_esp=(uint_t)START_OF_VM+1024*512; SerialPrintLevel(1000,"VM-Launching to vmxassist for boot\n"); vm_thread = Start_Kernel_Thread(VM_Thread, (ulong_t)&vm,PRIORITY_NORMAL,false); SerialPrintLevel(1000,"Next: setup GDT\n"); #endif #endif TODO("Write a Virtual Machine Monitor"); /* Now this thread is done. */ Exit(0); }