GPF on trying to go back to real mode

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.
Post Reply
thomasloven
Member
Member
Posts: 89
Joined: Tue Feb 26, 2008 10:47 am
Location: Sweden

GPF on trying to go back to real mode

Post by thomasloven »

Good evening.

Im trying to go back from protected mode to (un)real
Problems arise immediately...

First of all; GDT is declared as such:

Code: Select all

	gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //CODE segment 0x08
	gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //DATA segment 0x10
	gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); //User mode CODE 0x18
	gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); //User DATA 0x20
	gdt_set_gate(5, 0, 0xFFFF, 0x9A, 0x00); //16 bit CODE 0x28
	gdt_set_gate(6, 0, 0xFFFF, 0x92, 0x00); //16 bit DATA 0x30
	gdt_set_gate(7, (int)&global_tss, sizeof(TSS_t), 0x89, 0x0F); //TSS 0x38
I load my real mode task

Code: Select all

		current_directory->tables_physical[0] = current_directory->tables_physical[0xC0000000>>22]; //Identity map first mb
		switch_page_directory(current_directory);
		extern void switch_16bit();
		extern void s16();
		memcpy(0x7c00, &s16, 0x1000); //Copy 16 bit code to 0x7C00. It should be safe to use now, right?
		switch_16bit();
And finaly my 16 bit code with switcher

Code: Select all

global switch_16bit
global s16
switch_16bit:
	cli
	mov al, 0xFF ; Mask all irqs
	out 0x21, al
	out 0xA1, al
	jmp 0x7c00 ;Jump to the place s16 was loaded
s16:
	pushad
	jmp 0x28:$+2 //<---GPF HERE
[bits 16]
do_16_bitm:
	mov ax, 0x30
	mov ds, ax
	mov ss, ax
	jmp $
The long jump causes a General Protection Fault.
Is there something else I must do first?
Move the stack? Turn off paging?
User avatar
JoeKayzA
Member
Member
Posts: 79
Joined: Wed Aug 24, 2005 11:00 pm
Location: Graz/Austria

Post by JoeKayzA »

Hi,

what's the exact error code you get in the gpf? The jump target "0x28:$+2" seems a bit risky to me, why don't you just use do_16_bitm as the target? If the target address is wrong, it would probably result in an invalid opcode gpf.
thomasloven
Member
Member
Posts: 89
Joined: Tue Feb 26, 2008 10:47 am
Location: Sweden

Post by thomasloven »

It gives 0x28 as error code. That would indicate a problem with the 5th entry in the gdt (right?) which is my 16 bit code.

I use $+2 because the function I want to jump to is linked together with my kernel at 0xCxxxxxxx and that would mean jmp do_16_bitm would jump there. Or is it assembled relative?
Anyway, changing it gives the same error.
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

Well paging is not supported in real mode, so id turn that off to be safe.
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

My guess is that your 16-bit protected mode code is above the 1MB together with the kernel. In this case you get a segment limit violation because 1MB+something > 64k

In that case, you'll need to set a base for that segment, or copy the 16-bit code to a location under 64k.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
thomasloven
Member
Member
Posts: 89
Joined: Tue Feb 26, 2008 10:47 am
Location: Sweden

Post by thomasloven »

I do copy the 16 bit code to 0x7c00

Code: Select all

memcpy(0x7c00, &s16, 0x1000);
I also tried moving the gdt and gdt pointer to below 0xAC00 and 0xBC00 respectively.

Edit
I'm giving this line up since I just got V86 to work.
It was just a distraction to get my mind of general protection faults for a while anyway.

...didn't work too well...
Post Reply