Help with activating pmode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Help with activating pmode

Post by tadada »

Ok after working with 16-bit for a month or so I decided to move onto 32-bit. Everything worked perfectly untill I got to actually activating pmode.(A20 has been activated) When it gets to the code where it activates pmode virtualPC gives me an error saying an unrecoverable processor error has happened. It the resets and runs again and continues to do so untill I shut it down. I tried to run it in Bochs but I can't get it even to boot. (never had good luck with Bochs)

Everything is included in the KERNEL's pre startup section through include files. (its an all assembly kernel) activate A20 is called and returns. Then enable_pmode is called and it fails. I tried putting all the enable_pmode code in the kernel so there is no call but it gives the same error. To exit the call and to start the Kernel I use jmp 08h:Kernel

This is my actual code to activate pmode:

Code: Select all

	CLI
	LGDT 	[GDTR]
	MOV 	EAX, CR0
	OR 	AL, 1
	MOV 	CR0, EAX

	JMP 08h:PModeMain
Can someone please help me?

Thanks in advance.
My OS: SOS (Simple Operating System).
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

You might want to AND EAX, 0x7FFFFFFF
to turn off "paging" -- but other than that, your code snippet should work. So that means the problem is in how you set up the GDT.
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Post by kmtdk »

Hi, tadada.
I havent heard about that error before, and i cant see any problem with the code.
But try this simpel bootloader, and tell if it works.(it does not activate a20)
Attachments
boot1.asm
the simple bootloader, just change the extensen to .bin
(512 Bytes) Downloaded 23 times
boot11.ASM
the simple bootloader code in Flat assembler syntax
(1.91 KiB) Downloaded 38 times
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
svdmeer
Member
Member
Posts: 87
Joined: Tue May 06, 2008 9:32 am
Location: The Netherlands

Post by svdmeer »

bewing wrote:You might want to AND EAX, 0x7FFFFFFF
to turn off "paging" -- but other than that, your code snippet should work. So that means the problem is in how you set up the GDT.
I can't say wheter the snippet will work. I miss the contents of GDTR and the GDT itself. Maybe they contain errors, that cause the crash.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

adding AND EAX, 0x7FFFFFFF right after the loading of the GDT didn't work

also the bootloader that you told me to run failed too.

This is the actual GDT:

Code: Select all

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:
GDTR: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			; base of GDT
My OS: SOS (Simple Operating System).
Martijn
Posts: 22
Joined: Tue Feb 26, 2008 3:43 am
Location: The Netherlands

Post by Martijn »

Your GDT and code look fine to me. Are you shure VirtualPC crashes before 'JMP 08h:PModeMain'?
If not, can you show us your 'PModeMain' function and verify it sets the data/stack segment registers like shown below?

Code: Select all

use32
PModeMain:
	mov ax, 0x10
	mov ds, ax
	mov ss, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

My PModeMain is below:

Code: Select all

	mov		ax, 0x10		; set data segments to data selector (0x10)
	mov		ds, ax
	mov		ss, ax
	mov		es, ax
	mov		sp, 90000h		; stack begins from 90000h
                cli                              ;no need really for interrupts have not been programmed yet
                hlt                             ;for now it just stops
before the ds wasn't set as 0x10 (that line was commented out) but even with it being set to 0x10 it still errors.

It errors with the code you suggested too.

It seems to be VirtualPC's fault. I'll try Qemu to see if it is. I also have a real computer with a floppy drive that runs linux. If Qemu fails I'll load the OS on a drive then try it on real hardware.
My OS: SOS (Simple Operating System).
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

It doesn't seem to be VirtualPC's fault for I found a tutorial with a well commented piece of source code. It runs fine. I'm going to read it over and see if I can deduce what is going wrong then.
My OS: SOS (Simple Operating System).
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Post by kmtdk »

OKay,
well you say that you can't get bochs to work..
i use bochs, and can only say good things about it.
to use bochs you have to create a txt file, were it can load some options.
i just send my, try with that one. It will then load from drive a:
If you get a error msg while starting bochs up, about some bx.... just chage the "romimage: file=$BXSHARE/BIOS-bochs-latest " to the drive:
romimage:" file=c:bochs/BIOS-bochs-latest "



KMT
Attachments
bochsrc.txt
(517 Bytes) Downloaded 54 times
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

well. Bochs booted the kernel but it erred. It constantly is updateing visually showing the startup code. (the virtual machine startup not my kernel startup)

I looked in the log and sure enough it hit an error:
00002626617e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting

When I stopped it the log file totaled 1.87 MBs

BTW: thank you very mmuch for that file. It runs nicely now.

EDIT: could this be cause by trying to load pmode when it already is in pmode? I was looking through the log a little bit more closly and like 20 lines about the error it says:

Code: Select all

01562758832e[CPU0 ] fetch_raw_descriptor: GDT: index (17)2 > limit (0)
01562758832i[CPU0 ] CPU is in protected mode (active)
after that it has the values of the registers. It continues on to what I believe is my code. After some lines it comes to

Code: Select all

01562758832i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
01562758832i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
which I believe is the activate pmode code. So it seems it was booted in pmode.

The problem I see with that is inbetween being booted and loading the kernel I print a string using Bios interrupts but If I start in pmode then it shoudln't be working.
My OS: SOS (Simple Operating System).
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Post by kmtdk »

when the last cr0 bit is 1. you are in pmode.
The next problem is because there is a faulier.
The faulier, in your case looks like the int 0x10
So before going into pmode, "cli"
and "DONT" "sti" before you have loaded a new IDT.
you cant use int 0x10 in pmode (unless you stored the address when you were in real mode)
my sugestion is: write you own print runtine:
it is failery simple.
an exempel might be, if ypou are using strings:
store the address in "ESI",store "0xb8000" in EDI, and call this function

Code: Select all

screen.print:
           
            mov al,[esi] ; get char
            xor al,0x00  ; if char= 0 then stop print.
            je screen.print.finish
            mov ah,0x0f  ; color
            inc esi           ; prepare for next char
            mov [edi],ax  ; put the char on the screen
            add edi,0x02  ; add 2 to edi, for the next char
            jmp screen.print  ; countione (sry for my bad spelling)
screen.print.finish:

             ret



KMT
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

the thing is when I print that string using the interrupts it works. It says "loading the Kernel" and then loads the kernel. I commented out all the printing lines and it still throws the exception. It even loads the kernel which is done through BIOS interrupts. (in both VirtualPC and Bochs before they error)
My OS: SOS (Simple Operating System).
svdmeer
Member
Member
Posts: 87
Joined: Tue May 06, 2008 9:32 am
Location: The Netherlands

Post by svdmeer »

tadada wrote:the thing is when I print that string using the interrupts it works. It says "loading the Kernel" and then loads the kernel. I commented out all the printing lines and it still throws the exception. It even loads the kernel which is done through BIOS interrupts. (in both VirtualPC and Bochs before they error)
Can you well me the number after the ORG-keyword in the 16-bit assembly code containing the protectedmode switch?

Maybe there is something wrong with that far-jump.

Are you sure PModeMain is calculated at the right offset?

Maybe it's an idea to post the complete code, the whole 16-bit part and a very little piece of testing code in protected mode.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

right after the ORG is 0x500

All it does is enables and then tests (after setting the registers)

I tried to orginise the file in a way that wouldn't hurt but would also spare you my comments to myself that had little to do with the actual code.

BTW: how would I put the bootloader onto the floppy in linux. In windows I usse partcopy but I can't seem to get it with Linux. I am trying to put it on a real floppy to test it and my windows computer is too modern.
Attachments
KERNEL_.asm.txt
I tried to orginise it in a way that wouldn't be horrendous
(3.13 KiB) Downloaded 30 times
My OS: SOS (Simple Operating System).
svdmeer
Member
Member
Posts: 87
Joined: Tue May 06, 2008 9:32 am
Location: The Netherlands

Post by svdmeer »

tadada wrote:right after the ORG is 0x500

All it does is enables and then tests (after setting the registers)

I tried to orginise the file in a way that wouldn't hurt but would also spare you my comments to myself that had little to do with the actual code.

BTW: how would I put the bootloader onto the floppy in linux. In windows I usse partcopy but I can't seem to get it with Linux. I am trying to put it on a real floppy to test it and my windows computer is too modern.
I think the ORG 0x500 causes your problem at the "JMP 08h:PModeMain" instruction.

Because you set ORG at 0x500, your PModeMain offset will be calculated from offset 0x500. Your protectedmode-segments begin at zero. That means PModeMain will be 0x500 too low.

You can try 2 solutions:
1. Set your ORG at 0x0000
2. (the easiest one) add 0x500 to PModeMain in the far-jump, so try "JMP 08h:(PModeMain+0x500)"


About that piece of source-code you included in your last post:
- You use " jmp SYS_CODE_SEL:Kernel". Because of the org 0x500 the problem is the same as described above. So try "jmp SYS_CODE_SEL:(Kernel+0x500)".
- You can't use the function print from the 32-bit code! Don't do it. Reason 1: You can't use the BIOS int 10h from protected mode. Reason 2: You can't call 16-bit code from 32-bit code without changing CS to a 16-bit codesegment. You need to keep 16-bit and 32-bit code strictly seperated. That means you have to write a 32-bit version of your print-function, with 32-bit code and without using the bios.
Post Reply