Systematic setup for loading kernel?
Systematic setup for loading kernel?
Hi
Firstly, I wanna give overview of what i have done :
1. I wrote a BootLoader/Bootsector that gives choice to load my OS or other OS and copied that BIN file(512 bytes) onto bootsector (not MBR) of the Active FAT32 partition of my HDD saving the old Bootsector onto spare sectors between 0-62 for normal booting if user selects other OS(XP in my case).
2. If MyOS is selected it loads the SecondStage BootLoader from the same partition.It is 4kb in size and detects hardware and stores that in a struct.
In the same SecondStage Bootloader I want to setup enviroment for Pmode (coz maybe kernel may not fit in less than 1MB) and enable Pmode.
I think I should do this :
a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
I will set base=0 and limit=0xfffff for 4GB memory access in all descriptors except NULL,offcourse.
(Intention is to use Flat-Memory Model using Paging.)
b. NO LDT
c. SET CR3 to a physical address of Page-Directory which will contain page table addresses where pages will be mapped to frames linearly, i mean 0 to 0 address, i.e.
No translation for kernel.
d. Remap PIC to invoke 32 or greater interrupt numbers in IDT on firing.
I am confused whether to enter correponding enteries in IDT or let kernel do it?
e. IDT having 32 descriptors(NONE POPULATED).
I am confused whether to populate atleast some or not? Please suggest.
f. Enable A20, Set PE and PG bits.
g. Make a far JMP to flush the que or in other words let the processor units know about that mode has changed.
(I think latter is a better quote.)
h. Load kernel into memory and some part of it will do rest of necessary things like filling of IDT,loading of shell, etc.
Also I am not using QEMU or BOCHS.
Ya Allah,
It is all messed up inside my cranial cavity.
Hope this is a correct way!
Firstly, I wanna give overview of what i have done :
1. I wrote a BootLoader/Bootsector that gives choice to load my OS or other OS and copied that BIN file(512 bytes) onto bootsector (not MBR) of the Active FAT32 partition of my HDD saving the old Bootsector onto spare sectors between 0-62 for normal booting if user selects other OS(XP in my case).
2. If MyOS is selected it loads the SecondStage BootLoader from the same partition.It is 4kb in size and detects hardware and stores that in a struct.
In the same SecondStage Bootloader I want to setup enviroment for Pmode (coz maybe kernel may not fit in less than 1MB) and enable Pmode.
I think I should do this :
a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
I will set base=0 and limit=0xfffff for 4GB memory access in all descriptors except NULL,offcourse.
(Intention is to use Flat-Memory Model using Paging.)
b. NO LDT
c. SET CR3 to a physical address of Page-Directory which will contain page table addresses where pages will be mapped to frames linearly, i mean 0 to 0 address, i.e.
No translation for kernel.
d. Remap PIC to invoke 32 or greater interrupt numbers in IDT on firing.
I am confused whether to enter correponding enteries in IDT or let kernel do it?
e. IDT having 32 descriptors(NONE POPULATED).
I am confused whether to populate atleast some or not? Please suggest.
f. Enable A20, Set PE and PG bits.
g. Make a far JMP to flush the que or in other words let the processor units know about that mode has changed.
(I think latter is a better quote.)
h. Load kernel into memory and some part of it will do rest of necessary things like filling of IDT,loading of shell, etc.
Also I am not using QEMU or BOCHS.
Ya Allah,
It is all messed up inside my cranial cavity.
Hope this is a correct way!
- Combuster
- 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:
You only need three, including null. If you don't know why, do more research.a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
having an empty IDT is worth the same as having no IDT at all. In fact loading an IDT early in real mode will mess up the IVT if you plan to use bios calls later. Also, where did those 16 IRQs from the remapped PIC go?e. IDT having 32 descriptors(NONE POPULATED).
Loading the kernel from disk after switching to protected mode? how do you manage that for all possible ATA and non-ATA devices?h. Load kernel into memory and some part of it will do rest of necessary things like filling of IDT,loading of shell, etc.
So, how do you get that kernel of yours into memory when you can't use bios calls from protected mode and the kernel can't fit into memory accessible from real mode?In the same SecondStage Bootloader I want to setup enviroment for Pmode (coz maybe kernel may not fit in less than 1MB) and enable Pmode.
You should.Also I am not using QEMU or BOCHS.
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am
LDT not used
I just wish to know why most OS designers do not use the LDT.
Is something wrong with using it?
Is something wrong with using it?
Hi,
The LDT is used to store segment descriptors specific to a process. Segmentation is now considered 'legacy' - it is not supported in 64 bit mode - overall, you are better using paging as a protection mechanism. Even if you have a LDT, you cannot use it to store Task State Segments.
This is why most people seem to set up a GDT with 5 flat segments (NULL, ring 0 code / data, ring 3 code / data) plus TSS descriptors for each CPU core and leave it at that.
Cheers,
Adam
The LDT is used to store segment descriptors specific to a process. Segmentation is now considered 'legacy' - it is not supported in 64 bit mode - overall, you are better using paging as a protection mechanism. Even if you have a LDT, you cannot use it to store Task State Segments.
This is why most people seem to set up a GDT with 5 flat segments (NULL, ring 0 code / data, ring 3 code / data) plus TSS descriptors for each CPU core and leave it at that.
Cheers,
Adam
- einsteinjunior
- Member
- Posts: 90
- Joined: Tue Sep 11, 2007 6:42 am
Actually, you need 6 with most common OS-Designs: NULL, Ring0-Code, Ring0-Data, Ring3-Code, Ring3-Data, TSS. But okay... as long as you dont have multitasking, the first three are enough.Combuster wrote:You only need three, including null. If you don't know why, do more research.a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
edit: oops, there was somebody faster... but nevermind
As said before, you need 16 more for the PIC (at least). And I would suggest, you populate the 32 exception-descriptors as soon as you are in PMode. A simple error-msg and hlt is enough. This will save you much time when debugging your kernel. Cause otherwise every exception will triple-fault and reset the PC, and you don't have a clue what went wrong.e. IDT having 32 descriptors(NONE POPULATED).
21 is only half the truth...
For Combuster :
Yeah..I have to think about 16 IRQs from the Remapped PIC.
Even If there is no problem with loading IDT in Rmode, still i think i shouldn't 'coz loading IDT also means installing ISRs, which means large code size and no distinction between kernel and second-stage bootloader.
What I am planning to have a mini-read module for ATA devices ONLY. I will use it to load kernel instead of IBM int 13H extensions which are not available in Pmode.
For einsteinjunior:
I am not a rich guy with dozens of PCs. I only owe a single Desktop with CRT monitor occupying half of my room with P4 processor.
Yeah it is a tedious way to compile and restart but gave me a mental strenght to visualise that I can do it..
After I am able to load kernel into memory i will switch to QEMU/BOCHS....Which one is better and easy?
And so far as crashing is concerned.....Allah knows better.
For Krox:
I will go for hlt or err msg to avoid triple fault and to denug easily. Thnx
Now, After all this what I wanna know is what to do if my kernel size is large enough such that it doesnt fit in less than 1MB space and kernel switches CPU to Pmode?
I am not going to use BIOS calls in my kernel.But I dont think loading IDT early in real mode will mess up the IVT as IDT has no meaning in Rmode and IVT has no meaning in Pmode.having an empty IDT is worth the same as having no IDT at all. In fact loading an IDT early in real mode will mess up the IVT if you plan to use bios calls later. Also, where did those 16 IRQs from the remapped PIC go?
Yeah..I have to think about 16 IRQs from the Remapped PIC.
Even If there is no problem with loading IDT in Rmode, still i think i shouldn't 'coz loading IDT also means installing ISRs, which means large code size and no distinction between kernel and second-stage bootloader.
Yep! You are correct.Loading the kernel from disk after switching to protected mode? how do you manage that for all possible ATA and non-ATA devices?
What I am planning to have a mini-read module for ATA devices ONLY. I will use it to load kernel instead of IBM int 13H extensions which are not available in Pmode.
I think you got it!So, how do you get that kernel of yours into memory when you can't use bios calls from protected mode and the kernel can't fit into memory accessible from real mode?
NULL/CODE/DATA....Why not STACK? I will get it soon, anyway thanks for that.You only need three, including null. If you don't know why, do more research.
For einsteinjunior:
Simple...Install a BootLoader using booatble CD/Floppy/Flash and copy the actual Bootsector to spare sectors as mentioned. This was only problematic part to do until my OS will Read/Write on HDD.How do you do tests then?
Ah!You should surely be some rich guy with many PCs for development and testing.....
If not then say goodbye to the good functionning of your PC.Hoping it can survive a crash......
I am not a rich guy with dozens of PCs. I only owe a single Desktop with CRT monitor occupying half of my room with P4 processor.
Yeah it is a tedious way to compile and restart but gave me a mental strenght to visualise that I can do it..
After I am able to load kernel into memory i will switch to QEMU/BOCHS....Which one is better and easy?
And so far as crashing is concerned.....Allah knows better.
For Krox:
Yeah...That is what my delimma was.And I would suggest, you populate the 32 exception-descriptors as soon as you are in PMode. A simple error-msg and hlt is enough. This will save you much time when debugging your kernel. Cause otherwise every exception will triple-fault and reset the PC, and you don't have a clue what went wrong.
I will go for hlt or err msg to avoid triple fault and to denug easily. Thnx
Now, After all this what I wanna know is what to do if my kernel size is large enough such that it doesnt fit in less than 1MB space and kernel switches CPU to Pmode?
Im not entirely sure how true that is. ntrldr's very first thing is entering pmode and installing interrupts. Afterwords it switches to v86 mode to load and execute ntdetect.having an empty IDT is worth the same as having no IDT at all. In fact loading an IDT early in real mode will mess up the IVT if you plan to use bios calls later. Also, where did those 16 IRQs from the remapped PIC go?
Granted, some might mess up; but most BIOS calls should still work fine as the location of the IDT does not at all touch the IVT in memory.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Partially correct. While you do change the base address of the ivt, you do not lose all Bios interrupts (Although alot of them become unusable, though).JamesM wrote:IDTR contains the IVT offset in real mode. If you install an IDT, you change IDTR, so you lose all your bios interrupts.
The default ivt copied into memory by the Bios will still be there when a new idt is installed. This allows us to execute Bios interrupts directly without using INT instruction via real or v86 modes. (I do this in my v86 monitor)
However:
a) Using the INT instruction to execute Bios interrupts will not work (of course) as its tied to your pmode IDT;
b) Need to be careful as some Bios interrupts execute via INT instruction and IO privilege levels. This may essentially make alot of Bios interrupts unavailable.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Wow!JamesM wrote:IDTR contains the IVT offset in real mode. If you install an IDT, you change IDTR, so you lose all your bios interrupts.
This is not mentioned in 386 manual. Thanks James!
So, IDTR has significance in Rmode.
I think nothing special about GDTR,LDTR and TR in Rmode?
Yeah....Taking above post of James into consideration this is correct. Thanks.Neon wrote: The default ivt copied into memory by the Bios will still be there when a new idt is installed. This allows us to execute Bios interrupts directly without using INT instruction via real or v86 modes. (I do this in my v86 monitor)
However:
a) Using the INT instruction to execute Bios interrupts will not work (of course) as its tied to your pmode IDT;
b) Need to be careful as some Bios interrupts execute via INT instruction and IO privilege levels. This may essentially make alot of Bios interrupts unavailable.
Doing Disk I/O in Pmode using ATA read module can load my kernel but I am not going to do that now.Thanks everybody. But the question is
If my kernel is larger than 1MB what to do?
Load the file in multiple turns, and copy the buffer above 1MB each time (switch to pmode and back or use unreal mode or so). It's some overhead, but you probably won't notice any performance impact due to the disk latency.Pitchu wrote:But the question is
If my kernel is larger than 1MB what to do?
This is how I do mine, I jump back and forth between r-mode and unreal mode (flat real mode) while loading, so I can load my kernel at 1mb. This way, I don't have anything in the way, and it can expand as big as it needs be. It takes up a bit more space than I really wanted, but it is much nicer than hoping you don't run out of space, and worrying about segments, etc.JoeKayzA wrote:Load the file in multiple turns, and copy the buffer above 1MB each time (switch to pmode and back or use unreal mode or so). It's some overhead, but you probably won't notice any performance impact due to the disk latency.