MCPcopy Create free account
hub / github.com/bendudson/EuraliOS / create_user_ondemand_pages

Function create_user_ondemand_pages

kernel/src/memory.rs:325–380  ·  view source on GitHub ↗

Create user-accessible pages, which are allocated on demand ie when written to. One frame is allocated, and made writable through the first page in the range. The other pages point to the same frame but are read-only. Writes to those frames trigger a page fault, and the handler allocates a frame. This allows large user heaps to be created without using a lot of memory. Inputs ------ size Size

(
    level_4_physaddr: u64,
    start_addr: VirtAddr,
    size: u64)

Source from the content-addressed store, hash-verified

323/// size Size of memory region in bytes
324///
325pub fn create_user_ondemand_pages(
326 level_4_physaddr: u64,
327 start_addr: VirtAddr,
328 size: u64)
329 -> Result<(), MapToError<Size4KiB>> {
330
331 let memory_info = unsafe {MEMORY_INFO.as_mut().unwrap()};
332 let frame_allocator = &mut memory_info.frame_allocator;
333
334 let l4_table: &mut PageTable = unsafe {
335 &mut *(memory_info.physical_memory_offset
336 + level_4_physaddr).as_mut_ptr()};
337
338 let mut mapper = unsafe {
339 OffsetPageTable::new(l4_table,
340 memory_info.physical_memory_offset)};
341
342 let page_range = {
343 let end_addr = start_addr + size - 1u64;
344 let start_page = Page::containing_address(start_addr);
345 let end_page = Page::containing_address(end_addr);
346 Page::range_inclusive(start_page, end_page)
347 };
348
349 // Only allocating one frame
350 let frame = frame_allocator
351 .allocate_frame()
352 .ok_or(MapToError::FrameAllocationFailed)?;
353
354 for page in page_range {
355 unsafe {
356 mapper.map_to_with_table_flags(page,
357 frame,
358 // Page not writable
359 PageTableFlags::PRESENT |
360 PageTableFlags::USER_ACCESSIBLE,
361 // Parent table flags include writable
362 PageTableFlags::PRESENT |
363 PageTableFlags::WRITABLE |
364 PageTableFlags::USER_ACCESSIBLE,
365 frame_allocator)?.flush()
366 };
367 }
368
369 // Make one page writable, so this 'owns' the frame
370 unsafe {
371 mapper.update_flags(page_range.start,
372 PageTableFlags::PRESENT |
373 PageTableFlags::WRITABLE |
374 PageTableFlags::USER_ACCESSIBLE)
375 .map_err(|_| MapToError::FrameAllocationFailed)?
376 .flush(); // Update page table
377 }
378
379 Ok(())
380}
381
382/// Map a consecutive set of pages to a consecutive set of frames

Callers 2

new_user_threadFunction · 0.85
new_memory_chunkFunction · 0.85

Calls 2

as_mut_ptrMethod · 0.80
allocate_frameMethod · 0.80

Tested by

no test coverage detected