diff cos/kernel/multiboot.c @ 37:5c20bd53cccd

Cleanup
author windel
date Mon, 16 Jan 2012 21:38:55 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cos/kernel/multiboot.c	Mon Jan 16 21:38:55 2012 +0100
@@ -0,0 +1,60 @@
+#include "kernel.h"
+
+multiboot_info_t *multiboot_info = 0; // Set by startup code.
+uint64_t available_memory = 0;
+uint64_t ramdisk_location = 0;
+
+/* Retrieve memory information from multiboot header */
+void read_multiboot_info()
+{
+   if ((multiboot_info->flags & (1 << 6)) == (1 << 6))
+   {
+      multiboot_memory_map_t *mmap;
+      for (mmap = (multiboot_memory_map_t*)(uint64_t)multiboot_info->mmap_addr; 
+            (uint64_t)mmap < multiboot_info->mmap_addr + multiboot_info->mmap_length; 
+            mmap = (multiboot_memory_map_t*) ( (uint64_t)mmap + mmap->size + sizeof(mmap->size)) )
+      {
+         /*
+         printf("size: %d, start: 0x%x, length=0x%x, type=%d\n", mmap->size, 
+            mmap->base, mmap->length, mmap->type);
+         */
+
+         if ( (mmap->type == 1) && (mmap->base == 0x100000) )
+         {
+            available_memory = mmap->length;
+         }
+      }
+   }
+
+   if (available_memory == 0)
+   {
+      panic("Found no usable memory in grub's memory map\n");
+   }
+
+   if ((multiboot_info->flags & (1 << 3)) == (1 << 3))
+   {
+      uint64_t i;
+      multiboot_module_t *mod = (multiboot_module_t*)(uint64_t)multiboot_info->mods_addr;
+      for (i=0; i<multiboot_info->mods_count; i++)
+      {
+         // TODO: determine better way of finding the initrd module.
+         if (i == 0)
+         {
+            ramdisk_location = mod->mod_start;
+         }
+
+         // Make sure that placement malloc does not overwrite the ramdisk.
+         uint64_t new_placement = (uint64_t)mod->mod_end;
+         if (new_placement > placement_address)
+         {
+            if ((new_placement & 0xFFF) != 0)
+            {
+               new_placement = (new_placement & (~0xFFF)) + 0x1000; // Align to 4 KiB page.
+            }
+            placement_address = new_placement;
+         }
+         mod++; // Go to next module.
+      }
+   }
+}
+