Page 1 of 1

Fiddling the Kernel Base address

Posted: Thu Feb 19, 2004 4:36 pm
by srg
Hi

I'm reading through Tim's excellent tutorial on Memory management: Part 1 Physical and there is one paragraph that I'm a bit confused about.

In:
But putting the memory manager in the boot loader isn?t practical. We need to have the processor seeing address 0xC0000000 as 0x100000 without enabling paging. Later, we want to enable paging and avoid relocating the kernel. We can do this by fiddling the base addresses of the kernel?s code and data. Remember that the processor forms physical addresses by adding the virtual address (e.g. 0xC0000000) to the segment?s base address and sending that to the address bus (or, if paging is enabled, to the MMU). So as long as our address space is continuous (that is, there?s no gaps or jumps) we can get the processor to associate any virtual address with any physical address. In our example before, with the kernel located at 0xC0000000 but loaded at 0x100000, we need a segment base address which turns 0xC0000000 into 0x1000000; that is, 0xC0000000 + base = 0x1000000. This is easy: our segment base address needs to be 0x41000000. When we refer to a global variable at address 0xC0001000, the CPU adds 0x41000000 and gets the address 0x1001000. This happens to be where the boot loader loaded part of our kernel, and everyone?s happy. If we later enable paging, and map address 0xC0000000 to 0x1000000 (and use a segment with base address zero), the same addresses will continue to be used.
If the Kernel has been loaded into address 0x100000, then surely the segment base address should turn 0xC0000000 into 0x100000 and not 0x1000000? If not, then why 0x1000000 as this is 16MB not 1MB?

This is a real bain teaser :)

Thank you
srg

Re:Fiddling the Kernel Base address

Posted: Thu Feb 19, 2004 4:46 pm
by Tim
Argh! One typo and it keeps coming back to bite you.

There is one too many zeroes there. You're right, it should be 1MB, not 16MB.

Re:Fiddling the Kernel Base address

Posted: Thu Feb 19, 2004 5:06 pm
by srg
Few I can calm down now hehe

I'm guessing you get a lot of queries about that, then update it then! hehe ;D

Anyway, please correct me if I'm wrong but is the maths in this relying on a wrap arround to get 0xC0001000 + 0x41000000 = 0x1001000. If so, what happends on a AMD64 system, would this all have been done in pmode then you switch to long mode, or doesn't it matter? It just sounds like another DOS and A20 Gate type problem if you get what I mean.

Thanks
srg

Re:Fiddling the Kernel Base address

Posted: Thu Feb 19, 2004 7:47 pm
by TB
Hello Tim,
I like your "GDT trick" and I would have used it, but for some reason, VMWare doesn't like it.

Re:Fiddling the Kernel Base address

Posted: Fri Feb 20, 2004 2:01 am
by Candy
srg wrote: Anyway, please correct me if I'm wrong but is the maths in this relying on a wrap arround to get 0xC0001000 + 0x41000000 = 0x1001000. If so, what happends on a AMD64 system, would this all have been done in pmode then you switch to long mode, or doesn't it matter? It just sounds like another DOS and A20 Gate type problem if you get what I mean.
As for the problems being similar, pointed that out to Tim some time ago too. But, there's one catch here. The A20 gate had to be enabled because you were using some system that was still being used, but in an extended system. Segmentation is an artifact of IA32 architecture, and operates between virtual and linear addresses. You should learn by that that it converts from a 32-bit address space to a 32-bit address space. It is NOT extended to 36-bits by the PAE extension.

As for AMD64, they don't even support segmentation in long mode. You cannot use a segmentation trick in long mode if there is no segmentation. Period.