Page 1 of 1

Moving kernel space to last giga (virtual adress)

Posted: Sat May 29, 2004 5:37 pm
by amirsadig
As I began to write users application, I would also use the standard user space ( first 3 giga byte of virtual ram). as used by gcc and ld.

my kernel work below the first giga byte?
have you some suggestion about moving kernel virtual adress to the third giga byte ( 0x40000000)?

Re:Moving kernel space to last giga (virtual adress)

Posted: Sat May 29, 2004 11:27 pm
by Brendan
Hi,
amirsadig wrote: As I began to write users application, I would also use the standard user space ( first 3 giga byte of virtual ram). as used by gcc and ld.

my kernel work below the first giga byte?
have you some suggestion about moving kernel virtual adress to the third giga byte ( 0x40000000)?
The third Gb would be 0xC0000000...

First step would be to compile or assemble the kernel for 0xC0000000. For GCC the option "-Ttext 0xC0000000" might work. This is the easy part.

The hard part will be initializing and enabling paging. If you currently initialize paging within the kernel while the kernel is identity mapped you're in trouble (linear addresses need to match physical addresses when paging is enabled). If this isn't the case making the change is easy - just change you boot code to suit. Otherwise I'd suggest adding another stage to your boot, so that instead of loading your kernel only you load some code that initializes paging too.

This new code can be loaded into physical memory and identity mapped. It would setup paging and then copy the kernel into it's correct location in linear memory and jump to it. One of the first things the kernel would do is remove the earlier code from the address space and memory.


Cheers,

Brendan

Re:Moving kernel space to last giga (virtual adress)

Posted: Sun May 30, 2004 3:31 am
by amirsadig
the addresses in the c or assembly are logical address. this mean the CPU use the segment describtor base adress to build the actual linear adress then it use Page directory.

what about to modify the Segment Describtor Base adress of the kernel to point to 0xC0000000. then CPU use this base adress to build the linear adress.
surely I must modify the page directory before. for example make a copy of all used page to correct page table. that mean before change the code segment the linear adress below 1 Giga and over 3 Giga point to kernel. then I can change the Segmet describtor baseadress.
this approach is simpler that changing code!.
correct me if I am wrong.

Re:Moving kernel space to last giga (virtual adress)

Posted: Sun May 30, 2004 8:07 am
by Brendan
Hi,
amirsadig wrote: the addresses in the c or assembly are logical address. this mean the CPU use the segment describtor base adress to build the actual linear adress then it use Page directory.

what about to modify the Segment Describtor Base adress of the kernel to point to 0xC0000000. then CPU use this base adress to build the linear adress.
surely I must modify the page directory before. for example make a copy of all used page to correct page table. that mean before change the code segment the linear adress below 1 Giga and over 3 Giga point to kernel. then I can change the Segmet describtor baseadress.
this approach is simpler that changing code!.
correct me if I am wrong.
That would also fix the problem. If you load your kernel at 0x10000 (for e.g.) in physical memory you can set the segment bases to 0x4000000, so that cs:0xC0010000 wraps around to become physical address 0x10000. After paging is enabled and the segment bases are set to 0x00000000, cs:0xC0010000 will become linear address 0xC0010000. You will still have to be careful with your addresses though - the BIOS would start at 0xC00F0000, RAM would start at 0xC0000000, video display memory might be at 0xC00B8000, etc.

You will also need to be careful how much space your kernel uses - if your kernel has 256 Kb of CODE & DATA followed by 512 Kb of BSS you wouldn't be able to use the last part of the BSS until paging is set up, as it would overwrite video display memory.

Cheers,

Brendan

Re:Moving kernel space to last giga (virtual adress)

Posted: Mon May 31, 2004 1:44 am
by srg
The only snag with that segment base trick is that it will only work on x86. Not even x86-64. But if your only planning on writing for x86 then this won't matter. Also, if this is part of your bootloader then that is very arch dependant anyway, so again won't matter. But still, I thought I should point it out.

srg

Re:Moving kernel space to last giga (virtual adress)

Posted: Mon May 31, 2004 11:08 am
by amirsadig
If you load your kernel at 0x10000 (for e.g.) in physical memory you can set the segment bases to 0x4000000, so that cs:0xC0010000 wraps around to become physical address 0x10000.
could you describe in more details above. how -when I set seg bases to 0x4000000- will let cs+0x10000 equal 0xC0010000

Re:Moving kernel space to last giga (virtual adress)

Posted: Mon May 31, 2004 12:57 pm
by Brendan
Hi,
amirsadig wrote: could you describe in more details above. how -when I set seg bases to 0x4000000- will let cs+0x10000 equal 0xC0010000
That's not quite what I said :) - "you can set the segment bases to 0x4000000, so that cs:0xC0010000 wraps around to become physical address 0x10000."

Basically:
cs.base + 0xC0010000
= 0x4000000 + 0xC0010000
= 0x100010000

BUT because 0x100010000 is too big for 32 bits the CPU truncates it, which leaves 0x00010000.

While I haven't tried it on a 64 bit CPU it should still work (unless you enable 64 bit "long mode" in which case nothing in your 32 bit kernel will work anyway).


Cheers,

Brendan

Re:Moving kernel space to last giga (virtual adress)

Posted: Mon May 31, 2004 4:17 pm
by Candy
srg wrote: The only snag with that segment base trick is that it will only work on x86. Not even x86-64.
yes it does work on x86-64 in 32-bit mode. The point of 32-bit mode is that it is identical to normal 32-bit mode.