Page 1 of 1

Help! I can't enter PMode

Posted: Sun Jul 18, 2004 9:22 pm
by chen17981
Hi,everyone. I am very confused that I cannot enter the Pmode, and when i use boches to debug, the limit of GDT could not be loaded. Could anyone help me?

[bits 16]
[org 0x9000]
jmp Begin

gdtr:   dw gdt_end - gdt - 1    ; GDT limit
   dd gdt         ; linear, physical
; address of GDT

;------------GDT Table---------------;
; null descriptor
gdt:   dw 0         ; limit 15:0
   dw 0         ; base 15:0
   db 0         ; base 23:16
   db 0         ; type
   db 0         ; limit 19:16, flags
   db 0         ; base 31:24

; linear data segment descriptor
LINEAR_SEL   equ   $-gdt
   dw 0xFFFF      ; limit 0xFFFFF
   dw 0         ; base 0
   db 0
   db 0x92          ; present, ring 0, data,
; expand-up, writable
db 0xCF ; page-granular, 32-bit
   db 0

; code segment descriptor
SYS_CODE_SEL   equ   $-gdt
gdt2: dw 0xFFFF ; limit 0xFFFFF
   dw 0         ; (base gets set above)
   db 0
   db 0x9A         ; present, ring 0, code,
; non-conforming,
; readable
db 0xCF ; page-granular, 32-bit
   db 0

; data segment descriptor
SYS_DATA_SEL   equ   $-gdt
gdt3: dw 0xFFFF ; limit 0xFFFFF
   dw 0         ; (base gets set above)
   db 0
   db 0x92         ; present, ring 0, data,
; expand-up, writable
db 0xCF ; page-granular, 32-bit
   db 0
gdt_end:
;----------End GDT Table-------------;
Begin:   
   cli
   xor ebx,ebx
   mov bx,cs       ; BX=segment
   shl ebx,4       ; EBX=linear
; address of
; segment base
   mov eax,ebx
   mov [gdt2 + 2],ax ; set base
; address of 32-
; bit segments
   mov [gdt3 + 2],ax
   
   shr eax,16
   mov [gdt2 + 4],al
   mov [gdt3 + 4],al
   
   mov [gdt2 + 7],ah
   mov [gdt3 + 7],ah
   
lea eax,[gdt + ebx] ; EAX=PHYSICAL
;address of gdt
mov [gdtr + 2],eax
lgdt [gdtr]       ;load GDT to GDTR

;Enter PMode

   mov eax,cr0
   inc ax
   mov cr0,eax


jmp dword SYS_CODE_SEL:FLUSH


[bits 32]
FLUSH:
   mov ax,LINEAR_SEL
   mov es,ax
   mov byte [es:dword 0xB8008],'5' ;Indicate that
; now I am in
; the PMode
      
hlt

Re:Help! I can't enter PMode

Posted: Mon Jul 19, 2004 12:09 am
by Dreamsmith
How is this code being executed? What loads and calls it?

Re:Help! I can't enter PMode

Posted: Mon Jul 19, 2004 1:16 am
by chen17981
sorry, I forgot to post the boot.asm,following is the code. When I load the second,third and fourth secotor from floopy to 0x90000, then jmp to the address.

[bits 16]
[org 0x7c00]

read:
xor ax,ax ;Reset the floppy
mov dl,0x0 ;floppy A=0, DISK C=80H
int 0x13
jc read ;if error,set CF

mov ax,0x9000
mov es,ax ; Data buffer for file
mov bx,0x00 ; Start of segment
mov ah,2     ; Function to read disk
mov al,3 ; Total sectors to read
mov ch,0 ; Track
mov cl,2 ; Sector
mov dh,0 ; Head | Drive is already loaded
int 0x13 ; Call BIOS read disk function
jc read     ; motor error, try again

kill_motor:
push dx
mov dx,0x3f2 ;stop the motor
mov al,0x0c ;from spinnign
out dx,al

jmp 0x9000:0x0
TIMES 510-($-$$) DB 0

SIGNATURE DW 0xAA55

Re:Help! I can't enter PMode

Posted: Mon Jul 19, 2004 1:47 am
by Pype.Clicker
ORG 0x9000 simply will not work with ES=9000. What you'd need is "ORG 0x90000", but the assembler will refuse that in real mode.

You should either load your rmode-to-pmode stuff below 64K so that you can use "ORG ..." and remain in segment 0 or stick with ES=9000, use ORG 0 and adjust the value stored in GDTR.base so that it reflects the *real* address of the GDT (not the offset within some segment).

HTH

Re:Help! I can't enter PMode

Posted: Mon Jul 19, 2004 10:16 am
by Dreamsmith
Yes, looking at the first bit of code, I thought it might be something like that. You're setting up your code segment with a base pointer of 0x90000, which is also your load address, so that means the logical address of your code is 0. However, at the very start of your file, you're declaring the logical address of your code as 0x9000 instead of 0. You don't NEED to load in the first 64K or memory, but if you don't, you need to be much more cognizant of the differences between your logical and physical addresses.

Re:Help! I can't enter PMode

Posted: Tue Jul 20, 2004 1:48 am
by chen17981
Thank you, nice guys. I have modified my code to retry. I use bochs to debug my code, and found that the value of DS is the problem. If I do not set DS=0x9000, I still cannot enter the Pmode. When I set the value to DS, NO PROBLEM.

Could anyone tell me the difference? I think that it is due to the proceesor which must use ds to access my data.

Following is my changed code:
[org 0x0]
cli
   xor ebx,ebx
   mov ax,0x9000
   mov ds,ax ;NEW ADD
   mov bx,ds       ; BX=segment
   shl ebx,4       ; EBX=linear addr
   mov eax,ebx
   mov [gdt2 + 2],ax
   mov [gdt3 + 2],ax
   
   shr eax,16
   mov [gdt2 + 4],al
   mov [gdt3 + 4],al
   
   mov [gdt2 + 7],ah
   mov [gdt3 + 7],ah
   
lea eax,[gdt]
add eax,ebx
mov [gdtr + 2],eax
lgdt [gdtr]        ;load GDT to GDTR

Re:Help! I can't enter PMode

Posted: Tue Jul 20, 2004 2:18 am
by Brendan
Hi,
chen17981 wrote: Could anyone tell me the difference? I think that it is due to the proceesor which must use ds to access my data.
It is. All instructions that refer to memory use a default segment register (unless you specify a specific segment with a segment override prefix). For most instructions the default segment register is DS, but if the instruction uses BP, SS, EBP or ESP then the default segment register is SS. The only exceptions are the string instructions that write to memory (stosd/stosw/stosb, movsd/movsw/movsb, insd/insw/insb). These instructions always use ES for the destination, which can't be changed by a segment override prefix.


Cheers,

Brendan

Re:Help! I can't enter PMode

Posted: Tue Jul 20, 2004 2:38 am
by chen17981
Thank you for your message.