diff --git a/Changelog.md b/Changelog.md index 2c409bbf..24cd6238 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Unreleased + +- [Fix map errors during kernel loading](https://github.com/rust-osdev/bootloader/pull/422) + - Don't error if a kernel page is already mapped to the correct frame + - Fix: unmap temp page again to enable multiple bss-like sections + # 0.9.25 – 2024-02-16 - [Fix data layout for custom targets for LLVM 18](https://github.com/rust-osdev/bootloader/pull/421) diff --git a/src/page_table.rs b/src/page_table.rs index ed2ac136..c666de79 100644 --- a/src/page_table.rs +++ b/src/page_table.rs @@ -96,8 +96,15 @@ pub(crate) fn map_segment( for frame in PhysFrame::range_inclusive(start_frame, end_frame) { let offset = frame - start_frame; let page = start_page + offset; - unsafe { map_page(page, frame, page_table_flags, page_table, frame_allocator)? } - .flush(); + match unsafe { + map_page(page, frame, page_table_flags, page_table, frame_allocator) + } { + Ok(flusher) => flusher.flush(), + Err(MapToError::PageAlreadyMapped(to)) if to == frame => { + // nothing to do, page is already mapped to the correct frame + } + Err(err) => return Err(err), + } } if mem_size > file_size { @@ -117,7 +124,7 @@ pub(crate) fn map_segment( unsafe { map_page( temp_page.clone(), - new_frame.clone(), + new_frame, page_table_flags, page_table, frame_allocator, @@ -145,6 +152,11 @@ pub(crate) fn map_segment( }); } + // unmap temp page again + let (new_frame, flusher) = page_table.unmap(temp_page).unwrap(); + flusher.flush(); + + // map last page to new frame unsafe { map_page( last_page,