Setting up new GDT
Setting up new GDT
I'm setting up a post-GRUB GDT for my kernel, and want to write a function to load the GDT and set the segment registers like the one at http://www.osdever.net/bkerndev/index.php?the_id=90 . How could I do this in Pascal? The compiler is set up to allow inline assembler (even whole routines of it) in Intel format.
Re:Setting up new GDT
If your GDT is set up in the same way then you should be able to implement the code exactly the same, I don't know whether Pascal takes line labels but it should, it should work fine as is. (Provided the GDT is NULL, Code, Data)
Re:Setting up new GDT
I've set mine up as NULL,DATA,CODE, but I know how to switch the numbers. The problem lies in jumping to a new code segment. I've got a way to label a line, but for some damn reason it refuses to accept the jmp instruction.
Re:Setting up new GDT
If it won't take it then you can create an ASM file and call that from the Pascal code, you will probably need to look through the language guides for inline assembly to see how to implement it properly using the inline assembler.
Re:Setting up new GDT
I've looked through the docs. They don't help much. And I tried a seperate asm file to be compiled with nasm, but then had trouble linking my RTL and it both into my final program.
Re:Setting up new GDT
Your lucky i just started an os in freepascal and got new GDT working
Code: Select all
procedure kload_gdt(); assembler; [public, alias: 'kload_gdt'];
asm
//jmp GDT_KERNEL_CODE_SEL:@loadedcs
//Freepascal will not compile this!
//But Intel manual says you can use a far ret.
//RETF executes a far return: after popping IP/EIP, it then pops CS, and then increments the
//stack pointer by the optional argument if present.
//Force dword sized push, because retf pops dwords and else the stack will be rong.
push dword GDT_KERNEL_CODE_SEL
push dword offset @loadedcs
lgdt gdtr
retf
@loadedcs:
mov ax, GDT_KERNEL_DATA_SEL
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
end ['EAX'];
Re:Setting up new GDT
Thank you so much! ;D
*Crazed bows before master*
Just one more question. In my linker script I have a KERNEL_END variable defined that I use to find the end of kernel memory, including the kernel stack. I want to use this constant in my Pascal code and I've written it as:
This reference resolves, but the variable always evaluates to zero. In my linker script I write on the very last line before the closing curly-brace of the SECTIONS section:
What's wrong here?
*Crazed bows before master*
Just one more question. In my linker script I have a KERNEL_END variable defined that I use to find the end of kernel memory, including the kernel stack. I want to use this constant in my Pascal code and I've written it as:
Code: Select all
var
KERNEL_END: longword; external name 'KERNEL_END';
Code: Select all
KERNEL_END = .;
Re:Setting up new GDT
The linker resolves linkscript variables as pointers, KERNEL_END is resolved as a variable located at that point.
In C the way around is:
It's cleaner to do this in the linkscript though:
This creates a variable and stores the kernel end in it.
In C the way around is:
Code: Select all
extern int KERNEL_END;
printf("Kernel End is at %x", &KERNEL_END); //Notice "Get Reference" symbol
Code: Select all
.data
{
...
KERNEL_DATA = .;
LONG(KernelEndPoint);
}
...
KernelEndPoint = .;