Cannot change GDT while in protected mode

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
fkpama
Posts: 3
Joined: Wed Mar 19, 2014 9:32 pm

Cannot change GDT while in protected mode

Post by fkpama »

Hi all, first post on the forum.

I should start by saying that I'm a newbie in OS programming! So forgive me if my question sounds stupid.

Until now, I managed to install grub2 on a hard disk and make him load my kernel. I'm now playing a little with this tutorial. I know it's for real mode programming, but I wanted to adapt it to the environment that we're in when given control by grub and somehow I'm stuck for 3/4 days now on the GDT's step.

When I debug with qemu, I see that my kernel freeze when I'm trying to change the DS register. as I understand things, I believe the DS register was not used until accessing data in other segment, even in protected mode (please feel free to correct me if I'm wrong). So I was hoping that my code, following the one on the tutorial, would smoothly work. But, as some of you may have understand since I'm sure I'm making a dumb mistake, It's not working.

Can someone help me here please? Did I missed something?

Thanks for your time guys
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: Cannot change GDT while in protected mode

Post by thepowersgang »

First off, bran's tutorial is actually a protected mode tutorial (an old one, with many very bad quirks).

Without seeing what code you're compiling, I can't really tell much about why your code is crashing. But I'd suggest running your code under bochs with the debugger enabled instead of using qemu at this stage. (You'll want to compile bochs with --enable-debugger if using linux, or use bochsdbg.exe if on windows)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
fkpama
Posts: 3
Joined: Wed Mar 19, 2014 9:32 pm

Re: Cannot change GDT while in protected mode

Post by fkpama »

Hi thepowersgang, thanks for your quick support. The code is pretty much exactly what's in the tutorial.

Here it is :

File asm.S :

Code: Select all

.global gdt_flush
gdt_flush:
lgdt	gp
	mov	$0x10, %ax
	mov	%ax, %ds
	mov	%ax, %es
	mov	%ax, %fs
	mov	%ax, %gs
	mov	%ax, %ss
	ljmp	$0x08, $flush2
        ret
Here's how I call it :

Code: Select all

typedef
        struct s_gdt
        {
                WORD limit_low;
                WORD base_low;
                BYTE base_middle;
                BYTE access;
                BYTE granularity;
                BYTE base_high; 
        } PACKED
        GDT_ENTRY;

typedef
        struct s_gdt_ptr
        {
                WORD limit;
                DWORD base;
        } PACKED
        GDT_PTR;

GDT_ENTRY gdt[3];
GDT_PTR gp;

extern void gdt_flush();

void gdt_set_gate(int num, DWORD base, DWORD limit, BYTE access, BYTE gran)
{
        gdt[num].base_low = (base & 0xFFFF);
        gdt[num].base_middle = ( base >> 16 ) & 0xFF;
        gdt[num].base_high = ( base >> 24 ) & 0xFF;

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

        gdt[num].granularity |= (gran & 0xF0);
        gdt[num].access = access;
}

void gdt_install()
{
        gp.limit = (sizeof(GDT_PTR) * 3) - 1;
        gp.base = (DWORD)&gdt;

        gdt_set_gate(0,0,0,0,0);
        gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
        gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

        gdt_flush((DWORD)&gp);
}
In the kernel_main I just call gdt_install(). WORD, BYTE, DWORD just expands to 'unsigned short', 'unsigned char' and 'unsigned int', respectively.

I'll give a try with the bochs debugger as you suggested.

Thanks for your help.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Cannot change GDT while in protected mode

Post by Bender »

Hi,
This may be incorrect. (I am not familiar with GAS Syntax so beware!)

Code: Select all

lgdt   gp
Should be:

Code: Select all

lgdt [gp]
Basically the difference is that X will pass the address of X, however [X] will get the value. (Hope what I am saying is sane)
EDIT: Does it even compile? Where exactly is flush2?
According to the tutorial:

Code: Select all

global _gdt_flush     ; Allows the C code to link to this
extern _gp            ; Says that '_gp' is in another file
_gdt_flush:
    lgdt [_gp]        ; Load the GDT with our '_gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
flush2:
    ret 
BTW I haven't looked at your other code.
-Bender
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
fkpama
Posts: 3
Joined: Wed Mar 19, 2014 9:32 pm

Re: Cannot change GDT while in protected mode

Post by fkpama »

Hi Bender,

I'm really sorry about that, I forgot to mention that I'm using gas (AT&T) syntax so I give the memory location with that statement.

about flush2, I didn't put it in this code :oops: . I must have deleted it by mistake (it's been 4 days you know :twisted: ) but I saw the registers that QEMU (multi boot) gave me and it was already pointing to the right offset and, I didn't have the chance to worry about that yet, I don't even pass the 2nd line :/
Last edited by fkpama on Wed Mar 19, 2014 11:21 pm, edited 2 times in total.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Cannot change GDT while in protected mode

Post by Bender »

Hi,
Well then do what thePowersGang suggested, test it on Bochs with debugging enabled, and post what you get.
-Bender
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Post Reply