Problem loading the GDT

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.
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Problem loading the GDT

Post by Steve the Pirate »

I'm getting a strange problem loading my GDT in my new kernel. When I test it in Virtualbox, it works, but when I test in Bochs, I get an error

Code: Select all

check_cs: attempt to jump to long mode without enabling EFER.LMA !
Does anyone have any idea why this is happening?

Thanks,

-Stephen
My Site | My Blog
Symmetry - My operating system.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

Are you setting CS.L in your code segment descriptor when you try to jump to protected mode? Its bit 21 of the (edit: 2nd half of the) descriptor (see 3A:3.4.5).

Regards,
John.
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Post by Steve the Pirate »

I'm already in protected mode, and I'm trying to set up a flat memory model...

I can't work out why Bochs thinks I'm trying to jump to long mode. Am I jumping to the wrong offset?
My Site | My Blog
Symmetry - My operating system.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

Can we see the GDT and the jump instruction, please?

Cheers,
Adam
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Post by Steve the Pirate »

My most recent attempt is using JamesM's tutorial code. The same thing still happens.

The only difference is that I'm calling it from C++, instead of from C as in the tutorial.

Here is the jump:

Code: Select all

[GLOBAL gdt_flush]    ; Allows the C code to call gdt_flush().

gdt_flush:
   mov eax, [esp+4]  ; Get the pointer to the GDT, passed as a parameter.
   lgdt [eax]        ; Load the new GDT pointer

   mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
   mov ds, ax        ; Load all data segment selectors
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax
   jmp 0x08:.flush   ; 0x08 is the offset to our code segment: Far jump!
.flush:
   ret
My Site | My Blog
Symmetry - My operating system.
User avatar
Combuster
Member
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:

Post by Combuster »

After debugging I can cause the error in my own kernel when changing a reserved bit in the GDT selector (which MUST be 0 since it is currently redefined as the L bit as jnc100 suggested)

Code: Select all

MOV byte [EDI+1*8+GDT_FLAGS_HI], GDT_LIMIT_HIMASK | GDT_FLAG_PAGES | GDT_FLAG_32BIT         ; works
MOV byte [EDI+1*8+GDT_FLAGS_HI], GDT_LIMIT_HIMASK | GDT_FLAG_PAGES | GDT_FLAG_32BIT | 0x20  ; causes panic
Your GDT, please?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Post by Steve the Pirate »

I think I fixed it! I am now using this as my set gate (mostly from JamesM's code again)

Code: Select all

void gdt::gate(s32int num, u32int base, u32int limit, u8int access, u8int gran)
{
   gdt_entries[num].base_low    = (base & 0xFFFF);
   gdt_entries[num].base_middle = (base >> 16) & 0xFF;
   gdt_entries[num].base_high   = (base >> 24) & 0xFF;

   gdt_entries[num].limit_low   = (limit & 0xFFFF);
   gdt_entries[num].granularity = (limit >> 16) & 0xFF;

   gdt_entries[num].granularity |= gran & 0xF0;
   gdt_entries[num].granularity &= 0xDF;                  // ADDED - Set CS.L to 0
   gdt_entries[num].access      = access;
} 
My GDT structure is:

Code: Select all

struct gdt_entry_struct
{
   u16int limit_low;
   u16int base_low;
   u8int  base_middle;
   u8int  access;
   u8int  granularity;
   u8int  base_high;
} __attribute__((packed));
I commented the line I added, which manually sets L to zero. It seems kind of hackish, and there's probably a better way of doing it, but it works.

Would the original code work on a non-64 bit processor?
My Site | My Blog
Symmetry - My operating system.
User avatar
Combuster
Member
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:

Post by Combuster »

My guess is that you're passing a value of 0xffffffff into the limit field while it expects 20 significant bits at most.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

That would be my guess too.

You can probably fix it in a less hacky way by adding:

Code: Select all

limit &= 0xFFFFF; // Limit should only be 20 bits long.
At the start of the function, as an error check.

EDIT: Thanks for bringing this to my attention: I haven't yet tried it on a 64-bit machine (although my own kernel uses the same code and works fine on my 64-bit dev box... hmm)

It seems that error has slipped through from Bran's original code, which my code is based off. Thanks.

Hrmph. Annoying that I didn't notice that. And that bochs ran successfully on my machine (the bochs on my dev box is a x86_64 build, as is qemu). The mattise kernel has the same base code (I just checked ;) ) and it doesn't crash on x64 boxen: I wonder why only you have this problem?? :)
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

JamesM wrote:The mattise kernel has the same base code (I just checked ;) ) and it doesn't crash on x64 boxen: I wonder why only you have this problem?? :)
It does work for me as well, which makes this problem really weird.

Perhaps the source of the problem is in his initialization of his GDT?

OP: would you be able to post the code which actually calls gdt::gate? That might help us find the real source of the problem.
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Post by Steve the Pirate »

It's pretty much the same as JamesM's code:

Code: Select all

   gdt_set_gate(0, 0, 0, 0, 0);                // Null segment
   set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
   set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
   set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
   set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
So I gather that I should only have 0xFFFF as the limit?
My Site | My Blog
Symmetry - My operating system.
User avatar
Combuster
Member
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:

Post by Combuster »

Steve the Pirate wrote:So I gather that I should only have 0xFFFF as the limit?
no, 0xFFFFF - 20 ones in binary
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Yeah, it's really strange that this problem has only just appeared... Even Bran's code has it in! :(
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Post by Steve the Pirate »

Even weirder is that I downloaded the code from your tutorials, and it doesn't throw that error...
My Site | My Blog
Symmetry - My operating system.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Oh? Interesting. So you downloaded my code, compiled and ran it and it ran fine, but yours doesn't? I'll have a closer look.
Post Reply