diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2009-12-26 21:15:05 +0100 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2009-12-26 21:15:05 +0100 |
commit | a35e29c07873db467e0ca670290666f8786dab03 (patch) | |
tree | 93ca3d311b76a8259f6883d3f32d1eabfefea60b /kernel | |
parent | f57cbe8ecdb4f6ecb22618de361d4fcaee3fdcf3 (diff) |
First steps reading multiboot info. Added GDT.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/SConscript | 2 | ||||
-rw-r--r-- | kernel/entry.c | 25 | ||||
-rw-r--r-- | kernel/gdt.c | 28 | ||||
-rw-r--r-- | kernel/gdt.h | 28 | ||||
-rw-r--r-- | kernel/main.c | 6 | ||||
-rw-r--r-- | kernel/multiboot.h | 43 |
6 files changed, 129 insertions, 3 deletions
diff --git a/kernel/SConscript b/kernel/SConscript index 87fcb1f..d9988ac 100644 --- a/kernel/SConscript +++ b/kernel/SConscript @@ -27,4 +27,4 @@ kernel_bld = Builder( env.Append(BUILDERS = {'Kernel' : kernel_bld}) -kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c']) +kernel = env.Kernel('kernel', ['kernel.ld', 'entry.c', 'main.c', 'gdt.c']) diff --git a/kernel/entry.c b/kernel/entry.c index d040cfb..4dd2ee1 100644 --- a/kernel/entry.c +++ b/kernel/entry.c @@ -1,4 +1,5 @@ #include "types.h" +#include "multiboot.h" extern void addr_phys; extern void addr_virt; @@ -18,13 +19,15 @@ asm( ".globl entry\n" "entry:\n" "mov $entry_stack_top,%esp\n" + "push %ebx\n" "push %eax\n" "call entry_main\n" ); void entry_serial_out(char* str); +void entry_serial_out_hex(uint32_t x); -void entry_main(uint32_t mb_magic, void* mb_info) { +void entry_main(uint32_t mb_magic, multiboot_info* mb_info) { entry_serial_out("entry_main()\n"); if(mb_magic != 0x2badb002) { entry_serial_out("Multiboot magic word is wrong!\n"); @@ -34,6 +37,17 @@ void entry_main(uint32_t mb_magic, void* mb_info) { // TODO: Copy multiboot information. + entry_serial_out("Flags: "); + entry_serial_out_hex(mb_info->flags); + + if(mb_info->flags & (1 << 2)) { + entry_serial_out(mb_info->cmdline); + entry_serial_out("\n"); + } else { + entry_serial_out("No cmdline.\n"); + } + + // Create initial page tables. for(unsigned int i = 0; i < 1024; i++) { // Clear page directory. @@ -90,3 +104,12 @@ void entry_serial_out(char* str) { outb(0x3f8, *str++); } } + +void entry_serial_out_hex(uint32_t x) { + char str[] = "00000000\n"; + for(int i = 0; i < 8; i++) { + int z = (x >> (28 - i * 4)) & 0xf; + str[i] = z < 10 ? '0' + z : 'a' - 10 + z; + } + entry_serial_out(str); +} diff --git a/kernel/gdt.c b/kernel/gdt.c new file mode 100644 index 0000000..7d23289 --- /dev/null +++ b/kernel/gdt.c @@ -0,0 +1,28 @@ +#include "gdt.h" + +gdt_entry gdt[] = { + gdt_entry_init(0, 0, 0), + gdt_entry_init(0, 0xfffff, 0xc09a), // Code segment. + gdt_entry_init(0, 0xfffff, 0xc092), // Data segment. + gdt_entry_init(0, 0xfffff, 0xc0fa), // User mode code segment. + gdt_entry_init(0, 0xfffff, 0xc0f2), // User mode data segment. +}; + +gdt_ptr gdtr = { + .base = gdt, + .limit = sizeof(gdt) - 1 +}; + +void gdt_init() { + asm volatile( + "lgdt (%0)\n" + "mov %w1, %%ds\n" + "mov %w1, %%es\n" + "mov %w1, %%fs\n" + "mov %w1, %%gs\n" + "mov %w1, %%ss\n" + "ljmp $0x08, $.flush\n" + ".flush:\n" + : : "r" (&gdtr), "r" (0x10) + ); +} diff --git a/kernel/gdt.h b/kernel/gdt.h new file mode 100644 index 0000000..e2c5b46 --- /dev/null +++ b/kernel/gdt.h @@ -0,0 +1,28 @@ +#ifndef GDT_H +#define GDT_H + +#include "types.h" + +typedef struct { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_mid; + uint16_t flags; + uint8_t base_high; +} __attribute__((packed)) gdt_entry; + +typedef struct { + uint16_t limit; + gdt_entry* base; +} __attribute__((packed)) gdt_ptr; + +#define gdt_entry_init(b, l, f) { \ + .base_low = (b & 0xffff), \ + .base_mid = (b >> 16 & 0xff), \ + .base_high = (b >> 24 & 0xff), \ + .limit_low = (l & 0xffff), \ + .flags = (f | (l >> 8 & 0x0f00))} + +void gdt_init(); + +#endif diff --git a/kernel/main.c b/kernel/main.c index 513894b..25ad1f1 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,3 +1,4 @@ +#include "gdt.h" void kernel_serial_out(char* str); @@ -5,7 +6,10 @@ void main() { kernel_serial_out("main()\n"); - // TODO: GDT. + gdt_init(); + kernel_serial_out("GDT set.\n"); + + kernel_serial_out("Halting.\n"); asm volatile( "cli\n" diff --git a/kernel/multiboot.h b/kernel/multiboot.h new file mode 100644 index 0000000..5a9e348 --- /dev/null +++ b/kernel/multiboot.h @@ -0,0 +1,43 @@ +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include "types.h" + +typedef struct { + uint32_t flags; + + uint32_t mem_lower; + uint32_t mem_upper; + + uint32_t boot_device; + + char* cmdline; + + uint32_t mods_count; + uint32_t mods_addr; + + union { + uint32_t foo[3]; + } syms; + + uint32_t mmap_length; + uint32_t mmap_addr; + + uint32_t drives_length; + uint32_t drives_addr; + + uint32_t config_table; + + uint32_t boot_loader_name; + + uint32_t apm_table; + + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint32_t vbe_mode; + uint32_t vbe_interface_seg; + uint32_t vbe_interface_off; + uint32_t vbe_interface_len; +} multiboot_info; + +#endif |