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)