Hello,
I am currently trying to virtualize my own OS using the Intel Virtualization Technology (VT-x). To provide a memory map for the guest OS I allocated a 128MB block of continuous memory (for testing purposes for now) and loaded the kernel elf into this very guest memory block at the according guest physical address (GPA). Now for the guest to percieve itself as the one having 128MB of memory available, the EPT is mapped as follows:
- 0x00000000 - 0x000b8000: The first part is mapped up until the VGA buffer.
- 0x000b8000 - 0x000b9000: This area is mapped to the host physical address 0x000b8000 to enable guest output on the screen.
- 0x000b9000 - 0x08000000: The rest of the guest physical memory block allocated in the host.
Now when I enter the guest OS the execution stops right at the point where the kernel elf is being validated (Click to enlarge):
The top half of the screen is the guest output, the lower half of the screen is the host output.
Turns out the kernel elf header is completely missing in the memory. But when I checked I found out that the kernel elf header is definitely in guest physical memory but not in guest linear memory:
Physical memory dump in the guest:
Linear memory dump in the guest:
The address selected at which to start the memory dump is the address where the kernel elf header is supposed to be. As you can see, in the physical memory dump the elf header is there, but in the linear memory dump there are only null bytes.
At this point where all screenshots were taken, the guest OS has not yet enabled paging. As such the linear and physical memory addresses should show the same content. But obvioisly that doesn't seem to be the case.
To answer one of potential questions incoming:
Maybe the mapping in the EPT is wrong.
Yep thats what I though first. But the EPT maps a portion of the host physical address to the guest physical address space. If paging in the guest is not enabled, each guest linear address is treated as a guest physical address (Original from Intel documentation: "If CR0.PG = 0, each linear address is treated as a guest-physical address").
So even though I loaded all neccessary elf files (one elf for the bootstrap code, one for the kernel itself), a modified copy of the multiboot info structure the kernel elf header is the only thing which seems to be missing in the linear address space. The kernel elf is located at a higher address (0x0039a000) and the bootstrap elf is located at a lower address (0x00100000). The kernel elf header is or should be located at 0x0019a000, but it is only available in the guest physical address space but not in the guest linear address space. Since execution happens in the linear address space, the elf is seemingly missing.
I hope someone can help me shed some light onto this issue which literally keeps me awake for days.