Higher-Half Startup

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
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Higher-Half Startup

Post by Rusky »

So, my kernel has some normal sections (e.g. .text, .data) and an .init section. The .text section and friends are linked at 0xF0000000 but loaded at 0x100000, while the .init section is both linked and loaded at the same address low in physical memory. Thus, bootstrapping the kernel involves enabling paging and setting up the correct mapping for the kernel proper.

This involves some dependency juggling- the code to construct the page tables needs to be called before paging is enabled, which means that 1) the page directory, which goes in the kernel proper, is not at its final address and 2) I potentially also need access to the kernel heap, which is also not at its final address.

L4 (the Pistachio reference implementation) solves this by using a temporary page directory with PSE enabled- the temp directory can go in the .init section and there's no need to allocate page tables. This kind of bothers me and I'd like to do this without this kind of throwaway table.

I could initialize the page directory through a pointer to &kernel_directory - kernel_offset and use a temporary heap allocator that just grabs chunks from the beginning using the same pointer technique, but that doesn't sound much better. So, my question is this: has anyone done this kind of setup before in a cleaner way than Pistachio or I have?
TylerH
Member
Member
Posts: 285
Joined: Tue Apr 13, 2010 8:00 pm
Contact:

Re: Higher-Half Startup

Post by TylerH »

A common method is to take advantage of segmentation offsets. IMO, it sounds like the easiest way.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Higher-Half Startup

Post by gerryg400 »

It depends a little on how you intend to load your kernel. From a boot sector ? Your own loader ? Or Grub ?
If a trainstation is where trains stop, what is a workstation ?
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Re: Higher-Half Startup

Post by Rusky »

Ah, yeah. I'm booting from GRUB. I suppose if I wrote my own bootloader or a third-stage bootloader that set up the processor state more to my liking that could work, but the segmentation idea sounds a little cleaner- a temporary GDT is a lot simpler than a temporary page directory.

At the risk of sounding obsessive, I don't quite like the GDT trick either. Is there a better way to set up a mapping like that with the GDT? Also, out of curiosity, does anyone know how any mainstream kernels do it?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Higher-Half Startup

Post by thepowersgang »

Afaik, most kernels have the higher half mapping set up using paging and link the entire kernel to the high address.

There is a small assembly stub that is linked to low memory that handles the initial setup (so, enables paging)

Personally, I see the GDT trick as a bit of an unnecessary hack, but others see it as cleaner.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Re: Higher-Half Startup

Post by Rusky »

Indeed. I am using a small stub to map the kernel, but just setting up paging appears to require less-clean hacks, because neither the page directory nor the kernel heap are at the address in the symbol table until paging is enabled. I could do some pointer fiddling, but that requires a temporary heap allocator to use the physical address of the heap.

It seems I need a temporary something- a page directory, a GDT or a heap allocator. The first two require temporary tables and the second requires extra messing with pointers, so at this point it's just a question of which one is more understandable, I guess.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Higher-Half Startup

Post by thepowersgang »

it shouldn't be that difficult, just make a compile-time page directory and table with physical addresses, and take that address using "mov eax, gPageDir - KERNEL_BASE"

I have this code in a single ASM file that handles switching to higher half all on it's own, meaning I can assume that I'm already there everywhere else.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Higher-Half Startup

Post by Solar »

Just throwing this in without really knowing whether it's appropriate: Higher Half bare bones.

(Consider this a drive-by linking. No idea whether it solves OP's problem.)
Every good solution is obvious once you've found it.
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Re: Higher-Half Startup

Post by Rusky »

The problem with making a compile-time page directory with 4k pages is that technically the number of tables isn't set, so I'm not sure how I would go about building it without a lot of tedium and the risk of going over one page and having it not mapped in the future.

It also looks better to map things in a while loop. A language with a better macro system could solve this, but the only one I even know of with that kind of power is Lisp, which isn't exactly optimal for this kind of project. :/

The higher-half barebones does things the same as Pistachio but is a lot simpler, so good link. :)
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Higher-Half Startup

Post by Owen »

Rusky wrote:The problem with making a compile-time page directory with 4k pages is that technically the number of tables isn't set, so I'm not sure how I would go about building it without a lot of tedium and the risk of going over one page and having it not mapped in the future.

It also looks better to map things in a while loop. A language with a better macro system could solve this, but the only one I even know of with that kind of power is Lisp, which isn't exactly optimal for this kind of project. :/

The higher-half barebones does things the same as Pistachio but is a lot simpler, so good link. :)
Turn on PSE. Map your kernel with a 4 or 2MB page built into the binary. Use those paging structures for the kernel/task 0 as appropriate. Job done.

(The only time I would do things differently is if i wanted a position independent kernel)
User avatar
Rusky
Member
Member
Posts: 792
Joined: Wed Jan 06, 2010 7:07 pm

Re: Higher-Half Startup

Post by Rusky »

4Mib pages can be used along with 4Kib ones, duh. Thanks for sort-of pointing that out, Owen. That gets rid of the heap requirement, but the kernel could still go above 4Mib... initializing the page directory at its physical address would still work, it would just require a bit of pointer trickery- a lot simpler than a completely separate heap allocator.

Thanks all for putting up with my slowness. :P
Post Reply