pub fn create_boot_info<I, D>(
    mut frame_allocator: LegacyFrameAllocator<I, D>,
    page_tables: &mut PageTables,
    mappings: &mut Mappings,
    system_info: SystemInfo,
) -> (&'static mut BootInfo, TwoFrames)
where
    I: ExactSizeIterator<Item = D> + Clone,
    D: LegacyMemoryRegion,
{
    log::info!("Allocate bootinfo");

    // allocate and map space for the boot info
    let (boot_info, memory_regions) = {
        let boot_info_addr = boot_info_location(&mut mappings.used_entries);
        let boot_info_end = boot_info_addr + mem::size_of::<BootInfo>();
        let memory_map_regions_addr =
            boot_info_end.align_up(u64::from_usize(mem::align_of::<MemoryRegion>()));
        let regions = frame_allocator.len() + 1; // one region might be split into used/unused
        let memory_map_regions_end =
            memory_map_regions_addr + regions * mem::size_of::<MemoryRegion>();

        let start_page = Page::containing_address(boot_info_addr);
        let end_page = Page::containing_address(memory_map_regions_end - 1u64);
        for page in Page::range_inclusive(start_page, end_page) {
            let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
            let frame = frame_allocator
                .allocate_frame()
                .expect("frame allocation for boot info failed");
            unsafe {
                page_tables
                    .kernel
                    .map_to(page, frame, flags, &mut frame_allocator)
            }
            .unwrap()
            .flush();
            // we need to be able to access it too
            unsafe {
                page_tables
                    .bootloader
                    .map_to(page, frame, flags, &mut frame_allocator)
            }
            .unwrap()
            .flush();
        }

        let boot_info: &'static mut MaybeUninit<BootInfo> =
            unsafe { &mut *boot_info_addr.as_mut_ptr() };
        let memory_regions: &'static mut [MaybeUninit<MemoryRegion>] =
            unsafe { slice::from_raw_parts_mut(memory_map_regions_addr.as_mut_ptr(), regions) };
        (boot_info, memory_regions)
    };

    // reserve two unused frames for context switch
    let two_frames = TwoFrames::new(&mut frame_allocator);

    log::info!("Create Memory Map");

    // build memory map
    let memory_regions = frame_allocator.construct_memory_map(memory_regions);

    log::info!("Create bootinfo");

    // create boot info
    let boot_info = boot_info.write(BootInfo {
        version_major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
        version_minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
        version_patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
        pre_release: !env!("CARGO_PKG_VERSION_PRE").is_empty(),
        memory_regions: memory_regions.into(),
        framebuffer: mappings
            .framebuffer
            .map(|addr| FrameBuffer {
                buffer_start: addr.as_u64(),
                buffer_byte_len: system_info.framebuffer_info.byte_len,
                info: system_info.framebuffer_info,
            })
            .into(),
        physical_memory_offset: mappings.physical_memory_offset.map(VirtAddr::as_u64).into(),
        recursive_index: mappings.recursive_index.map(Into::into).into(),
        rsdp_addr: system_info.rsdp_addr.map(|addr| addr.as_u64()).into(),
        tls_template: mappings.tls_template.into(),
    });

    (boot_info, two_frames)
}
/// Allocates and initializes the boot info struct and the memory map.
///
/// The boot info and memory map are mapped to both the kernel and bootloader
/// address space at the same address. This makes it possible to return a Rust
/// reference that is valid in both address spaces. The necessary physical frames
/// are taken from the given `frame_allocator`.
Allocates and initializes the boot info struct and the memory map.
The boot info and memory map are mapped to both the kernel and bootloader
address space at the same address. This makes it possible to return a Rust
reference that is valid in both address spaces. The necessary physical frames
are taken from the given `frame_allocator`.
Allocates and initializes the boot info struct and the memory map . The boot info and memory map are mapped to both the kernel and bootloader address space at the same address . This makes it possible to return a Rust reference that is valid in both address spaces . The necessary physical frames are taken from the given ` frame_allocator ` .
pub fn create_boot_info<I, D>(
    mut frame_allocator: LegacyFrameAllocator<I, D>,
    page_tables: &mut PageTables,
    mappings: &mut Mappings,
    system_info: SystemInfo,
) -> (&'static mut BootInfo, TwoFrames)
where
    I: ExactSizeIterator<Item = D> + Clone,
    D: LegacyMemoryRegion,
{
    log::info!("Allocate bootinfo");
    // allocate and map space for the boot info
    let (boot_info, memory_regions) = {
        let boot_info_addr = boot_info_location(&mut mappings.used_entries);
        let boot_info_end = boot_info_addr + mem::size_of::<BootInfo>();
        let memory_map_regions_addr =
            boot_info_end.align_up(u64::from_usize(mem::align_of::<MemoryRegion>()));
        let regions = frame_allocator.len() + 1; // one region might be split into used/unused
        let memory_map_regions_end =
            memory_map_regions_addr + regions * mem::size_of::<MemoryRegion>();
        let start_page = Page::containing_address(boot_info_addr);
        let end_page = Page::containing_address(memory_map_regions_end - 1u64);
        for page in Page::range_inclusive(start_page, end_page) {
            let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
            let frame = frame_allocator
                .allocate_frame()
                .expect("frame allocation for boot info failed");
            unsafe {
                page_tables
                    .kernel
                    .map_to(page, frame, flags, &mut frame_allocator)
            }
            .unwrap()
            .flush();
            // we need to be able to access it too
            unsafe {
                page_tables
                    .bootloader
                    .map_to(page, frame, flags, &mut frame_allocator)
            }
            .unwrap()
            .flush();
        }
        let boot_info: &'static mut MaybeUninit<BootInfo> =
            unsafe { &mut *boot_info_addr.as_mut_ptr() };
        let memory_regions: &'static mut [MaybeUninit<MemoryRegion>] =
            unsafe { slice::from_raw_parts_mut(memory_map_regions_addr.as_mut_ptr(), regions) };
        (boot_info, memory_regions)
    };
    // reserve two unused frames for context switch
    let two_frames = TwoFrames::new(&mut frame_allocator);
    log::info!("Create Memory Map");
    // build memory map
    let memory_regions = frame_allocator.construct_memory_map(memory_regions);
    log::info!("Create bootinfo");
    // create boot info
    let boot_info = boot_info.write(BootInfo {
        version_major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
        version_minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
        version_patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
        pre_release: !env!("CARGO_PKG_VERSION_PRE").is_empty(),
        memory_regions: memory_regions.into(),
        framebuffer: mappings
            .framebuffer
            .map(|addr| FrameBuffer {
                buffer_start: addr.as_u64(),
                buffer_byte_len: system_info.framebuffer_info.byte_len,
                info: system_info.framebuffer_info,
            })
            .into(),
        physical_memory_offset: mappings.physical_memory_offset.map(VirtAddr::as_u64).into(),
        recursive_index: mappings.recursive_index.map(Into::into).into(),
        rsdp_addr: system_info.rsdp_addr.map(|addr| addr.as_u64()).into(),
        tls_template: mappings.tls_template.into(),
    });
    (boot_info, two_frames)
}
pub fn create_boot_info < I , D > ( mut frame_allocator : LegacyFrameAllocator < I , D > , page_tables : & mut PageTables , mappings : & mut Mappings , system_info : SystemInfo , ) -> ( & ' static mut BootInfo , TwoFrames ) where I : ExactSizeIterator < Item = D > + Clone , D : LegacyMemoryRegion , { log :: info ! ( " " ) ; // allocate and map space for the boot info let ( boot_info , memory_regions ) = { let boot_info_addr = boot_info_location ( & mut mappings . used_entries ) ; let boot_info_end = boot_info_addr + mem :: size_of :: < BootInfo > ( ) ; let memory_map_regions_addr = boot_info_end . align_up ( u64 :: from_usize ( mem :: align_of :: < MemoryRegion > ( ) ) ) ; let regions = frame_allocator . len ( ) + 1 ; // one region might be split into used/unused let memory_map_regions_end = memory_map_regions_addr + regions * mem :: size_of :: < MemoryRegion > ( ) ; let start_page = Page :: containing_address ( boot_info_addr ) ; let end_page = Page :: containing_address ( memory_map_regions_end - 1u64 ) ; for page in Page :: range_inclusive ( start_page , end_page ) { let flags = PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE ; let frame = frame_allocator . allocate_frame ( ) . expect ( " " ) ; unsafe { page_tables . kernel . map_to ( page , frame , flags , & mut frame_allocator ) } . unwrap ( ) . flush ( ) ; // we need to be able to access it too unsafe { page_tables . bootloader . map_to ( page , frame , flags , & mut frame_allocator ) } . unwrap ( ) . flush ( ) ; } let boot_info : & ' static mut MaybeUninit < BootInfo > = unsafe { & mut * boot_info_addr . as_mut_ptr ( ) } ; let memory_regions : & ' static mut [ MaybeUninit < MemoryRegion > ] = unsafe { slice :: from_raw_parts_mut ( memory_map_regions_addr . as_mut_ptr ( ) , regions ) } ; ( boot_info , memory_regions ) } ; // reserve two unused frames for context switch let two_frames = TwoFrames :: new ( & mut frame_allocator ) ; log :: info ! ( " " ) ; // build memory map let memory_regions = frame_allocator . construct_memory_map ( memory_regions ) ; log :: info ! ( " " ) ; // create boot info let boot_info = boot_info . write ( BootInfo { version_major : env ! ( " " ) . parse ( ) . unwrap ( ) , version_minor : env ! ( " " ) . parse ( ) . unwrap ( ) , version_patch : env ! ( " " ) . parse ( ) . unwrap ( ) , pre_release : ! env ! ( " " ) . is_empty ( ) , memory_regions : memory_regions . into ( ) , framebuffer : mappings . framebuffer . map ( | addr | FrameBuffer { buffer_start : addr . as_u64 ( ) , buffer_byte_len : system_info . framebuffer_info . byte_len , info : system_info . framebuffer_info , } ) . into ( ) , physical_memory_offset : mappings . physical_memory_offset . map ( VirtAddr :: as_u64 ) . into ( ) , recursive_index : mappings . recursive_index . map ( Into :: into ) . into ( ) , rsdp_addr : system_info . rsdp_addr . map ( | addr | addr . as_u64 ( ) ) . into ( ) , tls_template : mappings . tls_template . into ( ) , } ) ; ( boot_info , two_frames ) }
Allocates and initializes the boot info struct and the memory map.
Allocates and initializes the boot info struct and the memory map .
frame_allocator
LegacyFrameAllocator<I, D>
page_tables
&mut PageTables
mappings
&mut Mappings
system_info
SystemInfo
frame_allocator
LegacyFrameAllocator<I, D>
page_tables
&mut PageTables
mappings
&mut Mappings
system_info
SystemInfo