| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 | use elf_rs::{ElfFile, ProgramHeaderEntry, ProgramType};use multiboot2::{    BootLoaderNameTag, CommandLineTag, MemoryArea, MemoryAreaType, MemoryMapTag,    ModuleTag,};/// Loads the first module into memory. Assumes that the module is a ELF file./// The handoff is performed according to the Multiboot2 spec.pub fn load_module(mut modules: multiboot::information::ModuleIter) -> ! {    // Load the ELF from the Multiboot1 boot module.    let elf_mod = modules.next().expect("Should have payload");    let elf_bytes = unsafe {        core::slice::from_raw_parts(            elf_mod.start as *const u64 as *const u8,            (elf_mod.end - elf_mod.start) as usize,        )    };    let elf = elf_rs::Elf32::from_bytes(elf_bytes).expect("Should be valid ELF");    // Check if a header is present.    {        let hdr = multiboot2_header::Multiboot2Header::find_header(elf_bytes)            .unwrap()            .expect("Should have Multiboot2 header");        let hdr =            unsafe { multiboot2_header::Multiboot2Header::load(hdr.0.as_ptr().cast()) }.unwrap();        log::info!("Multiboot2 header:\n{hdr:#?}");    }    // Map the load segments into memory (at their corresponding link).    {        let elf = elf_rs::Elf32::from_bytes(elf_bytes).expect("Should be valid ELF");        elf.program_header_iter()            .filter(|ph| ph.ph_type() == ProgramType::LOAD)            .for_each(|ph| {                map_memory(ph);            });    }    // Currently, the MBI is not enriched with "real" information as requested.    // Subject here is not to write a feature-complete bootloader but to test    // that the basic data structures are usable.    // build MBI    let mbi = multiboot2::builder::InformationBuilder::new()        .bootloader_name_tag(BootLoaderNameTag::new("mb2_integrationtest_chainloader"))        .command_line_tag(CommandLineTag::new("chainloaded YEAH"))        // random non-sense memory map        .memory_map_tag(MemoryMapTag::new(&[MemoryArea::new(            0,            0xffffffff,            MemoryAreaType::Reserved,        )]))        .add_module_tag(ModuleTag::new(            elf_mod.start as u32,            elf_mod.end as u32,            elf_mod.string.unwrap(),        ))        .build();    log::info!(        "Handing over to ELF: {}",        elf_mod.string.unwrap_or("<unknown>")    );    // handoff    unsafe {        core::arch::asm!(        "jmp *%ecx",        in("eax") multiboot2::MAGIC,        in("ebx") mbi.as_ptr() as u32,        in("ecx") elf.entry_point() as u32,        options(noreturn, att_syntax));    }}/// Blindly copies the LOAD segment content at its desired address in physical/// address space. The loader assumes that the addresses to not clash with the/// loader (or anything else).fn map_memory(ph: ProgramHeaderEntry) {    log::debug!("Mapping LOAD segment {ph:#?}");    let dest_ptr = ph.vaddr() as *mut u8;    let content = ph.content().expect("Should have content");    unsafe { core::ptr::copy(content.as_ptr(), dest_ptr, content.len()) };    let dest_ptr = unsafe { dest_ptr.add(ph.filesz() as usize) };    // Zero .bss memory    for _ in 0..(ph.memsz() - ph.filesz()) {        unsafe {            core::ptr::write(dest_ptr, 0);        }    }}
 |