Triple-fault when enabling paging (solved)

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
Shibata
Posts: 9
Joined: Mon Jan 23, 2012 7:16 pm

Triple-fault when enabling paging (solved)

Post by Shibata »

(Sorry for my bad english, I'm brazilian)

Hi everyone! I'm new in the forum. I'm here because I'm having big problems with IA-32E paging and there aren't any good brazilian foruns on OS development.

I'm developing a simple OS as a hobby, just to learn how a OS work. Nowadays, it's only a text mode OS that does all the initialization stuff (A20 line, segmentation, paging, PIC...) and shows some messages on the screen.

I understand all the theory of paging and segmentation, but I can't get IA-32E paging working. I'm running my code under Bochs. After I enable paging, Bochs tells that the physical address is not available. I understand the error, but can't fix it. It must be something simple, but I've been trying to fix it for more than two weeks and can't get it working.

I've reduced my code to the simplest possible. It jumps directly from Real Mode to Long Mode, without Protected Mode. It detects hardware (1Gb pages supported, Long Mode supported and so on), activates A20, loads a 64 bit GDT and identity maps 1Gb (using a PDPTE that maps 1Gb). I believe that most of the code is ok, so I'll post the stuff that may be causing the error.

Before paging, I load this GDT:

Code: Select all

GDT:

dq 0 ;null-selector

;code:
dw 1111_1111_1111_1111b;bits 0-15 -> bits 0-15 of the segment limit
dw 0;bits 16-31 -> bits 0-15 of the base address
db 0;bits 32-39 -> bits 16-23 of the base address


db 1001_1111b

db 1010_1111b

db 0

;data (32 bits):
dw 1111_1111_1111_1111b
dw 0
db 0


db 1001_0111b


db 1010_1111b
db 0

.p: ;pointer
	dw GDT.p - GDT - 1
	dq GDT
Firstly, the first PML4E entry. It's loaded at physical position 0. I'm under Real Mode here:

Code: Select all

mov dword [0], (1000h << 12) | 111b ; It's present, Read/Write and accessible for users and supervisors. It points the PDPTE at 1000h
mov dword [4], 0
Right after it, there's the code that creates the PDPTE:

Code: Select all

mov dword [1000h],(1 << 7) | 111b ; Present, Read/Write, User/Supervisor. Maps a 1Gb page at physical address 0.
mov dword [1000h + 4],0
Then, I load cr3 with the address of the PML4E:

Code: Select all

xor eax,eax
mov cr3,eax ; PCIDE is off
Enable Long Mode:

Code: Select all

mov ecx,0xC0000080
rdmsr
or eax,1 << 8;LME
wrmsr
Enable PAE:

Code: Select all

mov eax,cr4
or eax,1 << 5;PAE
mov cr4,eax
Paging and Protected Mode:

Code: Select all

mov eax,cr0
or eax,1 << 31 | 1 << 0;Paging (PG) and Protected Mode (PE)
mov cr0,eax
Then, I would jump to Long Mode (but the linear address is outside the physical RAM and Bochs shows "Physical Address not available"):

Code: Select all

jmp 8:long_mode

[bits 64]
long_mode:
hlt
It's midnight here and I'm going to sleep. I'll see your posts tomorrow.

Thanks in advance for any help.
Last edited by Shibata on Tue Jan 24, 2012 7:14 am, edited 1 time in total.
Shibata
Posts: 9
Joined: Mon Jan 23, 2012 7:16 pm

Re: Triple-fault when enabling paging

Post by Shibata »

berkus wrote:The very topic title "Triple-fault when enabling paging" screams for "I DIDN'T SEARCH THE FORUM FOR SIMILAR TOPICS 'COZ I WAS AFRAID I WILL FIND A HUNDRED OF THE EXACTLY THE SAME TOPICS ANSWERED THERE, so I would just go and break the forum rules hoping someone answer to me."

I answered, enjoy.
Sorry, but I've searched around, and I didn't find much documentation on IA-32E, only 32-bits paging and PAE. I tried to make it work with what I've found, but I couldn't. I posted because I think I'm doing everything I should, but can't get it working.
berkus wrote:Did you at the very least "CLI"?
Yes. That's the first thing I do. Here's what my code before enabling paging does:

1 - cli
2 - Setup A20
3 - Test CPUID support
4 - Test if CPUID functions above 0x80000001 are supported
5 - Map memory using BIOS int 15h, eax = 0xE820

The rest is in the topic.


EDIT: Found the problem. I shouldn't shift the bits of the PDPTE address in the PML4E. Thanks for trying to help :D .
Post Reply