PMode in Boot Loader

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.
B.E

PMode in Boot Loader

Post by B.E »

I have a bootloader. It reads a multiple sector file from the disk using the FAT12. after the bootloader I still have another 130 bytes free. Is it posible to switch to PMode in 130 bytes.

The GDT would use up 32(4 descriptors) bytes, IDT would only use up 8 (1 descriptor, copy the 1 descriptor 256 times). This would leave me with 90 bytes. would the PMode code fit into 90 bytes. Or is it better to go into protected mode in my kernal code.
Curufir

Re:PMode in Boot Loader

Post by Curufir »

B.E wrote: The GDT would use up 32(4 descriptors) bytes
Nope, you only need NULL and ring 0 code/data descriptors. If you aren't fussy you can even use the 8 bytes of the NULL descriptor for useful data.
IDT would only use up 8 (1 descriptor, copy the 1 descriptor 256 times).
IDT isn't required for the switch to PMode, just be sure to mask IRQs and turn off interrupts before the switch.
Or is it better to go into protected mode in my kernal code.
As usual with OS dev that's a question only you can really answer (You certainly have enough room left). Personally I do it in the second stage of my loader so that I have space to give meaningful error messages in the first stage.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:PMode in Boot Loader

Post by Brendan »

Hi,
B.E wrote: I have a bootloader. It reads a multiple sector file from the disk using the FAT12. after the bootloader I still have another 130 bytes free. Is it posible to switch to PMode in 130 bytes.

The GDT would use up 32(4 descriptors) bytes, IDT would only use up 8 (1 descriptor, copy the 1 descriptor 256 times). This would leave me with 90 bytes. would the PMode code fit into 90 bytes. Or is it better to go into protected mode in my kernal code.
You don't need a valid IDT to switch to protected mode (just disable interrupts). For the GDT you'd need 16 bytes (code & data/stack segments) and another 6 bytes for the "lgdt" structure. The code to enable protected mode would take around 20 bytes, so you could squeeze it all into less than 50 bytes.

Even though you've got plenty of space for this, it still might not be a good idea. It really depends on how your OS will boot when it's finished (will your OS always require a FAT file system to boot from), and how your OS will handle interrupts, paging and video.

The problem with simply disabling interrupts is that the CPU can "cache" a few IRQ's if they are received at the wrong time (ie. just after you've disabled them). For example:

Code: Select all

   disable interrupts
   <--interrupt received here
   enable protected mode
   initialize the PICs so it generates different interrupts
   enable interrupts
   <--old interrupt/IRQ received here (rather than the new/remapped interrupt)
To avoid this Linux has a hack to flush any stale interrupts within it's initialization code. My OS prevents these stale interrupts from occuring in the first place, using something like:

Code: Select all

   mask all IRQs in the PICs
   wait for any remaining IRQ's to be handled
   disable interrupts
   enable protected mode, etc..
This prevents the CPU's "interrupt cache" from carrying stale interrupts into the protected mode environment.

For paging, you may want to keep the lowest 16 MB of RAM as free as possible for ISA DMA and bus mastering devices, or you might want to map the kernel at 0xC0000000 (for e.g.). In this case it's easier to have a second stage, which would initialize protected mode and paging (and possibly handle the PICs, IO APICs, memory detection, etc.). This makes it easier to write the kernel as all of the kernel's code would be 32 bit without any strange addressing fix-ups.

For video, some OS's set a default video mode while in real mode. This can involve asking the VBE/BIOS for a list of valid video modes and checking for a valid/useable one (for e.g. 800*600 with 256 colours and LFB). My OS has a full graphical menu that allows the user to select a default video mode during boot.

It's also going to depend on what sort of kernel/OS you are planning. For a micro-kernel OS you need a way to get device drivers into memory before you can load things from disk. The only sane way of doing this is to load some device drivers into memory before you enter protected mode, so that they can be accessed after. For monolithic kernels this isn't as much of a problem.

If none of these issues worry you, then you could enter protected mode within your boot sector. I take the opposite approach, and use a 4 stage boot where the kernel doesn't contain any initialization code.


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
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:PMode in Boot Loader

Post by Colonel Kernel »

Brendan wrote:The problem with simply disabling interrupts is that the CPU can "cache" a few IRQ's if they are received at the wrong time (ie. just after you've disabled them). For example:

Code: Select all

   disable interrupts
   <--interrupt received here
   enable protected mode
   initialize the PICs so it generates different interrupts
   enable interrupts
   <--old interrupt/IRQ received here (rather than the new/remapped interrupt)
To avoid this Linux has a hack to flush any stale interrupts within it's initialization code. My OS prevents these stale interrupts from occuring in the first place, using something like:

Code: Select all

   mask all IRQs in the PICs
   wait for any remaining IRQ's to be handled
   disable interrupts
   enable protected mode, etc..
This prevents the CPU's "interrupt cache" from carrying stale interrupts into the protected mode environment.
Hmmm... This problem is news to me. Does anyone know if GRUB does anything to prevent this?

Brendan, I think the answer is probably "no", but do you have a way of reliably reproducing this problem?
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
Dex4u

Re:PMode in Boot Loader

Post by Dex4u »

Here's going to pmode and printing a string, assemble it and see what size it is.
http://www.mega-tokyo.com/forum/index.p ... eadid=7486
B.E

Re:PMode in Boot Loader

Post by B.E »

Thankyou for that. I been thinking about it and want to know what I shuld do with the free bytes.

If I use a second stage for my loader what else can I do with the 130 bytes I still have in the boot sector and if I don't use a second stage I still have around about 80 bytes left. What can I do with the free bytes. Ok if there were only 10 bytes free after going into protected mode, I might use a second stage but 80 bytes. How many bytes would it take to enable pageing.

Why do most of you guys put your kernal at 0xC0000000?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:PMode in Boot Loader

Post by Brendan »

Hi,
Colonel Kernel wrote:Hmmm... This problem is news to me. Does anyone know if GRUB does anything to prevent this?

Brendan, I think the answer is probably "no", but do you have a way of reliably reproducing this problem?
It seems this is a local APIC problem, rather than a legacy PIC problem (and shouldn't happen for the PIC chips).


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.
Argh

Re:PMode in Boot Loader

Post by Argh »

B.E wrote: I still have around about 80 bytes left. What can I do with the free bytes.
List of things a bootloader could do: http://my.execpc.com/~geezer/osd/boot/steps.txt
Poseidon

Re:PMode in Boot Loader

Post by Poseidon »

B.E wrote: Why do most of you guys put your kernal at 0xC0000000?
A task has its own base address, for example 0x1000. When your kernel has multitasking and it would be somewhere low in the memory, a task can only be 0x99000 bytes big (you can do something that it splits the tasks up so that it continues after the kernel).
I'm not sure I'm complete in my story, I read somewhere that the kernel doesn't have to be in the address space of the task, but that your OS will be slower than because there are more context switches. Somebody, correct me when I'm wrong ;D.
Argh

Re:PMode in Boot Loader

Post by Argh »

Poseidon wrote:
B.E wrote: Why do most of you guys put your kernal at 0xC0000000?
... When your kernel has multitasking and it would be somewhere low in the memory, a task can only be 0x99000 bytes big (you can do something that it splits the tasks up so that it continues after the kernel).
I'm confused by your explanation.

I figured that 0xC0000000 was basically just an arbitrarily high location (making user program addresses low) that gives you a gig of virtual memory to work with for your kernel, while leaving a good 3 gig for user programs. The boundary could just as well be at 0x80000000.

If the question is why split the address space, try the following:
http://www.mega-tokyo.com/forum/index.p ... eadid=7438
mystran

Re:PMode in Boot Loader

Post by mystran »

There is absolutely no good reason why kernel should be at high address and userspace at low address (except see below). You can have you kernel at 1MB (or whatever) and map your userspace from 1GB upwards. You can even play with segmentation to make BOTH think they are at low-address, while in fact one just has a segment base-offset that points into the high end of address space.

The only tasks that might care would be applications from other operating systems. If you want to have (say) Linux binaries run on your system, then it's going to be helpful if you can map the stuff at the same address you map it in Linux. But even then, you can STILL play with segmentation if you want.

If you want to support old DOS applications, then (AFAIK) you need the lowest 1MB of address space free for use by them. I have absolutely no idea if there are similar requirements for DPMI stuff, but probably not.

So basicly, if you don't care about software for other systems (or are willing to recompile) then you can put your kernel where you want. Why people like to have userspace in lowest part of the address space is not known to me.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:PMode in Boot Loader

Post by Candy »

mystran wrote: So basicly, if you don't care about software for other systems (or are willing to recompile) then you can put your kernel where you want. Why people like to have userspace in lowest part of the address space is not known to me.
That's probably to help the week and unknowing. Having a first program print out an error at location 18956 is not nice, but it's better than having it print out an error at location 99835610470957813512 (counting on 64-bit computing). You can somewhat relate the first to some small program. The second confuses and scares most might-be programmers right away.

Same with Windows error messages. If you get error #23, you can call somebody for what it is. If you get error 8000017D what're you going to say? it's not like most people would find that intuitive... or could even guess a page number for finding the error.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:PMode in Boot Loader

Post by Brendan »

Hi,
B.E wrote:Why do most of you guys put your kernal at 0xC0000000?
There's a variety of reasons (some may not matter depending on your OS). Reasons include:

- virtual 8086 tasks expect to be able to use the first 1 Mb of the virtual address space.

- if you ever want to support PAE it's best to split parts of the address space on 1 Gb boundaries. This is because with PAE there's 4 seperate page directories where each page directory controls 1 Gb of the linear address space.

- if you ever want to support 64 bit (long mode) you may want legacy 32 bit applications to have up to 4 Gb of space (up to 0x0000000100000000), with the kernel above 0x8000000000000000. In this case the 32 bit/legacy software will need to be designed to use lower addresses. You can't do the reverse, with the kernel at lower address and legacy 32 bit software above 0x8000000000000000.


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:PMode in Boot Loader

Post by Candy »

Brendan wrote: - if you ever want to support 64 bit (long mode) you may want legacy 32 bit applications to have up to 4 Gb of space (up to 0x0000000100000000), with the kernel above 0x8000000000000000. In this case the 32 bit/legacy software will need to be designed to use lower addresses. You can't do the reverse, with the kernel at lower address and legacy 32 bit software above 0x8000000000000000.
*cough* AMD64 and EM64T both have only 48 bits of actual address space. So, your pointers become 0x0000000100000000, 0xFFFFFF8000000000 and 0xFFFFFF8000000000. I thought your OS did 64-bit already?
B.E

Re:PMode in Boot Loader

Post by B.E »

I've desided to use a multi-stage bootloader and leave the free bytes. Who knows I might need to send something to the kernal at startup

Thankyou for all of your help clearing the confusion over where to put the kernal.
Post Reply