diff --git a/i386/i386at/biosmem.c b/i386/i386at/biosmem.c index a7a440e..2ca1f61 100644 --- a/i386/i386at/biosmem.c +++ b/i386/i386at/biosmem.c @@ -440,9 +440,34 @@ biosmem_find_boot_data(const struct multiboot_raw_info *mbi, uint32_t min, struct elf_shdr *shdr; uint32_t i, start, end = end; unsigned long tmp; + const struct biosmem_map_entry *entry; start = max; + /* Exclude unmapped areas */ + i = 0; + entry = biosmem_map; + while (entry < biosmem_map + biosmem_map_size) + { + /* Exclude memory before this entry */ + if (i < entry->base_addr) + biosmem_find_boot_data_update(min, &start, &end, i, entry->base_addr); + if (entry->type == BIOSMEM_TYPE_AVAILABLE) + /* Do not exclude this area */ + i = entry->base_addr + entry->length; + else + /* Exclude this area too */ + i = entry->base_addr; + entry++; + } + /* Exclude last entry and anything else beyond */ + if (i < max) + biosmem_find_boot_data_update(min, &start, &end, i, max); + + if (biosmem_heap_cur) + /* Heap is in use */ + biosmem_find_boot_data_update(min, &start, &end, biosmem_heap_cur, biosmem_heap_end); + biosmem_find_boot_data_update(min, &start, &end, _kvtophys(&_start), _kvtophys(&_end)); @@ -738,6 +763,8 @@ biosmem_load_segment(struct biosmem_segment *seg, uint64_t max_phys_end, phys_addr_t avail_start, phys_addr_t avail_end) { unsigned int seg_index; + phys_addr_t start, end, max_start, max_end; + uint32_t next; seg_index = seg - biosmem_segments; @@ -753,6 +780,34 @@ biosmem_load_segment(struct biosmem_segment *seg, uint64_t max_phys_end, phys_end = max_phys_end; } +#ifndef MACH_HYP + max_start = phys_start; + max_end = phys_start; + next = phys_start; + + do { + extern struct multiboot_info boot_info; + + start = next; + end = biosmem_find_boot_data((struct multiboot_raw_info *)&boot_info, start, phys_end, &next); + + if (end == 0) { + end = phys_end; + next = 0; + } + + if ((end - start) > (max_end - max_start)) { + max_start = start; + max_end = end; + } + } while (next != 0); + + max_start = round_page(max_start); + max_end = trunc_page(max_end); + + seg->avail_start = max_start; + seg->avail_end = max_end; +#else if ((avail_start < phys_start) || (avail_start >= phys_end)) avail_start = phys_start; @@ -761,7 +816,9 @@ biosmem_load_segment(struct biosmem_segment *seg, uint64_t max_phys_end, seg->avail_start = avail_start; seg->avail_end = avail_end; - vm_page_load(seg_index, phys_start, phys_end, avail_start, avail_end); +#endif + + vm_page_load(seg_index, phys_start, phys_end, seg->avail_start, seg->avail_end); } void __init