PMode in Boot Loader
PMode in Boot Loader
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.
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.
Re:PMode in Boot Loader
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.B.E wrote: The GDT would use up 32(4 descriptors) bytes
IDT isn't required for the switch to PMode, just be sure to mask IRQs and turn off interrupts before the switch.IDT would only use up 8 (1 descriptor, copy the 1 descriptor 256 times).
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.Or is it better to go into protected mode in my kernal code.
Re:PMode in Boot Loader
Hi,
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:
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:
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
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.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.
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)
Code: Select all
mask all IRQs in the PICs
wait for any remaining IRQ's to be handled
disable interrupts
enable protected mode, etc..
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.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re:PMode in Boot Loader
Hmmm... This problem is news to me. Does anyone know if GRUB does anything to prevent this?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: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
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)
This prevents the CPU's "interrupt cache" from carrying stale interrupts into the protected mode environment.Code: Select all
mask all IRQs in the PICs wait for any remaining IRQ's to be handled disable interrupts enable protected mode, etc..
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:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Re:PMode in Boot Loader
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
http://www.mega-tokyo.com/forum/index.p ... eadid=7486
Re:PMode in Boot Loader
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?
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?
Re:PMode in Boot Loader
Hi,
Cheers,
Brendan
It seems this is a local APIC problem, rather than a legacy PIC problem (and shouldn't happen for the PIC chips).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?
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:PMode in Boot Loader
List of things a bootloader could do: http://my.execpc.com/~geezer/osd/boot/steps.txtB.E wrote: I still have around about 80 bytes left. What can I do with the free bytes.
Re:PMode in Boot Loader
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).B.E wrote: Why do most of you guys put your kernal at 0xC0000000?
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.
Re:PMode in Boot Loader
I'm confused by your explanation.Poseidon wrote:... 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).B.E wrote: Why do most of you guys put your kernal at 0xC0000000?
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
Re:PMode in Boot Loader
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.
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.
Re:PMode in Boot Loader
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.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.
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.
Re:PMode in Boot Loader
Hi,
- 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
There's a variety of reasons (some may not matter depending on your OS). Reasons include:B.E wrote:Why do most of you guys put your kernal at 0xC0000000?
- 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.
Re:PMode in Boot Loader
*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?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.
Re:PMode in Boot Loader
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.
Thankyou for all of your help clearing the confusion over where to put the kernal.