Page 1 of 2

mode switch

Posted: Fri Oct 10, 2008 4:59 pm
by mobruan
hi, i wrote the following and the computer resets:

mov ax, word 0x0000
mov ds, ax
mov [528], word 0xffff
mov [530], word 0x0000
mov [532], byte 0x00
mov [533], byte 0x9a
mov [534], byte 0xcf
mov [535], byte 0x00

mov [536], word 0xffff
mov [538], word 0x0000
mov [540], byte 0x00
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov [1000], word 23
mov [1002], word 520
mov [1004], word 0x0000


cli
lidt [1000]
mov eax,cr0
or al,0x01
mov cr0,eax

jmp 1:pm

jmp $

bits 32

pm:

mov ax, 0xb800
mov ds, ax


mov [0x0000], byte 0x61
mov [0x0001], byte 01110010b

jmp $

it supposed to switch to protected mode.
thanks

Re: mode switch

Posted: Fri Oct 10, 2008 5:27 pm
by neon

Code: Select all

jmp 1:pm
This is bad. PMode uses selector:offset addressing, where the selector is an offset into the GDT you set up. In your case, it is at offset 8 from the base of the GDT.

Also, the null selector in the GDT is not ignored--it must be 0.

Also, your GDT is not properly installed anyways. You need to properly install your GDT into the GDTR in order for it to be used. I think you meant to do this (Its LGDT not LIDT instruction)

Re: mode switch

Posted: Fri Oct 10, 2008 5:56 pm
by ru2aqare
neon wrote:Also, the null selector in the GDT is not ignored--it must be 0.
As far as I know, the processor handles descriptor zero as an ordinary descriptor. It is only a custom that the descriptor is left empty. I saw a protected mode tutorial somewhere that used it to access the GDT itself.
mobruan wrote:

Code: Select all

jmp 1:pm
pm:
mov ax, 0xb800
mov ds, ax
You need to load a valid selector into ds. Real-mode segments wouldn't work even if you got through the far jump to protected mode, which in itself is incorrect. Hint:

Code: Select all

mov ax, 8*2
mov ds,ax
Anyway, why are you intent on using magic numbers instead of symbolic constants and labels?

Re: mode switch

Posted: Fri Oct 10, 2008 6:35 pm
by neon
ru2aqare wrote:As far as I know, the processor handles descriptor zero as an ordinary descriptor. It is only a custom that the descriptor is left empty. I saw a protected mode tutorial somewhere that used it to access the GDT itself.
You are right--According to the i86 manuals it doesnt matter what it contains as it is never used by the processor. Thanks for correcting :)

The manuals state that the processor will always #GPF in any case if the null descriptor is used (3.5.1 p 3-21). Thus I wouldnt consider it a normal descriptor.

Re: mode switch

Posted: Sat Oct 11, 2008 4:31 am
by mobruan
Hi, the code is like this and still resets:

mov ax, word 0x0000
mov ds, ax

mov [520], word 0x0000
mov [522], word 0x0000
mov [524], byte 0x00
mov [525], byte 0x00
mov [526], byte 0x00
mov [527], byte 0x00

mov [528], word 0xffff
mov [530], word 0x0000
mov [532], byte 0x00
mov [533], byte 0x9a
mov [534], byte 0xcf
mov [535], byte 0x00

mov [536], word 0xffff
mov [538], word 0x0000
mov [540], byte 0x00
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov [1000], word 23
mov [1002], word 520
mov [1004], word 0x0000


cli
lgdt [1000]
mov eax,cr0
or al,0x01
mov cr0,eax

jmp 8:pm

jmp $

bits 32

pm:

mov ax, 8*2
mov ds,ax

jmp $

have i to set a tss?
thanks

Re: mode switch

Posted: Sat Oct 11, 2008 4:59 am
by CodeCat
neon wrote:The manuals state that the processor will always #GPF in any case if the null descriptor is used (3.5.1 p 3-21). Thus I wouldnt consider it a normal descriptor.
Wouldn't that be because of the fact that the descriptor is all-zeroes rather than because it's the first descriptor in the GDT? I always thought that the null descriptor was just there to detect when a segment register got set to 0 accidentally.

Re: mode switch

Posted: Sat Oct 11, 2008 6:10 am
by Brendan
Hi,
CodeCat wrote:
neon wrote:The manuals state that the processor will always #GPF in any case if the null descriptor is used (3.5.1 p 3-21). Thus I wouldnt consider it a normal descriptor.
Wouldn't that be because of the fact that the descriptor is all-zeroes rather than because it's the first descriptor in the GDT?
No, it's because it's the NULL descriptor.

The first 8 bytes of the GDT could be used for any purpose; and the first 8 bytes don't even need to exist (for e.g. you could safely load the GDTR with "base = 0x000FFFF8", so that the second GDT entry begins at address 0x0100000 and the first GDT descriptor is actually in ROM).

I typically store the pointer to the GDT in the first GDT entry, so that I can do "lgdt [GDTaddress]" (or "lgdt [GDTaddress + 2]" for better alignment).

Also note that the NULL descriptor is given other special treatment by the CPU, like any code at any privilege level can always load any data segment with zero.


Cheers,

Brendan

Re: mode switch

Posted: Sat Oct 11, 2008 6:21 am
by i586coder
there is more cleaner methods to enter protected mode :wink:

you need to set GDT,IDT,..., well before jump to protected mode

this link realy good about protected mode,.., take spin around

http://members.tripod.com/protected_mode/

good luck :mrgreen:

Re: mode switch

Posted: Sat Oct 11, 2008 8:50 am
by neon
Wouldn't that be because of the fact that the descriptor is all-zeroes rather than because it's the first descriptor in the GDT?
No. The descriptor can contain valid values as well--it doesnt matter as the processor will still generate a #GPF if it is used in any case.
Hi, the code is like this and still resets:
Post your error log from bochs.

Re: mode switch

Posted: Sat Oct 11, 2008 10:38 am
by mobruan
Hi, this code dont reset, but it dont print on screen, whats wrong? Is it enter im pm mode?

ORG 0x00000000

jmp start

bits 32

pm:

mov ax, 8*2
mov ds,ax

mov ax, word 0x20
mov es, word ax

es mov [0x0000], byte 0x61
es mov [0x0001], byte 01110010b


start:
mov ax, word 0x0000
mov ds, ax

mov [520], word 0x0000
mov [522], word 0x0000
mov [524], byte 0x00
mov [525], byte 0x00
mov [526], byte 0x00
mov [527], byte 0x00

mov [528], word 0xffff
mov [530], word 0x0000
mov [532], byte 0x00
mov [533], byte 0x9a ;1 000
mov [534], byte 0xcf
mov [535], byte 0x00

mov [536], word 0xffff
mov [538], word 0x0000 ; 10 000
mov [540], byte 0x00
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov [544], word 0x67
mov [546], word 1544 ;tss descriptor
mov [548], byte 0 ; 11 000
mov [549], byte 10001011b
mov [550], byte 10000000b
mov [551], byte 0

mov [536], word 0xffff
mov [538], word 0x8000 ;display seg
mov [540], byte 0x0b ; 100 000
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov ax, word 0x18
ltr ax

o32 mov [1544], dword 0x00000000 ;link
o32 mov [1548], dword 5000 ;esp 0
o32 mov [1552], dword 0x10 ;ss0
o32 mov [1556], dword 0 ;esp1
o32 mov [1560], dword 0 ;ss1
o32 mov [1564], dword 0 ;esp2
o32 mov [1568], dword 0 ;ss2
o32 mov [1572], dword 0 ;8 cr3
o32 mov [1576], dword 0 ;eip
o32 mov [1580], dword 0 ;eflags
o32 mov [1584], dword 0 ;eax
o32 mov [1588], dword 0 ;ecx
o32 mov [1592], dword 0 ;edx
o32 mov [1596], dword 0 ;ebx
o32 mov [1600], dword 0 ;esp
o32 mov [1604], dword 0 ;ebp
o32 mov [1608], dword 0 ;esi
o32 mov [1612], dword 0 ;edi
o32 mov [1616], dword 0 ;es
o32 mov [1620], dword 8 ;cs
o32 mov [1624], dword 10 ;ss
o32 mov [1628], dword 10 ;ds
o32 mov [1632], dword 0 ;fs
o32 mov [1636], dword 0 ;gs
o32 mov [1640], dword 0 ;ldt
o32 mov [1644], dword 0 ;io


mov [1000], word 31
mov [1002], word 520
mov [1004], word 0x0000


cli
lgdt [1000]
mov ax, word 0x18
ltr ax
mov eax,cr0
or al,0x01
mov cr0,eax

jmp 0x18:0000

;jmp $

Re: mode switch

Posted: Sat Oct 11, 2008 11:56 am
by neon
A tss isn't required for protected mode. Also, because you are entering protected mode I am assuming you are developing your own bootloader? If so, then you are missing quite a bit of other things needed to boot it.

I have created a working version of your code but I am considering if I should post it or not. There are alot of issues with your current code that can cause problems on real machines even if we get it working in Bochs. I highley recommend rewriting your code from scratch following the suggestions posted by AhmadTayseerDajani.

If you still wish to continue, feel free to ask and I will post the fixed version.

Re: mode switch

Posted: Sat Oct 11, 2008 12:46 pm
by mobruan
Hi, you can post!

Re: mode switch

Posted: Sat Oct 11, 2008 4:06 pm
by mobruan
Hi, i put a idt but still do nothing...any ideia?
thanks

ORG 0x00000000

start:
mov ax, word 8192
mov ds, ax

mov [520], word 0x0000
mov [522], word 0x0000
mov [524], byte 0x00
mov [525], byte 0x00
mov [526], byte 0x00
mov [527], byte 0x00

lea ax, [pm]

mov [528], word 0xffff
mov [530], word ax
mov [532], byte 0x00
mov [533], byte 0x9a ;1 000 code
mov [534], byte 0xcf
mov [535], byte 0x00

mov [536], word 0xffff
mov [538], word 0x8192 ; 10 000 data
mov [540], byte 0x00
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov [544], word 0x67
mov [546], word 9736 ;tss descriptor
mov [548], byte 0 ; 11 000
mov [549], byte 10001011b
mov [550], byte 10000000b
mov [551], byte 0

mov [536], word 0xffff
mov [538], word 0x8000 ;display seg
mov [540], byte 0x0b ; 100 000
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

;mov ax, word 0x18
;ltr ax

o32 mov [1544], dword 0x00000000 ;link
o32 mov [1548], dword 5000 ;esp 0
o32 mov [1552], dword 0x10 ;ss0
o32 mov [1556], dword 0 ;esp1
o32 mov [1560], dword 0 ;ss1
o32 mov [1564], dword 0 ;esp2
o32 mov [1568], dword 0 ;ss2
o32 mov [1572], dword 0 ;8 cr3
o32 mov [1576], dword 0 ;eip
o32 mov [1580], dword 0 ;eflags
o32 mov [1584], dword 0 ;eax
o32 mov [1588], dword 0 ;ecx
o32 mov [1592], dword 0 ;edx
o32 mov [1596], dword 0 ;ebx
o32 mov [1600], dword 0 ;esp
o32 mov [1604], dword 0 ;ebp
o32 mov [1608], dword 0 ;esi
o32 mov [1612], dword 0 ;edi
o32 mov [1616], dword 0 ;es
o32 mov [1620], dword 8 ;cs
o32 mov [1624], dword 10 ;ss
o32 mov [1628], dword 10 ;ds
o32 mov [1632], dword 0 ;fs
o32 mov [1636], dword 0 ;gs
o32 mov [1640], dword 0 ;ldt
o32 mov [1644], dword 0 ;io


mov [1000], word 31
mov [1002], word 8712
mov [1004], word 0x0000 ;gdt base

mov [1200], word 0x0000
mov [1202], word 0x8
mov [1204], byte 0x00
mov [1205], byte 10001110b ;interrupt descriptor
mov [1206], word 0x0000

mov [1006], word 31
mov [1008], word 9384 ;idt base
mov [1010], word 0


cli
lgdt [1000]
mov ax, word 0x18
ltr ax
mov eax,cr0
or al,0x01
mov cr0,eax

jmp 0x18:pm

bits 32

pm:

mov ax, 8*2
mov ds,ax

mov ax, word 0x20
mov es, word ax

es mov [0x0000], byte 0x61
es mov [0x0001], byte 01110010b

lidt[9198]

int 1

Re: mode switch

Posted: Sat Oct 11, 2008 4:51 pm
by mobruan
Hi, i found a error: i forgot the sti command before de int.
I was testing the program and realize if the ltr is after the mov cro the computer resets.
thanks, and now?

Re: mode switch

Posted: Sat Oct 11, 2008 6:37 pm
by neon
thanks, and now?
Rewrite it. I highly recommend it.

Assuming this is a boot loader, this is your modified code that works in Bochs. It displays an 'A' character on the top left corner of the screen in protected mode.

Please note that this code is being based off of your (horrific) code and can be written much much cleaner and more efficiently .

Code: Select all

bits 16
org 0x7c00

jmp main

bpbOEM			DB "MOS     "
bpbBytesPerSector:  	DW 512
bpbSectorsPerCluster: 	DB 1
bpbReservedSectors: 	DW 1
bpbNumberOfFATs: 	DB 2
bpbRootEntries: 	DW 224
bpbTotalSectors: 	DW 2880
bpbMedia: 		DB 0xf0
bpbSectorsPerFAT: 	DW 9
bpbSectorsPerTrack: 	DW 18
bpbHeadsPerCylinder: 	DW 2
bpbHiddenSectors: 	DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber: 	        DB 0
bsUnused: 		DB 0
bsExtBootSignature: 	DB 0x29
bsSerialNumber:	        DD 0xa0a1a2a3
bsVolumeLabel: 	        DB "MOS FLOPPY "
bsFileSystem: 	        DB "FAT12   "

main:

mov ax, word 0x0000
mov ds, ax

mov [528], word 0xffff
mov [530], word 0x0000
mov [532], byte 0x00
mov [533], byte 0x9a
mov [534], byte 0xcf
mov [535], byte 0x00

mov [536], word 0xffff
mov [538], word 0x0000
mov [540], byte 0x00
mov [541], byte 0x92
mov [542], byte 0xcf
mov [543], byte 0x00

mov [1000], word 23
mov [1002], word 520
mov [1004], word 0x0000

cli
lgdt [1000]
mov eax,cr0
or al,0x01
mov cr0,eax

jmp 8:pm

jmp $

bits 32

pm:

mov ax, 8*2
mov ds,ax

mov [0xb8000], byte 'A'
mov [0xb8001], byte 0x17

jmp $

TIMES 510-($-$$) DB 0
DW 0xaa55