Pmode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Pmode

Post by System123 »

I have just moved my kernel from borland pascal to free pascal(32 bit). Now i want to set up pmode. Do i need to set up pmode before i load the kernel from the disk? (In my case fdd). The other question is can i use pascal functions to set up my gdt and idt? The last one is how do i jump from my boot loader into my kernel
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Pmode

Post by AJ »

Hi,
Do i need to set up pmode before i load the kernel from the disk?
My preference is to load the kernel using BIOS functions. In this case, you need to load the kernel from disk before switching to PMode. Bear in mind that either your kernel will have to entirely fit in the space before the BIOS area at around 0x90000 or you will have to use unreal mode/PMode to copy the kernel to above 1MiB as you load it. You can then switch to Pmode and jump to your kernel.
The other question is can i use pascal functions to set up my gdt and idt?
As long as you can directly manipulate bits at known memory locations in Pascal, yes. I believe there is a Pascal barebones on the wiki and/or other people here have written Pascal kernels, so the answer must be yes.
The last one is how do i jump from my boot loader into my kernel
Assuming a flat binary loaded at the 1MiB mark:

Code: Select all

JMP 0x100000
:)
If you have an ELF format kernel, you need to extract the entry point from the ELF header and JMP to that.

Cheers,
Adam
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: Pmode

Post by inflater »

Do i need to set up pmode before i load the kernel from the disk?
You can load your kernel either by
1) real mode bootloader,
2) protected mode bootloader.

In first case, you need to put [bits 16] in your kernel's ASM stub and do the whole pmode switch there. Be warned though, you must have a fully working GDT and IDT and the protected mode set up before you call the main() function!
In second case, set up your "final" GDT/IDT/ISRs, since the one from the pmode bootloader is just temporary (i think), then you can start your pascal kernel.
The other question is can i use pascal functions to set up my gdt and idt?
Theoretically yes, but use ASM routines for that, you'll get a faster code plus you'll avoid some number of strange bugs. Really. - This applies only when your kernel is loaded by pmode bootloader!!! (When in real mode you need to set up pmode in asm.)
The last one is how do i jump from my boot loader into my kernel
When you have the protected mode fully set up, this can be done
extern Your_main_function
call Your_main_function
jmp $

like in brans kernel dev. Did you read the wiki?

And, anyways, DON'T EVER THINK of using THESE METHODS in borland pascal or in borland pascal kernel as you'll just mix up 16-bit again. You need to select if your kernel wants to be in real (B. pascal), or protected mode (FP 32-bit).

Plus, when you will be setting up gdt, idt and interrupt service routines: I suggest you code them in assembly. You'll avoid a bunch of problems that way.

BTW set the compiler to the binary format. You can switch to MZ-EXE, PE or ELF when you'll understand what you can do and do not in free pascal (since it's not meant to develop a kernel, thus running without a OS underlying). You'll see quickly what you can't do in "standalone" free pascal :D.

Regards
inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Pmode

Post by System123 »

I wasnt going to use this with BP. I have already converted my kernel to free pascal
Gizmic OS
Currently - Busy with FAT12 driver and VFS
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Pmode

Post by jal »

inflater wrote:Theoretically yes, but use ASM routines for that, you'll get a faster code plus you'll avoid some number of strange bugs. Really.
Oh really? First, when setting up a GDT it is absolutely useless to go for 'speed' as it is a one-time thing that'll take a nano-second on a modern CPU, regardless of whether you code in asm or a high-level language, and secondly, what 'strange bugs' are you thinking about? As long as you know your compiler and are able to align everything properly, there shouldn't be any 'strange bugs' (or any bug, for that matter). I've set up my GDT in C++, and it works perfectly well.


JAL
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: Pmode

Post by inflater »

To the flamebaiter: Now set the GDT and IDT up solely with pascal's declarations and arrays. You sure didn't tried that huh? :roll: Theoretically this can be accomplished, but wait until you get the first triple fault by e.g. mis-aligned tables. Therefore it's easier, faster and safer to do it in ASM.

C++ is more portable than Pascal i must say, so there it may work correctly.
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
leledumbo
Member
Member
Posts: 103
Joined: Wed Apr 23, 2008 8:46 pm

Re: Pmode

Post by leledumbo »

Taken from my OS:

Code: Select all

unit gdt;

interface

type

  TGDTEntry = packed record
    LowLimit: Word;
    LowBase: Word;
    MiddleBase: Byte;
    Access: Byte;
    Granularity: Byte;
    HighBase: Byte;
  end;

  TGDTPtr = packed record
    Limit: Word;
    Base: LongWord;
  end;

var
  GDTList: array [0..4] of TGDTEntry;
  GDTPtr: TGDTPtr;

procedure SetGDTGate(num: LongInt; base,limit: LongWord; acc,gran: Byte);
procedure InstallGDT;

implementation

uses
  console; // Write* routines are defined here

procedure FlushGDT; assembler; nostackframe;
label
  flush;
asm
  lgdt [GDTPtr]
  mov  ax,$10
  mov  ds,ax
  mov  es,ax
  mov  fs,ax
  mov  gs,ax
  mov  ss,ax
//  jmp  $08:flush   // don't know the correct syntax in FPC inline assembler, but it works!
flush:
end;

procedure SetGDTGate(num: LongInt; base,limit: LongWord; acc,gran: Byte);
begin
  with GDTList[num] do begin
    LowBase:=(base and $FFFF);
    MiddleBase:=(base shr 16) and $FF;
    HighBase:=(base shr 24) and $FF;
    LowLimit:=(limit and $FFFF);
    Granularity:=((limit shr 16) and $0F);
    Granularity:=Granularity or (gran and $F0);
    Access:=acc;
  end;
end;

procedure InstallGDT;
begin
  WriteString('Installing GDT... ');
  with GDTPtr do begin
    Limit:=SizeOf(GDTList)-1;
    Base:=PtrUInt(@GDTList);
  end;
  SetGDTGate(0,0,0,0,0); // nil descriptor
  SetGDTGate(1,0,$FFFFFFFF,$9A,$CF); // Kernel space code
  SetGDTGate(2,0,$FFFFFFFF,$92,$CF); // Kernel space data
  SetGDTGate(3,0,$FFFFFFFF,$FA,$CF); // User space code
  SetGDTGate(4,0,$FFFFFFFF,$F2,$CF); // User space data
  FlushGDT;
  WriteStrLn('Done.');
end;

end.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Pmode

Post by System123 »

My GDT setup function looks very similar to the one above. The only thing is I forgot to use packed records.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Pmode

Post by jal »

System123 wrote:My GDT setup function looks very similar to the one above. The only thing is I forgot to use packed records.
You should also check allignment of the actual declared variables.


JAL
Post Reply