mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
Fix address-marking bugs
* Non-blocksize-aligned regions could fail to be found. Have the bootloader load them aligned. * Consolidating used frame blocks in the bootstrap means these would have been impossible to free as address space * mark_permanent wasn't actually removing blocks from the free list
This commit is contained in:
@@ -14,13 +14,20 @@ loader_alloc_pages(
|
||||
EFI_BOOT_SERVICES *bootsvc,
|
||||
EFI_MEMORY_TYPE mem_type,
|
||||
size_t *length,
|
||||
void **pages)
|
||||
void **pages,
|
||||
bool align)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
|
||||
size_t page_count = ((*length - 1) / PAGE_SIZE) + 1;
|
||||
EFI_PHYSICAL_ADDRESS addr = (EFI_PHYSICAL_ADDRESS)*pages;
|
||||
|
||||
if (align) {
|
||||
// Align addr to the next multiple of N pages
|
||||
size_t align_size = page_count * PAGE_SIZE;
|
||||
addr = ((addr - 1) & ~(align_size - 1)) + align_size;
|
||||
}
|
||||
|
||||
status = bootsvc->AllocatePages(AllocateAddress, mem_type, page_count, &addr);
|
||||
if (status == EFI_NOT_FOUND || status == EFI_OUT_OF_RESOURCES) {
|
||||
// couldn't get the address we wanted, try loading the kernel anywhere
|
||||
@@ -66,7 +73,8 @@ loader_load_initrd(
|
||||
bootsvc,
|
||||
memtype_initrd,
|
||||
&data->initrd_length,
|
||||
&data->initrd);
|
||||
&data->initrd,
|
||||
true);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating pages");
|
||||
|
||||
status = file->Read(file, &data->initrd_length, data->initrd);
|
||||
@@ -153,7 +161,7 @@ loader_load_elf(
|
||||
|
||||
length = prog_header.mem_size;
|
||||
void *addr = (void *)(prog_header.vaddr - KERNEL_VIRT_ADDRESS);
|
||||
status = loader_alloc_pages(bootsvc, memtype_kernel, &length, &addr);
|
||||
status = loader_alloc_pages(bootsvc, memtype_kernel, &length, &addr, false);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating kernel pages");
|
||||
|
||||
if (data->kernel == 0)
|
||||
@@ -239,7 +247,8 @@ loader_load_kernel(
|
||||
bootsvc,
|
||||
memtype_data,
|
||||
&data->data_length,
|
||||
&data->data);
|
||||
&data->data,
|
||||
true);
|
||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_alloc_pages: kernel data");
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
@@ -304,7 +304,6 @@ memory_initialize(uint16_t scratch_pages, const void *memory_map, size_t map_len
|
||||
|
||||
// Now go back through these lists and consolidate
|
||||
block_slab.append(frame_block::consolidate(free));
|
||||
block_slab.append(frame_block::consolidate(used));
|
||||
|
||||
region_allocator region_slab(page_size, allocator);
|
||||
region_slab.allocate(); // Allocate some buddy regions for the address_manager
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace kutil {
|
||||
|
||||
using address_manager =
|
||||
buddy_allocator<
|
||||
16, // Min allocation: 64KiB
|
||||
12, // Min allocation: 4KiB
|
||||
36 // Max allocation: 64GiB
|
||||
>;
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ public:
|
||||
for (unsigned i = size_max; i >= size_min; --i) {
|
||||
for (auto *r : free_bucket(i)) {
|
||||
if (start >= r->address && end <= r->end()) {
|
||||
free_bucket(i).remove(r);
|
||||
delete_region(r, start, end);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user