summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-01-29 20:23:53 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-01-29 20:23:53 +0100
commit37db7181daf1cc10683de24f6203e595b2ac49bc (patch)
tree6fd009ef0206a3b2a836fd7d0b2e816f02422816 /kernel
parent81e59db8151915250df68f79f7afde1f1ce8dac3 (diff)
Copy multiboot information.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/entry.c32
-rw-r--r--kernel/kernel.ld6
-rw-r--r--kernel/main.c9
-rw-r--r--kernel/multiboot.h8
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