Higher Half loading
Posted: Mon Aug 24, 2009 9:59 am
Please help me with my higher half kernel, I don't understand, why this code not working, why I get tripplefaults. When I look memory(xp <ADDRES> in QEMU), I see, that all structures(page directory and tables) are correct(may be it is IMHO?).
start.asmloader.cpaging.hmain.clink.ld
start.asm
Code: Select all
format ELF
MULTIBOOT_MEMORY_INFO equ 1 shl 1
MULTIBOOT_BOOTLOADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_MEMORY_INFO
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_BOOTLOADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
section '.loader' executable writeable
public _start
public _stbss
public _endbss
extrn _loader
align 4
dd MULTIBOOT_BOOTLOADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
_start:
mov esp, _endbss
sub esp, 0xC0000000 - 0x101000
push ebx
call _loader
section '.bss' writeable
_stbss:
rb 8192
_endbss:
Code: Select all
#include <x86_32/paging.h>
#include <x86_32/multiboot.h>
#define PHYS(x) ((x) - 0xC0000000 + 0x101000)
#define LD(x) ((unsigned long)&x)
void loader(multiboot_info_t*) __attribute__((section(".loader")));
extern char sttext; /* start of text section(virtual) */
extern char endtext;
extern char stdata; /* start of data section(virtual) */
extern char enddata;
extern char stbss;
extern char endbss;
extern char end; /* end of kernel(virtual) */
#define TEXT_START LD(sttext)
#define DATA_START LD(stdata)
#define BSS_START LD(stbss)
#define TEXT_END LD(endtext)
#define DATA_END LD(enddata)
#define BSS_END LD(endbss)
#define TEXT_SIZE (TEXT_END-TEXT_START)
#define DATA_SIZE (DATA_END-DATA_START)
#define STACK_SIZE (BSS_END-BSS_START)
#define END LD(end)
void archmain();
void
loader(multiboot_info_t *mbi) {
unsigned long *page_directory = (unsigned long*)PHYS(PAGE_ALIGN(END));
unsigned long *page_table0 = page_directory + PAGE_SIZE; /* 1st MB and loader */
unsigned long *page_table1 = page_table0 + PAGE_SIZE; /* for main kernel */
int i;
/* clearing page directory and pagetables */
for(i = 0; i < 1024; i++)
page_directory[i] =
page_table0[i] =
page_table1[i] = 0;
/* Creating page table for 1st MB and loader */
page_directory[0] = (unsigned long)page_table0 | PDE_PRESENT
| PDE_WRITEABLE;
/* Creating page table for kernel */
page_directory[PDE_ENTRY(TEXT_START)] = (unsigned long)page_table1 | PDE_PRESENT
| PDE_WRITEABLE;
/* mapping 1st MiB */
for(i = 0; i < 256; i++)
page_table0[i] = (i*PAGE_SIZE) | PTE_PRESENT
| PTE_WRITEABLE;
/* mapping loader */
page_table0[256] = (1024*1024) | PTE_PRESENT;
/* mapping '.bss' */
for(i = 0; i < STACK_SIZE/PAGE_SIZE; i++) {
/* mapping 1:1, for loader */
page_table0[PTE_ENTRY(PHYS(BSS_START))+i] = PHYS(BSS_START+i*PAGE_SIZE) | PTE_PRESENT
| PTE_WRITEABLE;
/* mapping to kernel */
page_table1[PTE_ENTRY(BSS_START)+i]= PHYS(BSS_START+i*PAGE_SIZE)| PTE_PRESENT
| PTE_WRITEABLE;
}
/* mapping '.text' */
for(i = 0; i < PAGE_ALIGN(TEXT_SIZE)/PAGE_SIZE; i++) {
page_table1[PTE_ENTRY(TEXT_START)+i] = PHYS(TEXT_START+i*PAGE_SIZE)| PTE_PRESENT;
}
/* mapping '.data' */
for(i = 0; i < PAGE_ALIGN(DATA_SIZE)/PAGE_SIZE; i++) {
page_table1[PTE_ENTRY(DATA_START)+i] = PHYS(DATA_START+i*PAGE_SIZE) | PTE_PRESENT
| PTE_WRITEABLE;
}
/* enable paging */
__asm volatile( "add $(0xC0000000 - 0x101000), %%esp\n" /* set stack to kernel adresses */
"movl %0, %%eax\n"
"movl %%eax, %%cr3\n"
"movl %%cr0, %%eax\n"
"orl $0x80000000, %%eax\n"
"movl %%eax, %%cr0"::"m"(page_directory));
archmain();
for(;;);
}
Code: Select all
#ifndef X86_32_PAGING_H
#define X86_32_PAGIND_H
#define PAGE_SHIFT (12)
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_BASE(x) ((x) & ~(PAGE_SIZE - 1))
#define PAGE_ALIGN(x) (((x) + PAGE_SIZE) & ~(PAGE_SIZE - 1))
/* Page directory entry */
#define PDE_ENTRY(x) ((x) >> 22)
#define PDE_PRESENT (1UL << 0)
#define PDE_WRITEABLE (1UL << 1)
#define PDE_USERACCESS (1UL << 2)
#define PDE_WRITETHROUGH (1UL << 3)
#define PDE_CACHEDISABLE (1UL << 4)
#define PDE_ACCESSED (1UL << 5)
/* Page table entry */
#define PTE_ENTRY(x) (((x) >> 12) & 0x3ff)
#define PTE_PRESENT (1UL << 0)
#define PTE_WRITEABLE (1UL << 1)
#define PTE_USERACCESS (1UL << 2)
#define PTE_WRITETHROUGH (1UL << 3)
#define PTE_CACHEDISABLE (1UL << 4)
#define PTE_ACCESSED (1UL << 5)
#define PTE_DIRTY (1UL << 6)
#endif /* X86_32_PAGING_H */
Code: Select all
static int i = 1;
void
archmain() {
for(;;); /* (;,;)-=<fhtagn!> */
}
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(_start)
SECTIONS
{
. = 0x00100000;
.loader :
{
*(.loader)
}
. = 0xC0000000;
.text ALIGN(0x1000) : AT(ADDR(.text) - 0xBFF00000 + 0x1000)
{
_sttext = .;
*(.text)
*(.rodata*)
_endtext = .;
}
.data ALIGN(0x1000) : AT(ADDR(.data) - 0xBFF00000 + 0x1000)
{
_stdata = .;
*(.data)
_enddata = .;
}
.bss ALIGN(0x1000) : AT(ADDR(.bss) - 0xBFF00000 + 0x1000)
{
*(.bss)
*(COMMON)
}
_end = .;
}