Page 1 of 1

Problem with early paging

Posted: Wed Mar 21, 2012 6:35 am
by akoskovacs
Hi!

I would like to ask for some help with my kernel initialization code. Firstly, I want to enable paging as soon as possible. So, I created a separated section in the linker script to do it (.setup). Both boot.S and pgsetup.c linked to here.
linker.ld:

Code: Select all

OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY (loader)
hhalf = 0xc0000000;
page_size = 4096;

SECTIONS
{
    . = 0x00100000;
    .setup :
    {
    __start_setup = .;
        *(.setup)
        *(.setup.data)
        boot/boot.o(.bss)
        boot/boot.o(COMMON)
    __end_setup = .;
    }

    /* Higher half */
    . += 0xc0000000;
    .text : AT(ADDR(.text) - hhalf) 
    {
        *(.text)
    __start_cs_init = .;
        *(.init.text)
    __end_cs_init = .;
    }

    .rodata ALIGN(page_size) : AT(ADDR(.rodata) - hhalf)
    {
    __start_data_kernel = .;
        *(.rodata*)
    }

    .data ALIGN(page_size) : AT(ADDR(.data) - hhalf)
    {
        *(.data)
    }

    .bss ALIGN(page_size) : AT(ADDR(.bss) - hhalf)
    {
        sbss = .;
        *(COMMON)
        *(.bss)
        ebss = .;
    __end_data_kernel = .;
    }
}
This is linked and loaded on the first megabyte. It contains the multiboot loader and the page initialization code, which is a C file. It simply do the identity mapping and also maps the first 4MB to the 3GB boundary (0xC0000000). This code works, but I think this is the source of the problem.
pgsetup.c:

Code: Select all

#define __SETUP__
#include <page.h>

uint32_t page_directory[1024] __setup_data __align(PAGE_SIZE);
uint32_t page_table[1024] __setup_data __align(PAGE_SIZE);
void     setup_paging(void) __setup;

void setup_paging(void)
{
    register int i;
    for (i = 0; i < 1024; i++) {
        page_directory[i] = 0;
        page_table[i] = 0;
        /* Map the first 4MB and set the appropriate flags */
        page_table[i] = (i * PAGE_SIZE) | PT_PRESENT | PT_RW;
    }
    
    page_directory[0] = (uint32_t)page_table | PD_RW | PD_PRESENT;
    page_directory[768] = (uint32_t)page_table | PD_RW | PD_PRESENT;
    __asm__ __volatile__("movl %0, %%cr3\n"
                         "movl %%cr0, %%eax\n"
                         "orl 0x80000000, %%eax\n"
                         "movl %%eax, %%cr0\n"
                         : /* No output */
                         : "b"((uint32_t)page_directory)
                         : "eax");
}
After the loader calls the setup_page() it sets the %esp to a higher-half stack.
boot.S:

Code: Select all

# Multiboot header omitted...
.comm lower_stack, STACKSIZE/16, 32  # Low-stack, linked to .setup.bss
loader:
    mov   $(lower_stack + STACKSIZE/16), %esp
    #mov   %eax, (mbtable)
    #mov   %ebx, (chksig)
    pushl  %eax
    pushl  %ebx
    call  setup_paging
    popl   %eax
    popl   %ebx
    movl  $(higher_stack + STACKSIZE), %esp
    pushl  %eax
    pushl  %ebx
    call  kmain

hang:
    hlt
    jmp   hang
After running the whole thing, the Qemu claims with: "qemu: fatal: Trying to execute code outside RAM or ROM at 0xc0103400". It seems, it cannot execute the kmain() (at 0xc0103400), probably the paging code fails to set up the things, but I cannot found the exact error.

Sorry for the long post, but I think all code is essential. You can find my repo at: github.com/akoskovacs/Akosix/

Thank you in advance!

Re: Problem with early paging

Posted: Wed Mar 21, 2012 7:52 am
by bluemoon
So, what's the output of objdump, what's at specific location of error (0xc0103400)? and what's the offset of page_directory, page_table?

Re: Problem with early paging

Posted: Wed Mar 21, 2012 7:56 am
by shikhin
Hi,
akoskovacs wrote:

Code: Select all

    __asm__ __volatile__("movl %0, %%cr3\n"
                         "movl %%cr0, %%eax\n"
                        [b]"orl 0x80000000, %%eax\n"[/b]
                         "movl %%eax, %%cr0\n"
                         : /* No output */
                         : "b"((uint32_t)page_directory)
                         : "eax");
While I'm honestly poor with AT&T style syntax, and I didn't look through your code properly, but shouldn't the bold part be:

Code: Select all

"orl $0x80000000, %%eax\n"
Hope it helps.

Regards,
Shikhin

Re: Problem with early paging

Posted: Wed Mar 21, 2012 9:07 am
by akoskovacs
Shikhin wrote:Hi,
akoskovacs wrote:

Code: Select all

    __asm__ __volatile__("movl %0, %%cr3\n"
                         "movl %%cr0, %%eax\n"
                        [b]"orl 0x80000000, %%eax\n"[/b]
                         "movl %%eax, %%cr0\n"
                         : /* No output */
                         : "b"((uint32_t)page_directory)
                         : "eax");
While I'm honestly poor with AT&T style syntax, and I didn't look through your code properly, but shouldn't the bold part be:

Code: Select all

"orl $0x80000000, %%eax\n"
Hope it helps.

Regards,
Shikhin
Oh, Thank You! =D>

I felt it was something obvious.

Re: Problem with early paging

Posted: Wed Mar 21, 2012 10:32 am
by shikhin
Hi,
akoskovacs wrote:I felt it was something obvious.
It always is, my dear friend, it always is. :)

Or, quoting Solar (who was probably quoting someone else):
Solar wrote:Every bug is trivial, once you've found it.
Regards,
Shikhin!

Re: Problem with early paging

Posted: Wed Mar 21, 2012 10:44 am
by Solar
Shikhin wrote:Or, quoting Solar (who was probably quoting someone else):
Solar wrote:Every bug is trivial, once you've found it.
A former technical project manager of mine, name of Uwe Ueberfuhr. Credit where credit is due. 8)

Re: Problem with early paging

Posted: Wed Mar 21, 2012 4:04 pm
by gravaera
Germans got dat wisdom

Re: Problem with early paging

Posted: Wed Mar 21, 2012 10:03 pm
by shikhin
Hi,
Solar wrote:
Shikhin wrote:Or, quoting Solar (who was probably quoting someone else):
Solar wrote:Every bug is trivial, once you've found it.
A former technical project manager of mine, name of Uwe Ueberfuhr. Credit where credit is due. 8)
Who was probably quoting someone else, but I think giving that much credit is enough.. :)

Regards,
Shikhin