unsafe fn context_switch(
    addresses: Addresses,
    mut kernel_page_table: OffsetPageTable,
    mut frame_allocator: impl FrameAllocator<Size4KiB>,
) -> ! {
    // identity-map current and next frame, so that we don't get an immediate pagefault
    // after switching the active page table
    let current_addr = PhysAddr::new(registers::read_rip().as_u64());
    let current_frame: PhysFrame = PhysFrame::containing_address(current_addr);
    for frame in PhysFrame::range_inclusive(current_frame, current_frame + 1) {
        unsafe {
            kernel_page_table.identity_map(frame, PageTableFlags::PRESENT, &mut frame_allocator)
        }
        .unwrap()
        .flush();
    }

    // we don't need the kernel page table anymore
    mem::drop(kernel_page_table);

    // do the context switch
    unsafe {
        asm!(
            "mov cr3, {}; mov rsp, {}; push 0; jmp {}",
            in(reg) addresses.page_table.start_address().as_u64(),
            in(reg) addresses.stack_top.as_u64(),
            in(reg) addresses.entry_point.as_u64(),
            in("rdi") addresses.boot_info as *const _ as usize,
        );
    }
    unreachable!();
}
/// Performs the actual context switch.
///
/// This function uses the given `frame_allocator` to identity map itself in the kernel-level
/// page table. This is required to avoid a page fault after the context switch. Since this
/// function is relatively small, only up to two physical frames are required from the frame
/// allocator, so the [`TwoFrames`] type can be used here.
Performs the actual context switch.
This function uses the given `frame_allocator` to identity map itself in the kernel-level
page table. This is required to avoid a page fault after the context switch. Since this
function is relatively small, only up to two physical frames are required from the frame
allocator, so the [`TwoFrames`] type can be used here.
Performs the actual context switch . This function uses the given ` frame_allocator ` to identity map itself in the kernel - level page table . This is required to avoid a page fault after the context switch . Since this function is relatively small only up to two physical frames are required from the frame allocator so the [ ` TwoFrames ` ] type can be used here .
unsafe fn context_switch(
    addresses: Addresses,
    mut kernel_page_table: OffsetPageTable,
    mut frame_allocator: impl FrameAllocator<Size4KiB>,
) -> ! {
    // identity-map current and next frame, so that we don't get an immediate pagefault
    // after switching the active page table
    let current_addr = PhysAddr::new(registers::read_rip().as_u64());
    let current_frame: PhysFrame = PhysFrame::containing_address(current_addr);
    for frame in PhysFrame::range_inclusive(current_frame, current_frame + 1) {
        unsafe {
            kernel_page_table.identity_map(frame, PageTableFlags::PRESENT, &mut frame_allocator)
        }
        .unwrap()
        .flush();
    }
    // we don't need the kernel page table anymore
    mem::drop(kernel_page_table);
    // do the context switch
    unsafe {
        asm!(
            "mov cr3, {}; mov rsp, {}; push 0; jmp {}",
            in(reg) addresses.page_table.start_address().as_u64(),
            in(reg) addresses.stack_top.as_u64(),
            in(reg) addresses.entry_point.as_u64(),
            in("rdi") addresses.boot_info as *const _ as usize,
        );
    }
    unreachable!();
}
unsafe fn context_switch ( addresses : Addresses , mut kernel_page_table : OffsetPageTable , mut frame_allocator : impl FrameAllocator < Size4KiB > , ) -> ! { // identity-map current and next frame, so that we don't get an immediate pagefault // after switching the active page table let current_addr = PhysAddr :: new ( registers :: read_rip ( ) . as_u64 ( ) ) ; let current_frame : PhysFrame = PhysFrame :: containing_address ( current_addr ) ; for frame in PhysFrame :: range_inclusive ( current_frame , current_frame + 1 ) { unsafe { kernel_page_table . identity_map ( frame , PageTableFlags :: PRESENT , & mut frame_allocator ) } . unwrap ( ) . flush ( ) ; } // we don't need the kernel page table anymore mem :: drop ( kernel_page_table ) ; // do the context switch unsafe { asm ! ( " " in ( reg ) addresses page_table start_address ( ) as_u64 ( ) in ( reg ) addresses stack_top as_u64 ( ) in ( reg ) addresses entry_point as_u64 ( ) in ( " " ) addresses boot_info as const as usize ) ; } unreachable ! ( ) ; }
Performs the actual context switch.
Performs the actual context switch .
addresses
Addresses
kernel_page_table
OffsetPageTable
frame_allocator
impl FrameAllocator<Size4KiB>
addresses
Addresses
kernel_page_table
OffsetPageTable
frame_allocator
impl FrameAllocator<Size4KiB>