Page 1 of 1

Problems with PMode

Posted: Thu Jul 11, 2013 9:33 am
by danielbj
First of all: Yes, there are LOTS of threads around here about problems with PMode. After searching and reading and testing and debugging, I can't find a solution to my problem.

I have written a smal real mode OS before, and decided some months ago to start over, and go to Protected Mode. After months of reading about PMode, and planning the system architecture accordningly, I felt ready to start what some people describe as an adventurous journey into the land of protected mode.

However, despite being described many a place as a simple thing to do, I cannot enable the magic 0th bit of CR0.

I have tried almost everything I can come up with: My code is still in its simplest stage, so theres not too many things to bug the system.

I know this may sound annoying: But here's my code. If you would take a really quick look at it, you might be able to spot what I have stared myself blind at.

I really appreciate all kinds of hints to what may be causing me trouble for longer time than it takes to read the complete Intel manual hundreds of times.

Here comes the code and system status:

Code: Select all

;This is the start of the boot sequence. It is loaded by the bootloader to 0x8000.
;After this (still in real mode) my kernel (A set of system calls) and the complete IDT is loaded to 0x00030000 and 0x0004000 respectively.
;Right after this, a jump is performed to the tricky bit:

enterpmode:



;Clear interrupt flag
	cli

;Enable A20
	in al, 0x92
	or al, 00000010b
	out 0x92, al

;Get memory size
	mov ah, 0x88
	int 0x15
	jc error_rmode
	;ax=Contiguous KB starting at 0x00100000
	shr ax, 0x06
	;ax=Contiguous 64KB blocks starting at 0x00100000
	add ax, 0x10
	;ax=Contiguous 64KB blocks starting at 0x00000000
	
	;Store for later use
	mov [mem_size], ax
	jmp @f
	mem_size: dw 0x0000
	@@:








;Set up the three first GDT entries (NULL, K_CODE, K_DATA)
	mov cx, gdt_template
	mov dx, 0x0000;Table start offset
	mov ax, 0x5000;Table start segment
	mov es, ax
	@@:
	cmp cx, gdt_template_end
	jae gdt_template_end
	mov bx, cx
	mov al, [bx]
	mov bx, dx
	mov [es:bx], al
	inc cx
	inc dx
	jmp @b

gdt_template:;these entries have been checked more times than humanly possible in two months.
;NULL
dw 0x0000;limit low
dw 0x0000;base low
db 0x00;base middle
db 00000000b;access
db 00000000b;flags/limit high
db 0x00;base high

;K_CODE:
dw 0xffff;limit low
dw 0x0000;base low
db 0x00;base middle
db 10011010b;access
db 11001111b;flags/limit high
db 0x00;base high

;K_DATA:
dw 0xffff;limit low
dw 0x0000;base low
db 0x00;base middle
db 10010010b;access
db 11001111b;flags/limit high
db 0x00;base high
gdt_template_end:



;Load GDT (BASE=0x00050000 SIZE=0xffff)
	lgdt [gdtr_template]
	jmp @f

gdtr_template:
dw 0xffff;limit
dd 0x00050000;offset
@@:


;I have tried inserting a hang here. Result: No tripple fault.



;Set bit 0 of cr0 (Enable protected mode)
	mov eax, cr0
	or eax, 0x00000001
	mov cr0, eax
	use32


;Jump into segment 0x0008 (K_CODE)
	jmp far 0x0008:@f
	@@:

;Tried another hang here. Processor never reaches it: Tripple fault. I assume this is because of some techincal stuff related to PMode...?




Re: Problems with PMode

Posted: Thu Jul 11, 2013 10:22 am
by iansjack
I may be missing something, but I cannot see from your code what the value of CS is before the far jump.

Re: Problems with PMode

Posted: Thu Jul 11, 2013 10:25 am
by egos

Code: Select all

;Get memory size
	mov ah, 0x88
	int 0x15
	jc error_rmode
Put this code before "cli". There is more progressive function. Use it first.

Code: Select all

gdtr_template:
dw 0xffff;limit
dd 0x00050000;offset
No. Use actual limit.

Code: Select all

	use32


;Jump into segment 0x0008 (K_CODE)
	jmp far 0x0008:@f
	@@:
Very bad. Do you understand what "use32" does? Try this:

Code: Select all

  jmp fword 8:@f

  use32
@@:

Re: Problems with PMode

Posted: Thu Jul 11, 2013 10:34 am
by danielbj
Egos:

I understand the first bit, about moving the CLI.

But can you explain why i need to use the actual limit, and what that fword-jumpy thing is about?

(Thanks for the replies. I'm changing the code and trying to boot it right now :) )

Re: Problems with PMode

Posted: Thu Jul 11, 2013 10:47 am
by danielbj
iansjack: The CS is set to 0x0000 in the bootloader, not posted here :)

Re: Problems with PMode

Posted: Thu Jul 11, 2013 11:03 am
by linguofreak
danielbj wrote:But can you explain why i need to use the actual limit,
If you set your GDT limit to the actual size of your GDT, then any attempt to use segment numbers above that will cause an error. If you set it to 0xffff, then any random garbage that happens to be in memory beyond the segments you're actually using could be interpreted as a segment descriptor, which could cause incredibly hard-to-track-down bugs.
and what that fword-jumpy thing is about?
The far jump is made while a 16-bit code segment (the real-mode segment you started from) is still loaded in CS. So the CPU is still expecting 16-bit instructions up to and including the far jump, but your code has use32 before the far jump.

Re: Problems with PMode

Posted: Thu Jul 11, 2013 11:29 am
by egos
danielbj wrote:But can you explain why i need to use the actual limit
You should use actual limit for protection purposes. Using invalid selectors/descriptors can result in unexpected behaviour.
what that fword-jumpy thing is about?
"fword" allows to generate 32-bit instruction in 16-bit code. The 16-bit instruction is allowed but not recommended. Anyway your code is incorrect. I think "jmp 0:@f" isn't that you need :D

Re: Problems with PMode

Posted: Thu Jul 11, 2013 11:46 am
by danielbj
Egos! I cannot thank you enough!

The system works, and after months of being stuck on this simple problem, I am ready to proceed on my great adventure of making an operating system!

I officially owe you a beer. :D