Stumped on entering 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
Warthog
Posts: 6
Joined: Fri Apr 23, 2010 11:33 pm

Stumped on entering protected mode

Post by Warthog »

I've been stumped for a while now trying to get from real mode to protected mode.
Hoping an expert can help me get through this, or give me a tip on what to look at.

I can set bit 0 in CR0, to and I've setup a GDT and loaded the GDT register, but when I try to do an LJMPL, I never get there.

Using qemu, I'm putting a breakpoint right before the ljmpl and going into gdb. GDB shows the next instruction is:
(gdb) x/1i $eip
0x106b: ljmpl $0x8,$0x1400
And, there's a legal instruction at the address I'm trying to jump to:
(gdb) x/1i 0x1400
0x1400: xor %ax,%ax
Going into the qemu console, my registers look are:
GDT=0000108e 0000000f
IDT=00000000 000003ff
LDT=00000000 0000ffff
CR0=00000011
ES=0008
CS=0000
SS=08e0
DS=0008
FS=0008
GS=0008
Dumping the memory with my GDT shows:
(gdb) x/16bx 0x108e
0x108e: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x1096: 0xff 0xff 0x00 0x00 0x00 0x92 0xcf 0x00
If I step an instruction, gdb hangs, and when I go to the qemu console to show my registers, protected mode has been disabled and my IP is off who-knows-where.

I'm sort of stumped on where I'm going wrong. Any clues to help me figure this out?

Thanks!
Chris
Warthog
Posts: 6
Joined: Fri Apr 23, 2010 11:33 pm

Re: Stumped on entering protected mode

Post by Warthog »

I should probably have included the whole register set. In case it helps, here it is:
(qemu) info registers
EAX=00000011 EBX=00000008 ECX=00000001 EDX=00000001
ESI=00000433 EDI=0000dead EBP=00000000 ESP=00001000
EIP=0000106b EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0008 00000080 0000ffff 00009300 DPL=0 DS16 [-WA]
CS =0000 00000000 0000ffff 00009b0f DPL=0 CS16 [-RA]
SS =08e0 00008e00 0000ffff 00009300 DPL=0 DS16 [-WA]
DS =0008 00000080 0000ffff 00009300 DPL=0 DS16 [-WA]
FS =0008 00000080 0000ffff 00009300 DPL=0 DS16 [-WA]
GS =0008 00000080 0000ffff 00009300 DPL=0 DS16 [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 0000108e 0000000f
IDT= 00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
(qemu)
TylerH
Member
Member
Posts: 285
Joined: Tue Apr 13, 2010 8:00 pm
Contact:

Re: Stumped on entering protected mode

Post by TylerH »

Is there anything to stop from executing all valid instructions then continuing into data/random crap? I thought I had a problem for a long time because all my normal code would execute like it should until where I should have put an infinite loop or a halt, it would attempt to execute my data causing all sorts of weird errors. Try replacing xor ax,ax with an infinite loop to see if you still get an error.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Stumped on entering protected mode

Post by Owen »

It strikes me that your GDT's limit is 0xf, or 16 bytes. That, do me, looks wrong; I would expect it to be at least 24 in the form (Null - CS - DS).

Judging by your segment registers, you have already loaded all but SS with 0x8, which means that the second entry is a data descriptor (Else the load would have failed). You then attempt to do a far jump to a data descriptor, which won't work. (This is just an educated guess - but you don't often see use of real mode segment 0x8 ;-))

My psychic debugging skills tell me that the processor then raises a general protection fault exception, and all hell breaks loose because it is misinterpreting the real mode IVT as an IDT. The system then rapidly double faults and triple faults, and QEMU should then complain loudly. Protected mode is disabled because the emulator is prepared to reset.
Warthog
Posts: 6
Joined: Fri Apr 23, 2010 11:33 pm

Re: Stumped on entering protected mode

Post by Warthog »

Aha! That was it - once I added a second GDT descriptor and set it up correctly it worked like a charm.

Strangely, qemu doesn't seem to complain to me if I get a double/triple fault. Not sure why that is - more likely I haven't enable some sort of option or am not looking at the right output. But anyway, main problem solved.

Thanks for your help!
Post Reply