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)?
Moving kernel space to last giga (virtual adress)
Re:Moving kernel space to last giga (virtual adress)
Hi,
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
The third Gb would be 0xC0000000...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)?
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.
Re:Moving kernel space to last giga (virtual adress)
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.
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)
Hi,
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
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.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.
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.
Re:Moving kernel space to last giga (virtual adress)
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
srg
Re:Moving kernel space to last giga (virtual adress)
could you describe in more details above. how -when I set seg bases to 0x4000000- will let cs+0x10000 equal 0xC0010000If 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.
Re:Moving kernel space to last giga (virtual adress)
Hi,
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
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."amirsadig wrote: could you describe in more details above. how -when I set seg bases to 0x4000000- will let cs+0x10000 equal 0xC0010000
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.
Re:Moving kernel space to last giga (virtual adress)
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.srg wrote: The only snag with that segment base trick is that it will only work on x86. Not even x86-64.