mirror of https://github.com/ipxe/ipxe.git
[multiboot] try other regions for large modules
Multiboot modules are placed immediately after the primary executable image. If the memory region where the executable is placed is not very large, modules may not fit in that region. Try skipping over holes to see if the module will fit in a subsequent region.pull/350/head
parent
3efdbef2f0
commit
7b8d48197b
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue