System resets when PAE is enabled

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
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

System resets when PAE is enabled

Post by sawdust »

Hi,
I'm trying to setup paging with PAE enabled (2MB pages). As soon as the paging is turned on, the system restarts. Any idea on what's going on? The AMD CPU has PAE support. I checked the cpuid and feature flags already. I've seen people mapping the the last page dir entry in 4KB non-PAE paging. If that is required here, how is it done?
- Thanks in advance

Code: Select all

#define PAGE_SHIFT	21  // for 2MB page using PAE
#define PAGE_SIZE	(1 << PAGE_SHIFT)

struct pde {
	uint32_t addr_lo;
	uint32_t addr_hi;
} __attribute__ ((packed));

static inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
		/* Load the page table address */
		"movl	%0, %%cr3\n\t"
		/* Enable pae */
		"movl	%%cr4, %%eax\n\t"
		"orl	$0x00000020, %%eax\n\t"
		"movl	%%eax, %%cr4\n\t"
		/* Enable paging */
		"movl	%%cr0, %%eax\n\t"
		"orl	$0x80000000, %%eax\n\t"
		"movl	%%eax, %%cr0\n\t"
		:
		: "r" (pdp)
		: "ax"
		);
}


struct pde gPageDir[2048]     __attribute__ ((aligned(4096)));
struct pde gPageDirPtrTab[4]  __attribute__ ((aligned(4096)));
struct pde *pd                __attribute__ ((aligned(4096)));
struct pde *pdptr             __attribute__ ((aligned(4096)));

void PAE_InitPaging(uint32_t maxmem)
{
    uint32_t i, cr0;
    uint32_t pageflags = PF_GLOBAL | PF_PRESENT | PF_KERNELPAGE | PF_READWRITE;

    pd    = gPageDir;
    pdptr = gPageDirPtrTab;

    paging_off();

        // Point the page directory pointers at the page directories 
    pdptr[0].addr_lo = ((uint32_t)&pd[512*0])|1;
    pdptr[1].addr_lo = ((uint32_t)&pd[512*1])|1;
    pdptr[2].addr_lo = ((uint32_t)&pd[512*2])|1;
    pdptr[3].addr_lo = ((uint32_t)&pd[512*3])|1;

   //identity-map (maxmem == 512MB-1)
    for(i = 0; i < maxmem; i+= PAGE_SIZE)
    {
        printf("%d.. ",i/PAGE_SIZE);
        pd[i/PAGE_SIZE].addr_lo = i | pageflags;
        pd[i].addr_hi = 0;
        printf("0x%x \n",pd[i/PAGE_SIZE].addr_lo);
    }

    printf("..... turning on paging..\n");    // <= crashes immediately after this print

    paging_on(pdptr);

    printf("mapping done..\n");
    return;
}
Last edited by sawdust on Mon Dec 22, 2008 12:46 pm, edited 1 time in total.
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: System resets when PAE is enabled

Post by CodeCat »

Try adding the 'hlt' instruction after the first instruction in paging_on. If it doesn't crash but instead hangs, then move it to after the next instruction, and so on. The first time it does crash, the hlt instruction will be right after the faulty instruction.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: System resets when PAE is enabled

Post by jal »

CodeCat wrote:Try adding the 'hlt' instruction after the first instruction in paging_on. If it doesn't crash but instead hangs, then move it to after the next instruction, and so on. The first time it does crash, the hlt instruction will be right after the faulty instruction.
Or, use a suitable debugger, like the Bochs one. Much easier.


JAL
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Re: System resets when PAE is enabled

Post by sawdust »

Code: Select all

__inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
/* Load the page table address */
            "movl	%0, %%cr3\n\t"
/* Enable pae */
            "movl	%%cr4, %%eax\n\t"
            "orl	$0x20, %%eax\n\t"
            "movl	%%eax, %%cr4\n\t"
            
/* Enable paging */
            "movl	%%cr0, %%eax\n\t"
            "orl	$0x80000000, %%eax\n\t"
            "movl	%%eax, %%cr0\n\t"
            "hlt    \n\t"               <====== system resets just before this point
            :
            : "r" (pdp)
            : "ax"
            );
}
I inserted 'hlt' after every instruction and the reset happens after enabling paging. This paging_on() stub is taken from the popular memtest http://www.memtest86.com/ . The problem could be that I'm doing something wrong wrt the page-dir-ptr. My system has only 1GB physical memory and I guess it should be ok to enable PAE. Any help will be appreciated very much.
Thanks again
-sawdust
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: System resets when PAE is enabled

Post by IanSeyler »

[quote="sawdust"]

Code: Select all

__inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
/* Load the page table address */
            "movl	%0, %%cr3\n\t"
...
Can you verify that the page table is located at memory address 0x00000000 ?

-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: System resets when PAE is enabled

Post by CodeCat »

It says %0, not $0, so it's a designation for a variable inside an asm block. And in this case that variable is 'pdp'.
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Re: System resets when PAE is enabled - solved

Post by sawdust »

Thx guys. I put pdptr at known location, i.e., kernel_end. Everything works. 'hlt' really helped.
:)
Post Reply