firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
0

Configure Feed

Select the types of activity you want to include in your feed.

1use std::path::PathBuf; 2use clap::Parser; 3use elf::abi::PT_LOAD; 4use elf::ElfBytes; 5use elf::endian::LittleEndian; 6 7#[derive(Parser, Debug)] 8#[command(version, about, long_about = None)] 9struct Args { 10 #[arg(short)] 11 in_file: PathBuf, 12 13 #[arg(short)] 14 out_file: PathBuf, 15} 16 17fn main() { 18 let args = Args::parse(); 19 20 let elf_data = std::fs::read(args.in_file).expect("Failed to open ELF file"); 21 22 let elf = ElfBytes::<LittleEndian>::minimal_parse(&elf_data) 23 .expect("Failed to parse ELF file"); 24 25 // Copy all the LOAD segments, like objcopy -O binary 26 let mut bin: Vec<u8> = Vec::new(); 27 28 let mut data_paddr = 0u32; 29 let mut data_vaddr = 0u32; 30 let mut data_len = 0u32; 31 let mut current_addr: Option<u32> = None; 32 33 for phdr in elf.segments().expect("Failed to parse ELF file") { 34 if phdr.p_type == PT_LOAD { 35 if current_addr.is_none() { 36 current_addr.replace(phdr.p_vaddr as u32); 37 } 38 39 let current_addr = current_addr.as_mut().unwrap(); 40 41 if *current_addr < phdr.p_vaddr as u32 { 42 let diff = phdr.p_vaddr as u32 - *current_addr; 43 for _ in 0..diff { 44 bin.push(0); 45 } 46 } 47 48 let segment_data = elf.segment_data(&phdr).expect("Failed to parse ELF file"); 49 bin.extend_from_slice(segment_data); 50 *current_addr += segment_data.len() as u32; 51 } 52 53 // Assume that there is at most one segment that needs to be copied from flash to RAM 54 // (i.e. the segment containing .data) 55 if phdr.p_paddr != phdr.p_vaddr { 56 data_paddr = phdr.p_paddr as u32; 57 data_vaddr = phdr.p_vaddr as u32; 58 data_len = phdr.p_memsz as u32; 59 } 60 } 61 62 let mut bss_paddr = 0u32; 63 let mut bss_len = 0u32; 64 if let Some(bss) = elf.section_header_by_name(".bss") 65 .expect("Failed to parse ELF file") 66 { 67 bss_paddr = bss.sh_addr as u32; 68 bss_len = bss.sh_size as u32; 69 } 70 71 let len = bin.len() as u32; 72 73 // Add missing EPB header entries 74 bin[8..12].copy_from_slice(&len.to_le_bytes()); // len 75 bin[12..16].copy_from_slice(&data_len.to_le_bytes()); // data_len 76 bin[16..20].copy_from_slice(&data_paddr.to_le_bytes()); // data_lma 77 bin[20..24].copy_from_slice(&data_vaddr.to_le_bytes()); // data_vma 78 bin[24..28].copy_from_slice(&bss_len.to_le_bytes()); // bss_len 79 bin[28..32].copy_from_slice(&bss_paddr.to_le_bytes()); // bss_vma 80 81 let crc = crc32fast::hash(&bin[8..]); 82 bin[4..8].copy_from_slice(&crc.to_le_bytes()); // crc 83 84 std::fs::write(args.out_file, &bin).expect("Failed to write output"); 85}