implementing paging

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.
kiwipresse
Member
Member
Posts: 25
Joined: Sun Nov 04, 2007 7:41 am

implementing paging

Post by kiwipresse »

Hi,

I'm trying to implement paging but I'm confused:

is it necessary to set up the GDT (and IDT, get interrupts working etc.) before I want to use paging? I'm wonder whether I just can enable paging then jump to the higher half and set up all the necessary things. I think that this is a better solution since I can access everything with the virtual adress instead of the physical address and I don't need identity paging. Did I miss something? Is is considered that this is dirty?

I furthermore don't want to do things which GRUB already did for me...
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: implementing paging

Post by CodeCat »

The paging bit in cr0 has no effect until you enable the protected mode bit as well, as far as I know. But I suppose theoretically you can do both at the same time, as long as both the page tables and GDT are set up when you set the protected mode bit. It would just be rather complicated, but it would probably work.

However, the multiboot specification (used by GRUB) does not guarantee that the GDT has been set up at all, so you should not count on it if you want your OS to be multiboot compatible. All GRUB guarantees is that the current setup of the segment registers is a valid flat-mode segment, but even reloading them with the same values might cause trouble. So to avoid any surprises it's best to just set up your own GDT anyway.
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: implementing paging

Post by hailstorm »

One short answer: yes, it is necessary. As soon as you want to do the jump to the higher half, the GDT must be initialised with at least the code segment you want to jump to. The IDT however, is not so important at this point (that's how I think about it)...
But I believe you have to divide your kernel into two parts. The first part of your kernel has to initialise the GDT and pagetables, before you jump to the higher (2nd) half. Therefore, the first half of your kernel operates in another address space (since the paging system hasn't been setup). Take that in mind when you're about to link your kernel.

Or do I make big mistake by saying this? Haven't been here for a while lately... :mrgreen:
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: implementing paging

Post by Combuster »

Well, you don't need to have a GDT to enter the higher half - only paging (you're not required to reload CS or any other segment register for that). However having a GDT and IDT can save you a lifetime on the next typo so setting them up is a good idea anyway (the best place would be most likely shortly after jumping to the higherhalf)

The GDT was however needed somewhere before to load the segment registers with the enabling of protected mode, so with your own bootloader you might still have it.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: implementing paging

Post by CodeCat »

However, you can't have paging without protected mode, and protected mode without at least some form of GDT is impossible. But if the bootloader (GRUB) boots you in protected mode, then you can set up paging without having to worry about the GDT (there is still a GDT, but it's one that the bootloader set up for you), and you can set up the GDT once you're ready to jump to the higher half. Jumping to the higher half requires a far (absolute) jump, which requires having a valid code segment to jump to, which in turn requires a valid GDT entry for that segment.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: implementing paging

Post by Combuster »

Higherhalf does *not* require a far jump. Even Higher_Half_bare_bones doesn't use one. Care to explain why you claim that you have to?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: implementing paging

Post by CodeCat »

Well, it wouldn't work for me otherwise, but I guess I did something wrong then. I figured the jump had to be absolute and the only way to do that in GAS that I could think of was a far jump.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: implementing paging

Post by Combuster »

try jumping to a register next time, but not knowing how a processor can do an absolute jump doesn't qualify you for claiming that a far jump is the only possible option. And especially after someone else claims the opposite you shouldn't just repeat that without sensible arguments.

Just try to be careful about spreading false information next time, it doesn't help anybody who is looking for the answer and only brings you bad karma, ok?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: implementing paging

Post by CodeCat »

How can I prevent spreading false information if I'm not aware the information is false to begin with? :P
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Re: implementing paging

Post by Brynet-Inc »

CodeCat wrote:How can I prevent spreading false information if I'm not aware the information is false to begin with? :P
Uh, by consulting a higher authority.. no not that myth, just manuals. ;)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: implementing paging

Post by Combuster »

You claimed the following:
- I can't do it
- Therefore everybody else can't do it as well.
And I think we can agree that that usually leads to the wrong conclusions. (And you could have known that prior to posting even without additional information)

The more appropriate rule is "If I can't do it, someone else probably can unless I can prove it is impossible."
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
kiwipresse
Member
Member
Posts: 25
Joined: Sun Nov 04, 2007 7:41 am

Re: implementing paging

Post by kiwipresse »

First things first: thanks for your help!

I looked at other kernel code and discovered that some projects use start addresses below 0xC0000000 in their linker script but still map their kernel (or it seems to me) to the higher half. And nm told me that they are really not in the 0xC0000000 area. My solution was to put the files which are called from GRUB - or from files which are loaded from GRUB - in their own sections and to put the rest of the kernel in the higher half. Then I enabled paging and jumped to the higher half. Everything works.

But now I wonder whether they are using a better solution? How do they solve the address difference? Relocation? PIC? What did I miss and where can I get further information? :wink:
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: implementing paging

Post by pcmattman »

IIRC, they use a GDT trick that makes the addresses appear to be at 0xC0000000 rather than the actual 0x100000.

I personally think using paging and an "init" section in a linker script is much more efficient and (at least to me) makes more sense.
kiwipresse
Member
Member
Posts: 25
Joined: Sun Nov 04, 2007 7:41 am

Re: implementing paging

Post by kiwipresse »

Is it really much more efficient? I mean if I can forget which function lives in the higher half I would probably accept little performance penalty...

But I still don't understand the GDT trick... how can the following formula be true?
0xC0100000 + 0x40000000 = 0x100000
And I also founded projects which use the base address 0xE0000000 and 0x1FFFF as limit to achieve the same?!

Can somebody help me and perhaps refer to in-depth information about this? Thanks.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: implementing paging

Post by Combuster »

You're thinking in mathematical terms - the processor is limited to 32 bits, so if you do something that creates a result over 32 bits then it will lose part of the result. That's called an overflow.

And if you didn't find it yet: Higher Half With GDT
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply