Moving kernel space to last giga (virtual adress)

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.
Post Reply
amirsadig

Moving kernel space to last giga (virtual adress)

Post 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)?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

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

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
amirsadig

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

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

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

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
srg

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

Post 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
amirsadig

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

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

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

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

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

Post 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.
Post Reply