Page 1 of 1

Enter PM--"Bochs:using of nonexisting segment register&

Posted: Thu Jan 12, 2006 1:22 am
by raywill
I am rewriting my bootloader.
I have found that mixing 16 bits and 32bits codes in my kernel is really a nightmare.So I tried to enter PM in my Bootloader.
But I encountered some "interesting" problem:

This is my GDT:

Code: Select all

;;;;;;;;GDT Table Begin;;;;;;;;;;;;;;
         fake_gdt:
          fake_gdt_null:
            dd   0
            dd   0
          fake_gdt_data_addr   equ $- fake_gdt
          fake_gdt_data:
             dw   0xffff
            dw   0
            db   0
            db   10010010b   ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,2:data seg,read and write.
            db   11001111b   ;(7)limit len,0:1 byte,1:4K,(6)B bit,control stack,B=1,use esp,B=0,use sp,(5-4) reserved,(3-0)seg limit 19-16.
            db   0
          fake_gdt_code_addr   equ $-fake_gdt
          
          fake_gdt_code:
             dw   0xffff
            dw   0
            db   0
            db   10011010b   ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,10:code seg,execute and read.
            db   11001111b
            db   0
                  
         fake_gdt_end:
          fake_gdt_addr:
             dw   fake_gdt_end - fake_gdt - 1   ;gdt total length,here it contains 3 item
            dd   fake_gdt      ;gdt start address
;;;;;;;;GDT Table End;;;;;;;;;;;;;;
Here is the code to enable A20 and jump to kernel:

Code: Select all

   lgdt   [fake_gdt_addr]
; Set PE bit
   mov   eax,cr0
   or   eax,1
   mov   cr0,eax
; enable A20 gate
   in al, 92h
   or al, 00000010b
   out 92h, al
   
;set data segments   
   mov   ax,8   ;ds selector
   mov   ds,ax
   mov es,ax
   mov fs,ax
   mov gs,ax
   mov ss,ax
;jump to kenel,which loaded at 0x9000,in absolute address
   jmp 0x10:0x9000     ;cs=0x10=10 000b
;===================================================================

But in Bochs I got the follow error report:

Code: Select all


00000809157i[CPU0 ] MOV_EwSw: using of nonexisting segment register
00000809157e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00000809157i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called

Anything wrong with my jump instruction?
I am really confused :(

Re:Enter PM--"Bochs:using of nonexisting segment regist

Posted: Thu Jan 12, 2006 1:41 am
by durand
Your far jmp should come immediately after you've enabled the A20 and you should do a far jump to a 32 bit segment. Only once you're in the 32 bit segment should you flush all your data segments.

Right now you're still trying to flush the data segments in 16 bit mode which means you're attempting to use some registers which don't exist in 16 bit.


There was a thread a few days ago which had the exact steps required and in order:

http://www.mega-tokyo.com/forum/index.php?board=1;action=display;threadid=8866

Re:Enter PM--"Bochs:using of nonexisting segment regist

Posted: Thu Jan 12, 2006 1:50 am
by durand
Just to further demonstrate what I mean, something like this...

Code: Select all

; enable A20 gate
   in al, 92h
   or al, 00000010b
   out 92h, al

; far jump to a 32 bit segment in order to flush CS
   jmp 0x10, 32bit_jump

[code32] or [bits 32] or .code32 or [whatever your assembler needs to identify 32 bit code]

32bit_jump:   

;set data segments   
   mov   ax,8   ;ds selector
   mov   ds,ax
   mov es,ax
   mov fs,ax
   mov gs,ax
   mov ss,ax

;jump to kenel,which loaded at 0x9000,in absolute address
   jmp 0x10:0x9000     ;cs=0x10=10 000b

My syntax might be wrong so I don't expect it to work or anything, just explain a point.

Re:Enter PM--"Bochs:using of nonexisting segment regist

Posted: Thu Jan 12, 2006 3:32 am
by Pype.Clicker
that bochs error message suggests me your GDT hasn't been properly set up.

Bochs should be printing a crash report full of register state ... locate GDTR info there and cross-check it contains what's expected.

If you have a debugger-enabled version of bochs, you can also issue the "dump-cpu" command and see from there

typical output from real mode:

Code: Select all

<bochs:4> dump_cpu
eax:0x2400
...
esp:0x1fec
eflags:0x246
eip:0x80c9
cs:s=0x0, dl=0xffff, dh=0x9b00, valid=1
ss:s=0x0, dl=0xffff, dh=0x9300, valid=7
ds:s=0x7000, dl=0xffff, dh=0x9307, valid=3
...
gdtr:base=0x0, limit=0xffff
idtr:base=0x0, limit=0xffff
and typical output from protected mode (no IDT defined):

Code: Select all

<bochs:6> dump_cpu
eax:0x0
...
esp:0x1fda
eflags:0x46
eip:0xe865
cs:s=0xf000, dl=0xffff, dh=0x9b0f, valid=1
ss:s=0x0, dl=0xffff, dh=0x9300, valid=7
ds:s=0x40, dl=0x400ffff, dh=0x9300, valid=3
...
gdtr:base=0x8f84, limit=0x27
idtr:base=0x0, limit=0xffff