Use bootloader provided initrd instead of copying it
This commit is contained in:
parent
3ef75dcfbc
commit
9b7e36056a
@ -204,22 +204,28 @@ fn get_buffer(id: u64) -> Option<Box<[u8], &'static ASpaceMutex>> {
|
|||||||
static REGISTERD_PIDS: Lazy<RwLock<HashMap<u64, u64>>> = Lazy::new(|| RwLock::new(HashMap::new()));
|
static REGISTERD_PIDS: Lazy<RwLock<HashMap<u64, u64>>> = Lazy::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
static INITRD_BUF: Lazy<&'static [u8]> = Lazy::new(|| {
|
static INITRD_BUF: Lazy<&'static [u8]> = Lazy::new(|| {
|
||||||
|
#[warn(clippy::expect_used, reason = "FIXME")]
|
||||||
|
let ramdisk_start = BOOTINFO.ramdisk_addr.into_option().expect("initrd not present");
|
||||||
|
let ramdisk_len = BOOTINFO.ramdisk_len;
|
||||||
let initrd = unsafe {
|
let initrd = unsafe {
|
||||||
#[warn(clippy::expect_used, reason = "FIXME")]
|
|
||||||
let ramdisk_start = BOOTINFO.ramdisk_addr.into_option().expect("initrd not present");
|
|
||||||
let ramdisk_len = BOOTINFO.ramdisk_len;
|
|
||||||
slice::from_raw_parts(
|
slice::from_raw_parts(
|
||||||
ptr::with_exposed_provenance::<u8>(usize(ramdisk_start)),
|
ptr::with_exposed_provenance::<u8>(usize(ramdisk_start)),
|
||||||
usize(ramdisk_len),
|
usize(ramdisk_len),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
KERNEL_SPACE.lock().alloc_force_user = true;
|
let initrd_start_page = Page::containing_address(VirtAddr::new(ramdisk_start));
|
||||||
let initrd = Box::leak(
|
let initrd_num_pages = usize(ramdisk_len.div_ceil(4096));
|
||||||
Vec::with_capacity_in(initrd.len(), &*KERNEL_SPACE)
|
unsafe {
|
||||||
.tap_mut(|v| v.extend_from_slice(initrd))
|
KERNEL_SPACE
|
||||||
.into_boxed_slice(),
|
.lock()
|
||||||
);
|
.update_flags(
|
||||||
KERNEL_SPACE.lock().alloc_force_user = false;
|
initrd_start_page,
|
||||||
|
initrd_num_pages,
|
||||||
|
PageTableFlags::USER_ACCESSIBLE,
|
||||||
|
PageTableFlags::empty(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
initrd
|
initrd
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use x86_64::{
|
|||||||
registers::control::Cr3,
|
registers::control::Cr3,
|
||||||
structures::paging::{
|
structures::paging::{
|
||||||
frame::PhysFrameRange,
|
frame::PhysFrameRange,
|
||||||
mapper::{MapToError, MappedFrame, TranslateResult, UnmapError},
|
mapper::{FlagUpdateError, MapToError, MappedFrame, TranslateResult, UnmapError},
|
||||||
page::PageRange,
|
page::PageRange,
|
||||||
FrameAllocator, FrameDeallocator, Mapper, OffsetPageTable, Page, PageTable, PageTableFlags,
|
FrameAllocator, FrameDeallocator, Mapper, OffsetPageTable, Page, PageTable, PageTableFlags,
|
||||||
PhysFrame, Size4KiB, Translate,
|
PhysFrame, Size4KiB, Translate,
|
||||||
@ -79,6 +79,15 @@ impl From<UnmapError> for PagingError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<FlagUpdateError> for PagingError {
|
||||||
|
fn from(err: FlagUpdateError) -> Self {
|
||||||
|
match err {
|
||||||
|
FlagUpdateError::PageNotMapped => Self::PageNotMapped,
|
||||||
|
FlagUpdateError::ParentEntryHugePage => Self::ParentEntryHugePage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SAFETY: from_start_address_unchecked requires that the given address is page (4 KiB) aligned,
|
// SAFETY: from_start_address_unchecked requires that the given address is page (4 KiB) aligned,
|
||||||
// which means that the lower 12 bits are zero. We shift the page number left 12 bits, so the lower
|
// which means that the lower 12 bits are zero. We shift the page number left 12 bits, so the lower
|
||||||
// 12 bits will always be zero.
|
// 12 bits will always be zero.
|
||||||
@ -696,6 +705,43 @@ impl AddressSpace {
|
|||||||
Ok(dest_range_start)
|
Ok(dest_range_start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn update_flags(
|
||||||
|
&mut self,
|
||||||
|
page: Page,
|
||||||
|
num_pages: usize,
|
||||||
|
set_flags: PageTableFlags,
|
||||||
|
clear_flags: PageTableFlags,
|
||||||
|
) -> Result<(), PagingError> {
|
||||||
|
self.check_request_valid(page, num_pages)?;
|
||||||
|
#[expect(
|
||||||
|
clippy::arithmetic_side_effects,
|
||||||
|
reason = "check_request_valid guarentees this won't overflow"
|
||||||
|
)]
|
||||||
|
for page in (PageRange { start: page, end: page + u64(num_pages) }) {
|
||||||
|
let TranslateResult::Mapped { frame: _, offset: 0, flags } =
|
||||||
|
self.mapper.translate(page.start_address())
|
||||||
|
else {
|
||||||
|
return Err(PagingError::PageNotMapped);
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
self.mapper.update_flags(page, (flags | set_flags) & !(clear_flags))?.flush();
|
||||||
|
self.mapper.set_flags_p3_entry(
|
||||||
|
page,
|
||||||
|
PageTableFlags::PRESENT
|
||||||
|
| PageTableFlags::WRITABLE
|
||||||
|
| PageTableFlags::USER_ACCESSIBLE,
|
||||||
|
)?.flush_all();
|
||||||
|
self.mapper.set_flags_p2_entry(
|
||||||
|
page,
|
||||||
|
PageTableFlags::PRESENT
|
||||||
|
| PageTableFlags::WRITABLE
|
||||||
|
| PageTableFlags::USER_ACCESSIBLE,
|
||||||
|
)?.flush_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds a range of free pages and returns the starting page
|
/// Finds a range of free pages and returns the starting page
|
||||||
fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> {
|
fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> {
|
||||||
if num_pages == 0 {
|
if num_pages == 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user