diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2010-01-29 20:23:53 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2010-01-29 20:23:53 +0100 |
commit | 37db7181daf1cc10683de24f6203e595b2ac49bc (patch) | |
tree | 6fd009ef0206a3b2a836fd7d0b2e816f02422816 | |
parent | 81e59db8151915250df68f79f7afde1f1ce8dac3 (diff) |
Copy multiboot information.
-rw-r--r-- | kernel/entry.c | 32 | ||||
-rw-r--r-- | kernel/kernel.ld | 6 | ||||
-rw-r--r-- | kernel/main.c | 9 | ||||
-rw-r--r-- | kernel/multiboot.h | 8 |
4 files changed, 46 insertions, 9 deletions
diff --git a/kernel/entry.c b/kernel/entry.c index 61ac82b..28bdb12 100644 --- a/kernel/entry.c +++ b/kernel/entry.c @@ -8,6 +8,7 @@ extern void addr_load_virt; extern void addr_load_virt_end; extern void entry_stack; +extern void entry_multiboot; extern uint32_t entry_pagedir[]; extern uint32_t entry_pagetable_low[]; @@ -26,8 +27,9 @@ asm( void entry_serial_out(char* str); void entry_serial_out_hex(uint32_t x); +void entry_copy_multiboot(multiboot_info_t* mb_info); -void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { +void entry_main(uint32_t mb_magic, multiboot_info_t* mb_info) { entry_serial_out("entry_main()\n"); if(mb_magic != 0x2badb002) { entry_serial_out("Multiboot magic word is wrong!\n"); @@ -35,8 +37,9 @@ void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { } entry_serial_out("Multiboot ok\n"); - // TODO: Copy multiboot information. + entry_copy_multiboot(mb_info); + /* entry_serial_out("Flags: "); entry_serial_out_hex(mb_info->flags); @@ -49,6 +52,7 @@ void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { entry_serial_out("Module addr: "); entry_serial_out_hex(mb_info->mods_addr->mod_start); + */ // Create initial page tables. for(unsigned int i = 0; i < 1024; i++) { @@ -67,6 +71,8 @@ void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { } } + entry_pagetable_high[((uint32_t)&multiboot_info & 0x003ff000) >> 12] = (uint32_t)&entry_multiboot | 0x003; + entry_pagedir[(uint32_t)&addr_phys >> 22] = (uint32_t)&entry_pagetable_low | 0x007; entry_pagedir[(uint32_t)&addr_virt >> 22] = (uint32_t)&entry_pagetable_high | 0x003; @@ -80,7 +86,7 @@ void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { "mov %%cr0, %0\n" "or $0x80000000, %0\n" "mov %0, %%cr0\n" - : : "r" (&entry_pagedir) : "%0" + :: "r" (&entry_pagedir) : "%0" ); // TODO: Check that segments are loaded and mapped right. @@ -98,7 +104,25 @@ void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { while(1); } -#define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port)); +#define memcpy(source, target, size) asm volatile( \ + "cld\n" \ + "rep movsd\n" \ + :: "S" (source), "D" (target), "c" (size / 4) \ + : "flags", "memory") + +void entry_copy_multiboot(multiboot_info_t* mb_info) { + // Copy multiboot structure. + memcpy(mb_info, &entry_multiboot, sizeof(multiboot_info_t)); + uint32_t low_p = (uint32_t)&entry_multiboot + sizeof(multiboot_info_t); + uint32_t high_p = (uint32_t)&multiboot_info + sizeof(multiboot_info_t); + // Copy module structures. + memcpy(mb_info->mods_addr, low_p, mb_info->mods_count * sizeof(multiboot_module_t)); + multiboot_info.mods_addr = (multiboot_module_t*)high_p; + low_p += mb_info->mods_count * sizeof(multiboot_module_t); + high_p += mb_info->mods_count * sizeof(multiboot_module_t); +} + +#define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port)) void entry_serial_out(char* str) { while(*str) { diff --git a/kernel/kernel.ld b/kernel/kernel.ld index ab294ee..28f63c7 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -30,7 +30,8 @@ SECTIONS { entry_pagetable_low = .; . += 0x1000; entry_pagetable_high = .; . += 0x1000; entry_stack = .; . += 0x1000; entry_stack_top = .; - + entry_multiboot = .; . += 0x1000; + kernel/entry.o(.bss) } @@ -55,4 +56,7 @@ SECTIONS { *(COMMON) } + . = ALIGN(0x1000); + multiboot_info = .; . += 0x1000; + } diff --git a/kernel/main.c b/kernel/main.c index 93647f5..5cc94d3 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2,6 +2,7 @@ #include "gdt.h" #include "idt.h" #include "irq.h" +#include "multiboot.h" void main() { printf("main()\n"); @@ -15,6 +16,11 @@ void main() { irq_init(); printf("IRQs set.\n"); + printf("Multiboot flags: %08x\n", multiboot_info.flags); + for(int i = 0; i < multiboot_info.mods_count; i++) { + printf("Module %u: %08x %08x %s\n", i, multiboot_info.mods_addr[0].mod_start, multiboot_info.mods_addr[0].mod_end, multiboot_info.mods_addr[0].string); + } + asm volatile("sti"); asm volatile( @@ -22,8 +28,9 @@ void main() { "push $entry_stack_top\n" "pushf\n" "push $0x1b\n" - "push $0x0010a000\n" + "push %0\n" "iret\n" + :: "r" (multiboot_info.mods_addr[0].mod_start) ); printf("Halting.\n"); diff --git a/kernel/multiboot.h b/kernel/multiboot.h index 93a5c30..ffc3d25 100644 --- a/kernel/multiboot.h +++ b/kernel/multiboot.h @@ -8,7 +8,7 @@ typedef struct { uint32_t mod_end; char* string; uint32_t reserved; -} multiboot_module; +} multiboot_module_t; typedef struct { uint32_t flags; @@ -21,7 +21,7 @@ typedef struct { char* cmdline; uint32_t mods_count; - multiboot_module* mods_addr; + multiboot_module_t* mods_addr; union { uint32_t foo[3]; @@ -45,6 +45,8 @@ typedef struct { uint32_t vbe_interface_seg; uint32_t vbe_interface_off; uint32_t vbe_interface_len; -} multiboot_info; +} multiboot_info_t; + +extern multiboot_info_t multiboot_info; #endif |