OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 10:26 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: GDT troubles ...again
PostPosted: Fri Sep 07, 2007 11:48 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
OK, so I realized a few mistakes with my past projects and decided to start on a new one, being careful not to make any of those mistakes again. I got some basic printf stuff working, but the GDT is still giving me problems. Bochs gives me some errors about valid bits and interrupts:
Quote:
00017461598e[CPU0 ] load_seg_reg(DS): valid bit cleared
00017461598e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00017461598e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00017461598i[CPU0 ] protected mode
00017461598i[CPU0 ] CS.d_b = 32 bit
00017461598i[CPU0 ] SS.d_b = 32 bit
00017461598i[CPU0 ] | EAX=00000010 EBX=00103004 ECX=00000002 EDX=00000002
00017461598i[CPU0 ] | ESP=0010afac EBP=0010afd8 ESI=000247d8 EDI=00030658
00017461598i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00017461598i[CPU0 ] | SEG selector base limit G D
00017461598i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00017461598i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00017461598i[CPU0 ] | EIP=00100066 (00100066)
00017461598i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00017461598i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00017461598i[CPU0 ] >> mov ds, ax : 8ED8
00017461598e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting


So I wrote a quick function to dump a segment descriptor, and came up with:
Quote:
Segment 0: base 00000000, limit 00000000, accessed 0, writable 0, direction 0, exec 0, sys 1, dpl 0, present 1, bitness 1, granularity 1.
Raw: 00 00 00 00 00 90 c0 00
Segment 1: base 00000000, limit 000fffff, accessed 0, writable 1 [this is my code segment so I think this is "conforming" or something instead, but my dump function doesn't know the difference.], direction 0, exec 1, sys 1, dpl 0, present 1, bitness 1, granularity 1.
Raw: ff ff 00 00 00 9a cf 00
Segment 2: base 00000000, limit 000fffff, accessed 0, writable 1, direction 0, exec 0, sys 1, dpl 0, present 1, bitness 1, granularity 1.
Raw: ff ff 00 00 00 92 cf 00

Anything obvious I'm missing here? I don't see a bit called "valid" in the manual, is that referring to something else? (present is set on all of them.)

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 12:06 am 
Offline
Member
Member

Joined: Sun Apr 29, 2007 1:13 am
Posts: 234
from what i can tell, you're causing a GPF by writing invalid entries to the GDT.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 12:10 am 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
What's invalid about them though? I even printed out the contents to be sure. Is my structure in the wrong order or something?

Code:
   typedef struct __attribute__((packed))
   {
      uint_16 limit_low;
      uint_32 base_low:24;
      uint_8 accessed:1;
      uint_8 writable:1;
      uint_8 direction:1;
      uint_8 exec:1;
      uint_8 sys:1;
      uint_8 dpl:2;
      uint_8 present:1;
      uint_8 limit_high:4;
      uint_8 unused:2;
      uint_8 thirty_two_bit:1;
      uint_8 granularity:1;
      uint_8 base_high;
   } entry_t;
   
   typedef struct __attribute__((packed))
   {
      uint_32 base;
      uint_32 limit;
   } gdtr_t;


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 1:32 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
Poke. ("Bump" is such a cliche...)

I also noticed that in QEMU most of the time it will just lock up after selecting my OS in GRUB. Is this a related problem?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 3:21 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Maybe you should try setting a breakpoint in bochs to the location just where the problem starts and try examining the GDT.

Code:
info gdt 0 5

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 6:27 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
My GDT is only 3 entries long. Anyway, I could only get Bochs to enter the debugger *after* the CPU reset, so the GDT and all registers were reset also.

Looking around on the forums, I found http://www.osdev.org/phpBB2/viewtopic.php?t=14542&postdays=0&postorder=asc&highlight=fetchrawdescriptor&start=0
This suggested that I was supposed to make cs the first segment I reloaded instead of the last. But this:
Code:
extern gdtr
global gdt_flush
gdt_flush:
   mov eax, [esp+4]
   lgdt [eax]
   jmp 0x08:.finish_reload
.finish_reload:
   mov eax, 0x10
   mov ds, eax
   mov es, eax
   mov fs, eax
   mov gs, eax
   mov ss, eax
   ret

also didn't work:
Quote:
00017057497e[CPU0 ] jump_protected: call gate.p == 0
00017057497e[CPU0 ] fetch_raw_descriptor: GDT: index (f007)1e00 > limit (b020)


Taking another hint from that post I checked the versions of my toolchain, all stable afaik:
Quote:
[mike@thiscomputer ~]$ nasm -v
NASM version 0.98.39 compiled on Mar 1 2005
[mike@thiscomputer ~]$ g++ -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,objc --enable-threads=posix --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic
Thread model: posix
gcc version 4.2.1
[mike@thiscomputer ~]$ ld -v
GNU ld version 2.17.50.0.18 20070731


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 6:57 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Okay the following method may not be supported on your particular BOCHs version but this is how I would do it. With a thing known as Magic Breakpoints. All you have to do is put a xchg bx, bx where you want to debugger to stop at and edit the config file to say magic_break: enabled=1 somewhere in it.

The other way would be to use
Code:
mov ecx, 0
breakpoint:
cmp ecx, 0
    je breakpoint


and jump to the debugger when it locks up and type set ecx = 1 and then continue from there.

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 7:21 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
Quote:
00022852647i[CPU0 ] [22852647] Stopped on MAGIC BREAKPOINT

Nice, it works. Gotta love black magic (although I suppose it could be another color if I decided to change my Konsole background.)

I put one here:
Code:
gdt_flush:
   mov eax, [esp+4]
   lgdt [eax]
   xchg bx, bx
   jmp 0x08:.finish_reload
.finish_reload:

and got this:
Quote:
<bochs:4> info gdt 0 2
Global Descriptor Table (base=0x00170010, limit=45088):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x02]=??? descriptor hi=0x00000000, lo=0x00000000


So something is corrupting GDTR. (I know a 3-entry GDT is less than 45008 bytes.) The limit is also wrong (last symbol in objdump -S ends at 0x101aea)

-----

OK, just realized I had gdtr_t not only in the wrong order, but I made both base and limit uint_32's. So, now:
Code:
   typedef struct __attribute__((packed))
   {
      uint_16 limit_low;
      uint_32 base_low:24;
      uint_8 type:4;
      uint_8 system:1;
      uint_8 dpl:2;
      uint_8 present:1;
      uint_8 limit_high:4;
      uint_8 unused:2;
      uint_8 bitness:1;
      uint_8 granularity:1;
      uint_8 base_high;
   } entry_t;
   
   typedef struct __attribute__((packed))
   {
      uint_16 limit;
      uint_32 base;
   } gdtr_t;


And running this produces:
Quote:
00021334899i[CPU0 ] [21334899] Stopped on MAGIC BREAKPOINT
(0) Magic breakpoint
Next at t=21334899
(0) [0x00100064] 0008:00100064 (unk. ctxt): jmp far 0008:0010006b ; ea6b0010000800
<bochs:2> info gdt 0 2
Global Descriptor Table (base=0x00000017, limit=45088):
GDT[0x00]=Data segment, linearaddr=00f000ff, limit=f53f0 * 4Kbytes, Read/Write, Accessed
GDT[0x01]=16-Bit Trap Gate target=0x00fe:0x00e9a5f0, DPL=0
GDT[0x02]=Data segment, linearaddr=00f000ff, limit=f53f0 * 4Kbytes, Read/Write, Accessed


I was planning on waiting until I have all my current code working before importing it into a SVN repo. Should I do that now so you can see my code?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 8:16 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
Are you sure you are filling the structure out? The data doesn't even seem to change when you change to size of the structure. Also can you post the function that is supposed to fill out the GDTR structure?

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 8:21 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
I had this:
Code:
   entry_t gdt[3];
extern "C" gdtr_t gdtr = { (uint_32)&gdt[0], sizeof(gdt) - 1 };

(These are global variables btw, not declared in a function.)

But I started wondering why I had it declared as extern "C", removed that, and got this:
Quote:
<bochs:3> info gdt 0 2
Global Descriptor Table (base=0x00000017, limit=45088):
GDT[0x00]=Data segment, linearaddr=00f000ff, limit=f53f0 * 4Kbytes, Read/Write, Accessed
GDT[0x01]=16-Bit Trap Gate target=0x00fe:0x00e9a5f0, DPL=0
GDT[0x02]=Data segment, linearaddr=00f000ff, limit=f53f0 * 4Kbytes, Read/Write, Accessed
<bochs:4> c
00018291036e[CPU0 ] jump_protected: gate type 7 unsupported
00018291036i[CPU0 ] protected mode
00018291036i[CPU0 ] CS.d_b = 32 bit
00018291036i[CPU0 ] SS.d_b = 32 bit
00018291036i[CPU0 ] | EAX=00103008 EBX=00103008 ECX=00000000 EDX=000003d5
00018291036i[CPU0 ] | ESP=0010afac EBP=0010afd8 ESI=000247d8 EDI=00030658
00018291036i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00018291036i[CPU0 ] | SEG selector base limit G D
00018291036i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00018291036i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00018291036i[CPU0 ] | EIP=00100064 (00100064)
00018291036i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00018291036i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00018291036i[CPU0 ] >> jmp far 0008:0010006b : EA6B0010000800
00018291036e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00018291036i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00018291036i[APIC0] local apic in CPU 0 initializing
00018291036e[CPU0 ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=18291036
(0) [0x00100064] 0008:100064 (unk. ctxt): jmp far 0008:0010006b ; ea6b0010000800


Gate type 7? Um... why is it doing anything involving gates?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 8:45 pm 
Offline
Member
Member

Joined: Sat Dec 30, 2006 2:31 pm
Posts: 729
Location: East Coast, USA
I don't know this will help but try filling it out in a function.
Code:
void Init_GDTR( void )
{
   gdtr.limit = sizeof( gdt );
   gdtr.base = &gdt[0];

}


Well all of the errors are because either the GDTR is filled out incorrectly (just look at the base and limit in the bochs output) or the pointer that is passed to flush_gdt is incorrect.

_________________
My OS: Fuzzy Logic


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 08, 2007 8:50 pm 
Offline
Member
Member

Joined: Sat Jun 03, 2006 11:00 pm
Posts: 38
Still the gate type 7 message.

I'm going to take a short (couple of hours) break from OSDev for a few hours to do some web coding (for my OS's website of course :-), but please feel free to try to tell me wtf is going on :-)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 09, 2007 12:55 am 
Offline
Member
Member
User avatar

Joined: Tue Oct 17, 2006 11:33 pm
Posts: 3882
Location: Eindhoven
mmiikkee12 wrote:
I was planning on waiting until I have all my current code working before importing it into a SVN repo. Should I do that now so you can see my code?


It's advisable to check into a svn / cvs / something repo ASAP after you get one more feature working. You wouldn't be the first to have the just-not-working product remove half its source.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 09, 2007 1:51 am 
Offline
Member
Member
User avatar

Joined: Mon Jun 05, 2006 11:00 pm
Posts: 2293
Location: USA (and Australia)
mmiikkee12 wrote:
Poke.


I would have used pop. But then that'd mean all other threads after this would be deleted.

_________________
My OS is Perception.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 09, 2007 2:26 am 
Offline
Member
Member
User avatar

Joined: Tue Oct 17, 2006 11:33 pm
Posts: 3882
Location: Eindhoven
MessiahAndrw wrote:
mmiikkee12 wrote:
Poke.


I would have used pop. But then that'd mean all other threads after this would be deleted.


It's not a weasel. Use push.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot] and 43 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