Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
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?
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.
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.