diff --git a/src/arch/x86/image/multiboot.c b/src/arch/x86/image/multiboot.c index 0c85df708..59ef0ca4f 100644 --- a/src/arch/x86/image/multiboot.c +++ b/src/arch/x86/image/multiboot.c @@ -178,6 +178,36 @@ static physaddr_t multiboot_add_cmdline ( struct image *image ) { return virt_to_phys ( mb_cmdline ); } +static int multiboot_find_new_start ( struct image *image, physaddr_t *start ) { + struct memory_map memmap; + unsigned int i; + unsigned int current; + + get_memmap ( &memmap ); + + /* Find the current region: */ + for ( i = 0 ; i < memmap.count ; i++ ) { + if ( *start >= memmap.regions[i].start && + *start < memmap.regions[i].end ) { + current = i; + goto found; + } + } + + DBGC ( image, "MULTIBOOT could not find region for %lx\n", *start); + return -ENOENT; + +found: + if ( current + 1 < memmap.count ) { + *start = memmap.regions[current + 1].start; + DBGC ( image, "MULTIBOOT skipping ahead to %lx\n", *start); + return 0; + } + + DBGC ( image, "MULTIBOOT no more regions to try" ); + return -ENOMEM; +} + /** * Add multiboot modules * @@ -208,6 +238,7 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start, if ( module_image == image ) continue; +again: /* Page-align the module */ start = ( ( start + 0xfff ) & ~0xfff ); @@ -218,6 +249,13 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start, DBGC ( image, "MULTIBOOT %p could not prepare module " "%s: %s\n", image, module_image->name, strerror ( rc ) ); + + DBGC ( image, "MULTIBOOT trying to find another " + "memory region\n" ); + if ( multiboot_find_new_start ( image, &start ) == 0 ) { + goto again; + } + return rc; }