OSDev.org https://forum.osdev.org/ |
|
GDT: Jumps to wrong memory after reloading registers https://forum.osdev.org/viewtopic.php?f=1&t=32577 |
Page 1 of 1 |
Author: | Luca1 [ Sat Nov 18, 2017 3:45 pm ] |
Post subject: | GDT: Jumps to wrong memory after reloading registers |
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 |
Author: | iansjack [ Sat Nov 18, 2017 3:58 pm ] |
Post subject: | Re: GDT: Jumps to wrong memory after reloading registers |
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. |
Author: | Luca1 [ Sat Nov 18, 2017 4:01 pm ] |
Post subject: | Re: GDT: Jumps to wrong memory after reloading registers |
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) |
Author: | MichaelPetch [ Sat Nov 18, 2017 9:17 pm ] |
Post subject: | Re: GDT: Jumps to wrong memory after reloading registers |
Luca1 wrote: Code: struct gdt_info { unsigned int address; unsigned short size; } __attribute__((packed)); Code: struct gdt_info { 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.
unsigned short size; unsigned int address; } __attribute__((packed)); |
Author: | Luca1 [ Sun Nov 19, 2017 1:06 am ] |
Post subject: | Re: GDT: Jumps to wrong memory after reloading registers |
MichaelPetch wrote: Luca1 wrote: Code: struct gdt_info { unsigned int address; unsigned short size; } __attribute__((packed)); Code: struct gdt_info { 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.unsigned short size; unsigned int address; } __attribute__((packed)); 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! |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |