Page 1 of 2

Systematic setup for loading kernel?

Posted: Thu Apr 03, 2008 5:49 am
by Pitchu
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! :roll:

Posted: Thu Apr 03, 2008 6:28 am
by Combuster
a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
You only need three, including null. If you don't know why, do more research.
e. IDT having 32 descriptors(NONE POPULATED).
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?
h. Load kernel into memory and some part of it will do rest of necessary things like filling of IDT,loading of shell, etc.
Loading the kernel from disk after switching to protected mode? how do you manage that for all possible ATA and non-ATA devices?
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.
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?
Also I am not using QEMU or BOCHS.
You should.

LDT not used

Posted: Thu Apr 03, 2008 7:59 am
by einsteinjunior
I just wish to know why most OS designers do not use the LDT.
Is something wrong with using it?

Posted: Thu Apr 03, 2008 8:03 am
by AJ
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

Posted: Thu Apr 03, 2008 8:05 am
by einsteinjunior
So you are not using an emulator?
How do you do tests then?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......

Posted: Thu Apr 03, 2008 8:24 am
by Krox
Combuster wrote:
a. GDT having 4 descriptors(code/data/stack) for Kernel including NULL.
You only need three, including null. If you don't know why, do more research.
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.

edit: oops, there was somebody faster... but nevermind
e. IDT having 32 descriptors(NONE POPULATED).
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.

Posted: Thu Apr 03, 2008 9:49 am
by Pitchu
For Combuster :
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?
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.

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.

Loading the kernel from disk after switching to protected mode? how do you manage that for all possible ATA and non-ATA devices?
Yep! You are correct.
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.

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?
I think you got it!
You only need three, including null. If you don't know why, do more research.
NULL/CODE/DATA....Why not STACK? I will get it soon, anyway thanks for that. :P


For einsteinjunior:

How do you do tests then?
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.
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......
Ah!
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.. :P
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:
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.
Yeah...That is what my delimma was.
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?

Posted: Thu Apr 03, 2008 10:16 am
by Combuster
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.
Which is exactly why I warned you - it will.

Posted: Thu Apr 03, 2008 10:45 am
by Pitchu
May i know how?

Posted: Thu Apr 03, 2008 10:46 am
by neon
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?
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.

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.

Posted: Thu Apr 03, 2008 2:56 pm
by JamesM
IDTR contains the IVT offset in real mode. If you install an IDT, you change IDTR, so you lose all your bios interrupts.

Posted: Thu Apr 03, 2008 6:56 pm
by neon
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.
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).

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.

Posted: Fri Apr 04, 2008 12:00 am
by Pitchu
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.
Wow!
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?

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.
Yeah....Taking above post of James into consideration this is correct. Thanks.


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?

Posted: Fri Apr 04, 2008 12:28 am
by JoeKayzA
Pitchu wrote: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.

Posted: Fri Apr 04, 2008 1:19 am
by Ready4Dis
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.
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.