Page 1 of 1
Pmode, what a surprise
Posted: Thu Jan 17, 2008 7:58 am
by Zacariaz
So i have been reading the osdev tut at brokenthorn.com but one i need answered.
Code: Select all
bits 16
org 0x7c00
start:
jmp loader
gdt_data:
dd 0 ; null descriptor
dd 0
; gdt code: ; code descriptor
dw 0FFFFh ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
; gdt data: ; data descriptor
dw 0FFFFh ; limit low (Same as code)10:56 AM 7/8/2007
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
end_of_gdt:
toc:
dw end_of_gdt - gdt_data - 1 ; limit (Size of GDT)
dd gdt_data ; base of GDT
loader:
xor ax, ax
mov ds, ax
mov es, ax
cli
lgdt [toc]
hlt
times 510 - ($-$$) db 0
dw 0xAA55
Does this actually put the computer in to 32bit pmode?
Yes i know a20 hasnt been enabled and all that, but from what ive read this is really all there is to it, when only considering entering 32bit pmode, and i find that very hard to believe.
Posted: Thu Jan 17, 2008 8:03 am
by AJ
Hi,
Yes - that's pretty much all there is to it.
As you say, you need to enable A20 and once you have done the jump to pmode you will need an IDT and TSS if you plan to handle interrupts / multitask, but all that is done once you are in PMode - run it in Bochs and you will notice that the final register dump will say 'Protected Mode'.
Cheers,
Adam
[EDIT]Damn - you aren't in PMode - you havent set the PE bit in CR0![/EDIT]
Posted: Thu Jan 17, 2008 8:09 am
by Zacariaz
ah! i knew there was something i had overlooked, ill be right back
Posted: Thu Jan 17, 2008 8:15 am
by Zacariaz
so the lines that are missing is:
Code: Select all
mov eax, cr0
or eax, 1
mov cr0, eax
and then it should be in 32bit pmode, allthough with messed up segmentregister and no a20.
Correct?
edit: You know youre in pmode when you triplefault as you re-enable interrupts
Posted: Thu Jan 17, 2008 8:47 am
by cyr1x
AFAIK you also need to do a far-jump
e.g.
Code: Select all
jmp 0x08(or some other codesegment):somelocation
Posted: Thu Jan 17, 2008 9:13 am
by neon
Hey,
While the code is correct, it does not touch pmode at all. You need to set the PMode bit in cr0 to enter protected mode. From here, CS will still contain the segment value (Probably still 0x7c0), which is bad. Because of this, you need to reset CS to your code descriptor offset (0x8) by far jumping:
Code: Select all
; make sure to disable interrupts before entering pmode, and do not
; re-enable them until you have a valid IDT.
cli
mov eax, cr0
or eax, 1
mov cr0, eax
; we are now in pmode. Far jump to reset CS
jmp 0x8:Stage3
bits 32
Stage3:
; Welcome to 32bit world
Also, you dont *need* a20 to enter protected mode, however it is recommended.
Posted: Thu Jan 17, 2008 12:05 pm
by Zacariaz
is there a difference between enabling A20 before and after Pmode?
Here is the code so far:
Code: Select all
bits 16
org 0x7c00
start:
jmp stage1
gdt_data:
dd 0 ; null descriptor
dd 0
; gdt code: ; code descriptor
dw 0FFFFh ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
; gdt data: ; data descriptor
dw 0FFFFh ; limit low (Same as code)10:56 AM 7/8/2007
dw 0 ; base low
db 0 ; base middle
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
end_of_gdt:
toc:
dw end_of_gdt - gdt_data - 1 ; limit (Size of GDT)
dd gdt_data ; base of GDT
stage1:
xor ax, ax
mov ds, ax
mov es, ax
cli
lgdt [toc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x8:stage2
stage2:
hlt
times 510 - ($-$$) db 0
dw 0xAA55
Posted: Thu Jan 17, 2008 1:09 pm
by lukem95
if you enter it before i believe you are entering unreal mode briefly, although i dont think this matters.
also i've seen code that does both, i dont think there is a difference.
Posted: Thu Jan 17, 2008 3:53 pm
by neon
There is no difference.
The only thing wrong with the code is the exclusion of bits 32. (Please see my previous example.) Everything else looks fine.
Posted: Thu Jan 17, 2008 6:19 pm
by bewing
And, of course, once you are in PMODE, the BIOS no longer works. So you can't read anything else into memory with an INT command. So, unless you have all your data, or a disk driver in memory, you're stuck at that point.
And, of course, you really want to gather all the BIOS info that you can, before that point ... especially regarding memory and VBE info (and maybe PCI, and floppy, and etc. too).
Posted: Fri Jan 18, 2008 12:18 am
by Zacariaz
for now im just interested in getting into long mode (while understanding the process). I dont intent to make anything that should be able to run on other than my own machine (and qemu) which shouldnt be a problem.
Thus, i dont need to get the size of the memory as i always know it. Nor do i need any info about pci or anything else. Well, i need to read/write the disk (usb or hdd or maybe even lan, but i dont believe ill be able to do the usb/lan stuff) but ill take that up later when i understand the process better.
And kudos to brokenthorn.com, its really an amazing os tut.
Posted: Fri Jan 18, 2008 2:40 am
by AJ
Hi,
There is a difference between enabling A20 before or after you enter PMode. Because of the way the address lines are wired up, I believe that some systems prevent you accessing every other MiB if you don't enable it before you go to PMode (you can't access 2-3Mib, 4-5Mib etc...). Someone else may be able to furnish you with the details of this, but it's safer to enable A20 first.
Cheers,
Adam
Posted: Fri Jan 18, 2008 5:38 am
by Zacariaz
thats good to know.
Posted: Fri Jan 18, 2008 7:13 pm
by bewing
I'm not sure about qemu, but bochs always has the A20 line enabled. You do not have to do it yourself in bochs. Your PC may be the same. Just for fun, here is my A20 code.
(Written for NASM. Public domain. Interrupts need to be off, I think. It compiles, and should run fine. It needs timeouts in all the wait loops, of course.)
Posted: Mon Jan 21, 2008 11:29 am
by sancho1980
lukem_95 wrote:if you enter it before i believe you are entering unreal mode briefly, although i dont think this matters.
also i've seen code that does both, i dont think there is a difference.
AFAIK, unreal mode is when you enter pm, set your segments' bases to 0 and their limits to maximum and then return to real mode, so that you can address you full memory in real mode (which makes it so "UN"real)