How to load and jump to "higher half" kernel?
Posted: Mon Dec 28, 2020 2:19 pm
Following an os tutorial I got stuck with user mode - specifically how to establish paging.
Reading the little os book it explains that in order to play nice - the kernel should be placed high enough in order to let user processes use the lower part of virtual address space (0x0000_0000 ..) - as well as even there the kernel should be a bit higher (0xC000_0000 to the full VMA mapping and an additional 0x0010_0000 on the start address of the kernel code - if I understand correctly it's a best practice so it's not messing with the boot code memory space).
This means - the kernel should be loaded to the physical 0x0010_0000 address (or at least around that, 4k aligned) and then after enabling paging the virtual 0xC010_0000 address would be resolved to the physical 0x0010_0000.
This makes sense to me and the osdev page has a section on explaining some implementation ideas.
However I'm still missing a some significant context. My project implements the boot logic so I don't use Grub. This means I start with 16 bit real mode and I have to load the kernel from disk to memory while I have disk interrupts in bios, meaning I can only move the basic kernel code to 16 bit space (so 0x10_0000) is not a chance at this stage. All the tutorials I've found was mentioning a single kernel that is re-mapped when paging is enabled and already placed above the 16bit address space.
Does this mean that if I have a kernel in 16bit space, I need a second kernel (or maybe just call it pre-kernel and main-kernel) at 0x10_0000? And would I need to load that second kernel from disk after switching to protected mode (with 32bit memory addressing)?
Reading the little os book it explains that in order to play nice - the kernel should be placed high enough in order to let user processes use the lower part of virtual address space (0x0000_0000 ..) - as well as even there the kernel should be a bit higher (0xC000_0000 to the full VMA mapping and an additional 0x0010_0000 on the start address of the kernel code - if I understand correctly it's a best practice so it's not messing with the boot code memory space).
This means - the kernel should be loaded to the physical 0x0010_0000 address (or at least around that, 4k aligned) and then after enabling paging the virtual 0xC010_0000 address would be resolved to the physical 0x0010_0000.
This makes sense to me and the osdev page has a section on explaining some implementation ideas.
However I'm still missing a some significant context. My project implements the boot logic so I don't use Grub. This means I start with 16 bit real mode and I have to load the kernel from disk to memory while I have disk interrupts in bios, meaning I can only move the basic kernel code to 16 bit space (so 0x10_0000) is not a chance at this stage. All the tutorials I've found was mentioning a single kernel that is re-mapped when paging is enabled and already placed above the 16bit address space.
Does this mean that if I have a kernel in 16bit space, I need a second kernel (or maybe just call it pre-kernel and main-kernel) at 0x10_0000? And would I need to load that second kernel from disk after switching to protected mode (with 32bit memory addressing)?