OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Jul 23, 2018 9:52 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: [Solved] Exception after flushing GDT
PostPosted: Wed Jul 04, 2018 10:40 pm 
Offline

Joined: Wed Jun 13, 2018 12:29 am
Posts: 2
Hey folks,
I'm trying to get my GDT setup following the tutorial on the Wiki. Unfortunately, as soon as I try to flush my GDT, the system (i.e. qemu) appears to jump to a random address, and if I continue execution under the debugger it will restart. I assume this means some exception is being thrown, but I don't know which one; since the GDT is a prerequisite for the IDT (as I understand it), I don't have the latter set up.

I'm using the following function to initialize the GDT. It's basically copy-pasted from the tutorial:
Code:
global _set_gdt
_set_gdt:
   mov   eax, [esp + 4]
   mov   [gdtr + 2], eax
   mov   ax, [esp + 8]
   mov   [gdtr], ax
   lgdt  [gdtr]

reloadSegments:
   ; Reload CS register containing code selector:
   jmp   0x08:reload_CS ; 0x08 points at the new code selector
reload_CS:
   ; Reload data segment registers:
   mov   ax, 0x10 ; 0x10 points at the new data selector
   mov   ds, ax
   mov   es, ax
   mov   fs, ax
   mov   gs, ax
   mov   ss, ax
   ret


In my C code, I have the following GDT definitions:
Code:
struct gdt_descriptor
{
    uint32_t base;
    uint32_t limit;
    uint32_t type;
};
typedef struct gdt_descriptor gdt_descriptor_t;

static const uint32_t tss = 0xffffff97;
static const uint32_t tss_length = 0x68;

static const gdt_descriptor_t gdt_definitions[] =
{
    {.base = 0, .limit = 0, .type = 0}, // Selector 0x0, null descriptor Cannot be used.
    {.base = 0, .limit = 0xffffffff, .type = 0x9A}, // Selector 0x08, code
    {.base = 0, .limit = 0xffffffff, .type = 0x10}, // Selector 0x10, data
    {.base = tss, .limit =  tss + tss_length, .type = 0x89} // Selector 0x18, TSS
};

static uint8_t gdt[GDT_ENTRY_SIZE * (sizeof(gdt_definitions) / sizeof(gdt_descriptor_t))];


I chose the TSS value arbitrarily because I don't know what it should be, but it's not being used right now anyway, AFAIK. These values are encoded into the appropriate format using the encodeGdtEntry function from the tutorial. I copied it verbatim and just changed the name to match my convention. I call it as follows:

Code:
void gdt_initialize()
{
    const size_t gdt_entry_count = sizeof(gdt_definitions) / sizeof(gdt_descriptor_t);
    memset(gdt, 0, sizeof(gdt));

    for(size_t i = 0; i < gdt_entry_count; ++i)
    {
        encode_gdt_entry(gdt + (i * GDT_ENTRY_SIZE), gdt_definitions[i]);
    }
   
    _set_gdt(gdt, sizeof(gdt));
}


Here is what the GDT looks like before calling _set_gdt:

Code:
(gdb) x/32xb gdt
0x107020 <gdt>:        0x00    0x00    0x00    0x00    0x00    0x00    0x40    0x00
0x107028 <gdt+8>:      0xff    0xff    0x00    0x00    0x00    0x9a    0xcf    0x00
0x107030 <gdt+16>:     0xff    0xff    0x00    0x00    0x00    0x10    0xcf    0x00
0x107038 <gdt+24>:     0xff    0xff    0x97    0xff    0xff    0x89    0xcf    0xff


Stepping through in the debugger, everything looks correct up until the `mov ds, ax` instruction in `reload_CS`. Once that executes, the exception/crash occurs. One thing I'd like to do is check the value of the GDT register once I set it, but gdb can't do that and I don't know how to do it in qemu (if it's even possible). Any help is much appreciated!

PS: I noticed that the GDT tutorial uses Intel/NASM syntax whereas the getting started tutorials use AT&T/GAS. It would be nice to make these consistent. :)


Last edited by Piezoelectric on Wed Jul 04, 2018 11:25 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Exception after flushing GDT
PostPosted: Wed Jul 04, 2018 11:07 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 33
Your gdt+16 has no P bit. That one looks really b0rken. I think you need type 0x92 for that one, which should set the P bit and the S bit, and set the type to "writable data segment". And the limit for the TSS segment is just the length of the TSS minus 1. Oh, and clear the G bit on the TSS segment, since the length isn't measured in pages, right? The segment limit always the largest allowed byte (or page) offset.

As for assembly style: Them's fighting words! :wink: That's like asking for the best editor, best OS to work on, best processor-architecture...


Top
 Profile  
 
 Post subject: Re: Exception after flushing GDT
PostPosted: Wed Jul 04, 2018 11:25 pm 
Offline

Joined: Wed Jun 13, 2018 12:29 am
Posts: 2
Ugh, yup, that was it. I put the selector in where the type should have gone. Thanks! And thanks also for the advice about the TSS. That will come in handy once I actually start using it. :)

I don't want to start a religious war over assembly syntax, so I edited out my comment about my personal preference. I don't particularly care which style the wiki uses, but it would be nice to pick one and stick with it, so that users don't have to convert between them. I'm just not sure if I should make that change myself, because I don't want to step on anyone's toes.


Top
 Profile  
 
 Post subject: Re: [Solved] Exception after flushing GDT
PostPosted: Wed Jul 04, 2018 11:43 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3206
Location: Chichester, UK
The Wiki is just that - a Wiki - which means that different contributors will use different styles in all sorts of places. It's a source of information rather than a single, coherent tutorial.

It's not a bad idea to encounter different styles and become familiar with them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group