Code: Select all
{Set up the GDT.}
SetGDTEntry(0,0,0,0,0);
//Ring 0 segments. First Data, then Code.
SetGDTEntry(1,0,$FFFFFFFF,$92,$CF);
SetGDTEntry(2,0,$FFFFFFFF,$9A,$CF);
//Ring 1 segments. First Data, then Code.
SetGDTEntry(3,0,$FFFFFFFF,$B2,$CF);
SetGDTEntry(4,0,$FFFFFFFF,$BA,$CF);
//Ring 2 segments. First Data, then Code.
SetGDTEntry(5,0,$FFFFFFFF,$D2,$CF);
SetGDTEntry(6,0,$FFFFFFFF,$DA,$CF);
//Ring 3 segments. First Data, then Code.
SetGDTEntry(7,0,$FFFFFFFF,$F2,$CF);
SetGDTEntry(8,0,$FFFFFFFF,$FA,$CF);
//Segments with a special base that changes $100000 (physical kernel load address) into $C0100000 (virtual kernel load address in higher half.
SetGDTEntry(9,$40000000,$FFFFFFFF,$92,$CF);
SetGDTEntry($A,$40000000,$FFFFFFFF,$9A,$CF);
//Set the GDT pointer.
pGDT.wLimit:= sizeof(TGDTEntry) * 11 - 1;
pGDT.pBase:= @geGDT[0];
//Set the GDT and segment registers.
SetGDT();
SetSegmentRegisters(9 * $8,$A * $8);
Code: Select all
ENTRY(_start)
OUTPUT_FORMAT("elf32-i386")
SECTIONS
{
. = 0xC0100000;
.text ALIGN (0x1000) : AT(ADDR(.text) - 0xC0000000)
{
*(.text)
*(.rodata)
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
{
*(.data)
}
.bss ALIGN (0x1000) : AT(ADDR(.bss) - 0xC0000000)
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
KernelEnd = .;
}
I need a way to load the kernel to the point that it can switch the segment registers, but still have it work beyond that. [Foamy the squirrel]What shall I do O gurus of computer wisdom?[/Foamy the squirrel]