Triple fault when enabling paging

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.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

iansjack wrote:Your page directory is at a physical address higher than 2GB, and the page table address is much lower in physical memory (just above the 1MB mark)? That just doesn't feel right. I don't know how you are assigning physical pages but I would guess that most people assign the lowest available page first.

Without going in to the full details of how you are managing your pages I just have the gut feeling that your page table is screwed up.
Maybe the bits are going in reverse order?
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
mallard
Member
Member
Posts: 280
Joined: Tue May 13, 2014 3:02 am
Location: Private, UK

Re: Triple fault when enabling paging

Post by mallard »

iansjack wrote:I don't know how you are assigning physical pages but I would guess that most people assign the lowest available page first.
Actually, it's a much better idea to allocate high pages first. The lower you go in memory, the more "special" that memory is; <4GB for 32-bit MMIO, <16MB for ISA MMIO, <1MB for real-mode accessible MMIO, BIOS, etc. If you start allocating from the top of RAM, you maximise the amount of "special" memory that is available for any hardware drivers that need to use it. Hopefully, by the time that low memory needs to be allocated, you've loaded all the drivers that the system needs.
Image
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Triple fault when enabling paging

Post by neon »

Hello,
And it doesn't have anything about table address or index,
Yet you are indeed treating it as an address in a few places:

Code: Select all

tbl[i].phys_addr =mem;
...
pgdir[0].tbl_addr=pgtbl;
Both of which are wrong for the reasons stated before - because tbl_addr is defined as the high 12 bit PFN component of the page table structures, you need to use PFN's here.
My page directory in 32-bit unsigned integer is 0x9b800003, the page table is 0x0013700
I suspect what you posted was page_directory[0] rather then the actual address (cr3 register), which would imply 0x9b800003 -> 9b80 pfn, present, ring 0 -> invalid page frame number. You can verify this by using the info tab command in bochsdbg.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Triple fault when enabling paging

Post by iansjack »

mallard wrote:
iansjack wrote:I don't know how you are assigning physical pages but I would guess that most people assign the lowest available page first.
Actually, it's a much better idea to allocate high pages first. The lower you go in memory, the more "special" that memory is; <4GB for 32-bit MMIO, <16MB for ISA MMIO, <1MB for real-mode accessible MMIO, BIOS, etc. If you start allocating from the top of RAM, you maximise the amount of "special" memory that is available for any hardware drivers that need to use it. Hopefully, by the time that low memory needs to be allocated, you've loaded all the drivers that the system needs.
Really? I would have thought that a typical 32-bit system had 4GB of RAM nowadays, so if you allocate pages from the top of RAM first that is the very memory that you say is special. ISA can pretty well be ignored nowadays, and the amount of memory reserved for real mode stuff is so small that you can just map those pages as used from the start.

I could be completely wrong and it could be that the OP is mapping pages from the top of available RAM downwards; we'll have to wait and see what he says.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Triple fault when enabling paging

Post by neon »

It is my understanding that all he is doing is identity mapping the first page table, in which case the physical frames would not need to be dynamically allocated.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

iansjack wrote:
mallard wrote:
iansjack wrote:I don't know how you are assigning physical pages but I would guess that most people assign the lowest available page first.
Actually, it's a much better idea to allocate high pages first. The lower you go in memory, the more "special" that memory is; <4GB for 32-bit MMIO, <16MB for ISA MMIO, <1MB for real-mode accessible MMIO, BIOS, etc. If you start allocating from the top of RAM, you maximise the amount of "special" memory that is available for any hardware drivers that need to use it. Hopefully, by the time that low memory needs to be allocated, you've loaded all the drivers that the system needs.
Really? I would have thought that a typical 32-bit system had 4GB of RAM nowadays, so if you allocate pages from the top of RAM first that is the very memory that you say is special. ISA can pretty well be ignored nowadays, and the amount of memory reserved for real mode stuff is so small that you can just map those pages as used from the start.

I could be completely wrong and it could be that the OP is mapping pages from the top of available RAM downwards; we'll have to wait and see what he says.
I'm identity mapping pages from start of RAM.

Code: Select all

void paging_ident(page_table_t *tbl)
{
    //Identity map first 4 megabytes of memory.
    size_t size=4096;
    for(size_t i=0; i<size; i++)
    {
        tbl[i].rw_flag   =1;
        tbl[i].access_lvl=0;
        tbl[i].phys_addr =i;
        tbl[i].present =1;

    }
}
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Triple fault when enabling paging

Post by neon »

Hello,

Only loop for 1024 entries (the page tables only have 1024 pages.) Besides that, it looks alright to me and should work with the following code,

Code: Select all

pgdir[0].present    = 1;
pgdir[0].rw_flag    = 1;
pgdir[0].access_lvl = 0;
pgdir[0].tbl_addr   = pgtbl >> 12;
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

Doesn't work. Code:

Code: Select all


void paging_ident(page_table_t tbl[1024])
{
    //Identity map first 4 megabytes of memory.
    size_t size=1024;
    for(size_t i=0; i<size; i++)
    {
        tbl[i].rw_flag   =1;
        tbl[i].access_lvl=0;
        tbl[i].phys_addr =i;
        tbl[i].present =1;

    }
}

void setup_paging()
{
    void load_pg_dir(page_directory_t *);
    void paging_enable(void);
    setup_pgdir(pgdir);
    paging_ident((page_table_t*)pgtbl);
    pgdir[0].present    = 1;
    pgdir[0].rw_flag    = 1;
    pgdir[0].access_lvl = 0;
    pgdir[0].tbl_addr   = (uint32_t)(pgtbl) >> 12;
    load_pg_dir(pgdir);
    paging_enable();
}
; paging.asm
global load_pg_dir
load_pg_dir:
	push ebp
	mov ebp, esp
	mov eax, [esp+8]
	mov cr3, eax
	mov esp, ebp
	pop ebp
	ret
global paging_enable
paging_enable:
	push ebp
	mov ebp, esp
	mov eax, cr0
	or eax, 0x80000000
	mov cr0, eax ; Triple fault!
	mov esp, ebp
	pop ebp
	ret
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
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:

Re: Triple fault when enabling paging

Post by Combuster »

My page directory in 32-bit unsigned integer is 0x9b800003, the page table is 0x00137000. Looks like everything's correct.
Until those numbers are within 16KB of each other, or you can explain in detail why the first number is correct, I don't believe you. Has this changed already?
"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 ]
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

Combuster wrote:
My page directory in 32-bit unsigned integer is 0x9b800003, the page table is 0x00137000. Looks like everything's correct.
Until those numbers are within 16KB of each other, or you can explain in detail why the first number is correct, I don't believe you. Has this changed already?
Oops, yes. It's 0x00237000.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
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:

Re: Triple fault when enabling paging

Post by Combuster »

00237000 and 00137000 still dont look like successive allocations
"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 ]
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Triple fault when enabling paging

Post by neon »

Those addresses are...odd. If &pgdir[0]=0x00237000 and &pgtbl[0]=0x00137000, both allocated in static space, yet somehow a MB apart. What I'd advise for you to do is to have the compiler produce a linker map and get the linear addresses from there and compare with what you are giving us here. If they are correct, give us the value of the faulting address (cr2 register) for cross checking. Also, give us the uint32_t value of pgdir[0] and pgtbl[0] so that we can make sure they are correct.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

pgdir is 0x0009B803, pgtbl is 0x00000003.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re: Triple fault when enabling paging

Post by osdever »

I can't debug it using Bochs, because it just crashes with no error messages in console, just

Code: Select all

00000000000i[SYS   ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0  ] cpu hardware reset
and resetting. I can't ever see the GRUB menu, so the problem isn't in my code.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Triple fault when enabling paging

Post by iansjack »

I'm puzzled. In your initial post you said the problem happened when you turned on paging. Now you are saying that it isn't in your code.

If it's crashing before you can do any debugging then from where are you getting the values that you tell us your page table entries have?
Post Reply