From 532c631f856dde666ed19d3d479e9a57b4eb55f1 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 17 Jan 2015 18:36:32 +0100 Subject: [PATCH] map multiboot info during boot straping into the address space required to support mmio devices as output device during startup --- arch/x86/include/asm/page.h | 9 +++++++++ arch/x86/kernel/entry.asm | 17 ++++++++++++++--- arch/x86/kernel/uart.c | 2 ++ arch/x86/mm/page.c | 20 +++++++++++++++++--- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 9db82f3..196bc1e 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -110,6 +110,15 @@ size_t virt_to_phys(size_t vir); */ int page_init(void); +/** @brief Map one page into the boot page table + * + * @param viraddr + * @param phyaddr + * @param bits + * @return + */ +int page_map_bootmap(size_t viraddr, size_t phyaddr, size_t bits); + /** @brief Map a continuous region of pages * * @param viraddr Desired virtual address diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index a8c3fe6..e22ff65 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -65,10 +65,10 @@ stublet: ; Initialize stack pointer mov esp, boot_stack add esp, KERNEL_STACK_SIZE-16 + ; Interpret multiboot information + mov DWORD [mb_info], ebx ; Initialize CPU features call cpu_init -; Interpret multiboot information - mov DWORD [mb_info], ebx ; Jump to the boot processors's C code extern main @@ -93,6 +93,15 @@ cpu_init: mov DWORD [edi], eax pop edi %endif + push edi + mov eax, DWORD [mb_info] ; map multiboot info + and eax, 0xFFFFF000 ; page align lower half + mov edi, eax + shr edi, 10 ; (edi >> 12) * 4 (index for boot_pgt) + add edi, boot_pgt + or eax, 0x101 ; set present and global bits + mov DWORD [edi], eax + pop edi push edi push ebx push ecx @@ -106,7 +115,7 @@ L0: cmp ecx, ebx mov edi, eax shr edi, 10 ; (edi >> 12) * 4 (index for boot_pgt) add edi, boot_pgt - or eax, 0x103 ; set present, global, writable and + or eax, 0x103 ; set present, global and writable bits mov DWORD [edi], eax add ecx, 0x1000 jmp L0 @@ -363,6 +372,8 @@ boot_stack: ; These tables do a simple identity paging and will ; be replaced in page_init() by more fine-granular mappings. ALIGN 4096 +global boot_map +boot_map: boot_pgd: DD boot_pgt + 0x107 ; PG_PRESENT | PG_GLOBAL | PG_RW | PG_USER times 1022 DD 0 ; PAGE_MAP_ENTRIES - 2 diff --git a/arch/x86/kernel/uart.c b/arch/x86/kernel/uart.c index 800b8ad..dfe9769 100644 --- a/arch/x86/kernel/uart.c +++ b/arch/x86/kernel/uart.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -326,6 +327,7 @@ Lsuccess: mmio = 1; page_map(iobase & PAGE_MASK, iobase & PAGE_MASK, 1, PG_GLOBAL | PG_ACCESSED | PG_DIRTY | PG_RW | PG_PCD); kprintf("UART uses mmio address 0x%x\n", iobase); + vma_add(iobase, iobase + PAGE_SIZE, VMA_READ|VMA_WRITE); } // configure uart diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 51f2f4f..e2f6086 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -55,6 +55,9 @@ extern const void kernel_start; /** Lock for kernel space page tables */ static spinlock_t kslock = SPINLOCK_INIT; +/** This PGD table is initialized in entry.asm */ +extern size_t* boot_map; + /** A self-reference enables direct access to all page tables */ static size_t* self[PAGE_LEVELS] = { (size_t *) 0xFFC00000, @@ -77,6 +80,16 @@ size_t virt_to_phys(size_t addr) return phy | off; } +int page_map_bootmap(size_t viraddr, size_t phyaddr, size_t bits) +{ + if (BUILTIN_EXPECT(viraddr >= PAGE_MAP_ENTRIES*PAGE_SIZE, 0)) + return -EINVAL; + + boot_map[PAGE_MAP_ENTRIES + (viraddr >> PAGE_BITS)] = phyaddr | bits | PG_PRESENT; + + return 0; +} + int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits) { int lvl, ret = -ENOMEM; @@ -259,9 +272,10 @@ int page_init(void) /* Map multiboot information and modules */ if (mb_info) { - addr = (size_t) mb_info & PAGE_MASK; - npages = PAGE_FLOOR(sizeof(*mb_info)) >> PAGE_BITS; - page_map(addr, addr, npages, PG_GLOBAL); + // already mapped => entry.asm + //addr = (size_t) mb_info & PAGE_MASK; + //npages = PAGE_FLOOR(sizeof(*mb_info)) >> PAGE_BITS; + //page_map(addr, addr, npages, PG_GLOBAL); if (mb_info->flags & MULTIBOOT_INFO_MODS) { addr = mb_info->mods_addr;