OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 4:56 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: GDT: Jumps to wrong memory after reloading registers
PostPosted: Sat Nov 18, 2017 3:45 pm 
Offline

Joined: Tue Apr 11, 2017 11:18 am
Posts: 15
Hello everyone,

after reading through a lot of the wiki pages/tutorials I decided to setup my own GDT, however as soon as I reload any of the registers ds, ss and cs there's a jump to a completely wrong address for some reason and that causes a crash.

To store the address and size used when executing "lgdt" i used this struct:
Code:
struct gdt_info {
   unsigned int address;
   unsigned short size;
} __attribute__((packed));

And to store a single gdt entry I used this struct:
Code:
struct gdt_entry {
   unsigned char upperBase; // Bits 24 to 31 of base address
   unsigned char config; //Flags in the upper 4 bits and Limit from 16-19 in the lower four
   unsigned char access; //Access byte
   unsigned char middleBase; // Bits 16 to 23 of base address
   unsigned short lowerBase; //Bits 0 to 15 of base address
   unsigned short limit; //Lower limit(Bits 0 to 15)
} __attribute__((packed));


Then I define an array of 3 of the structs containing the null descriptor, the kernel data segment and the kernel code segment:
Code:
struct gdt_entry nullDescriptor = {
      .upperBase = 0,
      .config = 0,
      .access = 0,
      .middleBase = 0,
      .lowerBase = 0,
      .limit = 0
   };
   gdt_entries[0] = nullDescriptor;
   /* 0x9A = 10011010 0xC=1100 */
   gdt_entries[1] = gdt_makeEntry(0, 0xFFFFF, 0x9A, 0xC);
   /* 0x92 = 10010010 */
   gdt_entries[2] = gdt_makeEntry(0, 0xFFFFF, 0x92, 0xC);


With make_entry doing this:
Code:
struct gdt_entry gdt_makeEntry(unsigned int base, unsigned int limit, unsigned char access, unsigned char flags){
   struct gdt_entry newEntry = {
      .upperBase = (base & 0xFF000000) >> 24,
      .config = ((flags & 0x0F) << 4) | ((limit & 0xF0000) >> 16),
      .access = access,
      .middleBase = (base & 0x00FF0000) >> 16,
      .lowerBase = (base & 0x0000FFFF),
      .limit = (limit & 0x0FFFF)
   };
   return newEntry;
}

I'm using following assembler functions to lgdt:
Code:
global load_gdt
;load_gdt Loads a GDT, with the first argument being the address to a gdt_info struct
;Stack: [esp+4] Address to gdt_info struct
;   [esp] Return address
load_gdt:
   mov eax, [esp+4]
   lgdt [eax]
   ret

When stepping through this with GDB I checked if eax contained the correct address and it did, and the size and address of the GDT were also correct.
Now here comes the problematic code:
Code:
global gdt_setRegisters
;gdt_setRegisters Sets the required cs, ss and ds registers
;Stack:
;   [esp] Return address
gdt_setRegisters:
   jmp 0x08:flush_cs ;And then flush it

flush_cs:
   ; And we are with cs = [esp+2]
   mov ax, 0x10
   mov ds, ax
   mov ss, ax
   ret

As soon as the jmp is executed the executions jumps to a seemingly random address in memory resulting, sooner or later, in a crash. I also tried swapping around the flushing of the CS register and the setting of ds and ss, but I still get the same Problem it jumps to a bogus address once reaching the first instructions that modifies any of cs, ds and ss.

While single stepping through GDB I also noticed that the "disassemble" command doesn't recognise the far jump, but instead displays (BAD).

I hope you can help me.

Regards,
Luca


Last edited by Luca1 on Sat Nov 18, 2017 4:29 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: GDT: Jumps to wrong memory after reloading registers
PostPosted: Sat Nov 18, 2017 3:58 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
The only reason I can think of for the code to jump to a seemingly random location is that you are getting an exception, but haven't set up the IDT and exception handlers.


Top
 Profile  
 
 Post subject: Re: GDT: Jumps to wrong memory after reloading registers
PostPosted: Sat Nov 18, 2017 4:01 pm 
Offline

Joined: Tue Apr 11, 2017 11:18 am
Posts: 15
iansjack wrote:
The only reason I can think of for the code to jump to a seemingly random location is that you are getting an exception, but haven't set up the IDT and exception handlers.


I didn't, but from my last understanding this should Triple fault my CPU, shouldn't it?
And even then something is still wrong if I'm getting an exception and I'm quite confused why considering my GDT is seemingly correct(According to GDB, if you want I can post the path I followed)


Top
 Profile  
 
 Post subject: Re: GDT: Jumps to wrong memory after reloading registers
PostPosted: Sat Nov 18, 2017 9:17 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Luca1 wrote:
Code:
struct gdt_info {
   unsigned int address;
   unsigned short size;
} __attribute__((packed));
First thing I see here is that the size and address are reversed. Should be:
Code:
struct gdt_info {
   unsigned short size;
   unsigned int address;
} __attribute__((packed));
This is a known bug in the Little OS Book tutorial. I assume that you got this definition from that tutorial or someone who relied on that tutorial.


Top
 Profile  
 
 Post subject: Re: GDT: Jumps to wrong memory after reloading registers
PostPosted: Sun Nov 19, 2017 1:06 am 
Offline

Joined: Tue Apr 11, 2017 11:18 am
Posts: 15
MichaelPetch wrote:
Luca1 wrote:
Code:
struct gdt_info {
   unsigned int address;
   unsigned short size;
} __attribute__((packed));
First thing I see here is that the size and address are reversed. Should be:
Code:
struct gdt_info {
   unsigned short size;
   unsigned int address;
} __attribute__((packed));
This is a known bug in the Little OS Book tutorial. I assume that you got this definition from that tutorial or someone who relied on that tutorial.


Yeah I kinda followed along this tutorial. I turned around the order of the gdt_info and gdt_entry structs and now it works perfectly!
Thank you very much!


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 81 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