2008-08-17 Robert Millan <rmh@aybabtu.com>
* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'. * include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE) (GRUB_MACHINE_MEMORY_RESERVED): New macros. (grub_machine_mmap_iterate): New function declaration. * include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New structure. (GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New macros. * kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'. Move e820 parsing from here ... * kern/i386/pc/mmap.c: New file. (grub_machine_mmap_iterate): ... to here. * include/grub/i386/coreboot/memory.h: Remove `<grub/err.h>'. (GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ... (GRUB_MACHINE_MEMORY_AVAILABLE): ... this. Update all users. (grub_available_iterate): Redeclare to return `void', and redeclare its hook to use grub_uint64_t as addr and size parameters, and rename to ... (grub_machine_mmap_iterate): ... this. Update all users. * kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop to make it more readable. Rename to ... (grub_machine_mmap_iterate): ... this. * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables. (grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions. (grub_multiboot): Allocate an extra region after the payload, and fill it with a Multiboot memory map. Adjust a.out loader to calculate size with the extra space. (grub_multiboot_load_elf32): Adjust elf32 loader to calculate size with the extra space.
This commit is contained in:
parent
9807deb97d
commit
deceb3ecd3
10 changed files with 289 additions and 70 deletions
|
@ -78,14 +78,60 @@ grub_multiboot_unload (void)
|
|||
grub_free ((void *) mbi->cmdline);
|
||||
grub_free (mbi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
mbi = 0;
|
||||
grub_dl_unref (my_mod);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
|
||||
by the spec. Is there something we can do about it? */
|
||||
static grub_uint32_t mmap_addr = 0;
|
||||
static grub_uint32_t mmap_length;
|
||||
|
||||
/* Return the length of the Multiboot mmap that will be needed to allocate
|
||||
our platform's map. */
|
||||
static grub_uint32_t
|
||||
grub_get_multiboot_mmap_len ()
|
||||
{
|
||||
grub_size_t count = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
|
||||
grub_uint64_t size __attribute__ ((unused)),
|
||||
grub_uint32_t type __attribute__ ((unused)))
|
||||
{
|
||||
count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_machine_mmap_iterate (hook);
|
||||
|
||||
return count * sizeof (struct grub_multiboot_mmap_entry);
|
||||
}
|
||||
|
||||
/* Fill previously allocated Multiboot mmap. */
|
||||
static void
|
||||
grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
|
||||
{
|
||||
struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
|
||||
{
|
||||
mmap_entry->addr = addr;
|
||||
mmap_entry->len = size;
|
||||
mmap_entry->type = type;
|
||||
mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size);
|
||||
mmap_entry++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_machine_mmap_iterate (hook);
|
||||
}
|
||||
|
||||
/* Check if BUFFER contains ELF32. */
|
||||
static int
|
||||
grub_multiboot_is_elf32 (void *buffer)
|
||||
|
@ -127,7 +173,7 @@ grub_multiboot_load_elf32 (grub_file_t file, void *buffer)
|
|||
if (phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
|
||||
highest_segment = i;
|
||||
}
|
||||
grub_multiboot_payload_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
|
||||
grub_multiboot_payload_size += (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
|
||||
grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
|
||||
|
||||
playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
|
||||
|
@ -379,6 +425,9 @@ grub_multiboot (int argc, char *argv[])
|
|||
playground = NULL;
|
||||
}
|
||||
|
||||
mmap_length = grub_get_multiboot_mmap_len ();
|
||||
grub_multiboot_payload_size = mmap_length;
|
||||
|
||||
if (header->flags & MULTIBOOT_AOUT_KLUDGE)
|
||||
{
|
||||
int offset = ((char *) header - buffer -
|
||||
|
@ -387,9 +436,9 @@ grub_multiboot (int argc, char *argv[])
|
|||
header->load_end_addr - header->load_addr);
|
||||
|
||||
if (header->bss_end_addr)
|
||||
grub_multiboot_payload_size = (header->bss_end_addr - header->load_addr);
|
||||
grub_multiboot_payload_size += (header->bss_end_addr - header->load_addr);
|
||||
else
|
||||
grub_multiboot_payload_size = load_size;
|
||||
grub_multiboot_payload_size += load_size;
|
||||
grub_multiboot_payload_dest = header->load_addr;
|
||||
|
||||
playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
|
||||
|
@ -416,6 +465,12 @@ grub_multiboot (int argc, char *argv[])
|
|||
goto fail;
|
||||
|
||||
|
||||
grub_fill_multiboot_mmap ((struct grub_mmap_entry *) (grub_multiboot_payload_orig
|
||||
+ grub_multiboot_payload_size
|
||||
- mmap_length));
|
||||
|
||||
mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mmap_length;
|
||||
|
||||
if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
|
||||
{
|
||||
grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward));
|
||||
|
@ -439,11 +494,14 @@ grub_multiboot (int argc, char *argv[])
|
|||
|
||||
grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
|
||||
|
||||
mbi->flags = MULTIBOOT_INFO_MEMORY;
|
||||
|
||||
/* Convert from bytes to kilobytes. */
|
||||
mbi->mem_lower = grub_lower_mem / 1024;
|
||||
mbi->mem_upper = grub_upper_mem / 1024;
|
||||
mbi->flags |= MULTIBOOT_INFO_MEMORY;
|
||||
|
||||
mbi->mmap_addr = mmap_addr;
|
||||
mbi->mmap_length = mmap_length;
|
||||
mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
|
||||
|
||||
for (i = 0, len = 0; i < argc; i++)
|
||||
len += grub_strlen (argv[i]) + 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue