From 516f4f19206a0f5c15a5aff9d6a800f72ce663f1 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Fri, 14 Oct 2022 21:53:30 -0700 Subject: [PATCH] [boot] Support non-page-aligned program sections in init When the bootloader loads srv.init's program sections into memory, it needed to page-align them if they weren't. srv.init's loader itself handles this case, but the bootloader's did not. --- src/boot/loader.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/boot/loader.cpp b/src/boot/loader.cpp index da1fa35..b7abf62 100644 --- a/src/boot/loader.cpp +++ b/src/boot/loader.cpp @@ -101,19 +101,21 @@ load_program( bootproto::program_section §ion = sections[next_section++]; - size_t page_count = memory::bytes_to_pages(seg.mem_size); + uintptr_t virt_addr = seg.vaddr; + size_t mem_size = seg.mem_size; - if (seg.mem_size > seg.file_size) { - void *pages = g_alloc.allocate_pages(page_count, alloc_type::program, true); - void *source = util::offset_pointer(data.pointer, seg.offset); - g_alloc.copy(pages, source, seg.file_size); - section.phys_addr = reinterpret_cast(pages); - } else { - section.phys_addr = program.base() + seg.offset; - } + // Page-align the section, which may require increasing the size + size_t prelude = virt_addr & 0xfff; + mem_size += prelude; + virt_addr &= ~0xfffull; - section.virt_addr = seg.vaddr; - section.size = seg.mem_size; + size_t page_count = memory::bytes_to_pages(mem_size); + void *pages = g_alloc.allocate_pages(page_count, alloc_type::program, true); + void *source = util::offset_pointer(data.pointer, seg.offset); + g_alloc.copy(util::offset_pointer(pages, prelude), source, seg.file_size); + section.phys_addr = reinterpret_cast(pages); + section.virt_addr = virt_addr; + section.size = mem_size; section.type = static_cast(seg.flags); }