grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) { grub_uint32_t cont; struct grub_machine_mmap_entry *entry = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; grub_memset (entry, 0, sizeof (entry)); /* Check if grub_get_mmap_entry works. */ cont = grub_get_mmap_entry (entry, 0); if (entry->size) do { if (hook (entry->addr, entry->len, /* GRUB mmaps have been defined to match with the E820 definition. Therefore, we can just pass type through. */ entry->type, hook_data)) break; if (! cont) break; grub_memset (entry, 0, sizeof (entry)); cont = grub_get_mmap_entry (entry, cont); } while (entry->size); else { grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10, GRUB_MEMORY_AVAILABLE, hook_data)) return 0; if (eisa_mmap) { if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MEMORY_AVAILABLE, hook_data) == 0) hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE, hook_data); } else hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10, GRUB_MEMORY_AVAILABLE, hook_data); } return 0; }
void grub_machine_init (void) { int i; int grub_lower_mem; /* Initialize the console as early as possible. */ grub_console_init (); grub_lower_mem = grub_get_conv_memsize () << 10; /* Sanity check. */ if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END) grub_fatal ("too small memory"); /* FIXME: This prevents loader/i386/linux.c from using low memory. When our heap implements support for requesting a chunk in low memory, this should no longer be a problem. */ #if 0 /* Add the lower memory into free memory. */ if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END) add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END, grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END); #endif auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type) { /* Avoid the lower memory. */ if (addr < 0x100000) { if (size <= 0x100000 - addr) return 0; size -= 0x100000 - addr; addr = 0x100000; } /* Ignore >4GB. */ if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE) { grub_size_t len; len = (grub_size_t) ((addr + size > 0xFFFFFFFF) ? 0xFFFFFFFF - addr : size); add_mem_region (addr, len); } return 0; } grub_machine_mmap_iterate (hook); compact_mem_regions (); for (i = 0; i < num_regions; i++) grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size); grub_tsc_init (); }