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
Help! I can't enter PMode
Re:Help! I can't enter PMode
How is this code being executed? What loads and calls it?
Re:Help! I can't enter PMode
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
[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
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Help! I can't enter PMode
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
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
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
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
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
Hi,
Cheers,
Brendan
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.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.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.