This is how I tackled this problem:
My kernel image is loaded by GRUB at (physical) address 0x01000000 (16MB, just above the ISA DMA region). This image basically consists of two parts:
- An "early init" section. This section contains code that is executed to prepare to jump to the higher half kernel. I also reserve some space in this section for a stack and a heap used during this preparation. All code in this section is linked at (virtual) address 0x01000000.
- The rest of the image contains code and data that is part of the higher half kernel. All code in this part is linked at (virtual) address 0xc0000000 (3GB).
Since the code in the early init section is linked at the same address as where it is loaded, GRUB can jump into this code without any problems. This early init code performs the following steps:
- Relocate the MBI structure that GRUB passes to the kernel. The heap inside the early init section is used for this.
- Identity map all pages starting at physical address 0x0 up to the physical address of the last page used by the early init section. Identity mapping means that the virtual addresses are the same as the physical addresses. This makes sure that the code in the early init section can still be executed after paging is enabled.
- Map the higher half kernel at virtual address 0xc0000000.
- Enable paging.
- Jump into the higher half kernel.
At this point the rest of the initialization is done from higher half code. This includes setting up the GDT, IDT, memory management,... Note that the MBI is relocated to a well-known location so you shouldn't have to worry about overwriting it with your own data structures.
A small word about the physical memory manager: What I do is calculate the amount of pages needed for my data structures, allocate these structures starting at the first page after the kernel image and start dealing pages starting after these data structures.
I hope this explanation is clear. If it's not, please let me know. I could also provide you with a copy of my kernel if you'd like that.