| // Trivial tar loader. | |
| use core::mem::transmute; | |
| use matcha_hal::dprintf; | |
| const EFLASH_START: u32 = 0x44000000; | |
| const EFLASH_END: u32 = 0x45000000; | |
| #[repr(C, packed)] | |
| pub struct TarHeader { | |
| /* byte offset */ | |
| name: [u8; 100], /* 0 */ | |
| mode: [u8; 8], /* 100 */ | |
| uid: [u8; 8], /* 108 */ | |
| gid: [u8; 8], /* 116 */ | |
| size: [u8; 12], /* 124 */ | |
| mtime: [u8; 12], /* 136 */ | |
| chksum: [u8; 8], /* 148 */ | |
| typeflag: u8, /* 156 */ | |
| linkname: [u8; 100], /* 157 */ | |
| magic: [u8; 6], /* 257 */ | |
| version: [u8; 2], /* 263 */ | |
| uname: [u8; 32], /* 265 */ | |
| gname: [u8; 32], /* 297 */ | |
| devmajor: [u8; 8], /* 329 */ | |
| devminor: [u8; 8], /* 337 */ | |
| prefix: [u8; 155], /* 345 */ | |
| /* 500 */ | |
| } | |
| impl Default for TarHeader { | |
| fn default() -> Self { | |
| return TarHeader { | |
| name: [0; 100], | |
| mode: [0; 8], | |
| uid: [0; 8], | |
| gid: [0; 8], | |
| size: [0; 12], | |
| mtime: [0; 12], | |
| chksum: [0; 8], | |
| typeflag: 0, | |
| linkname: [0; 100], | |
| magic: [0; 6], | |
| version: [0; 2], | |
| uname: [0; 32], | |
| gname: [0; 32], | |
| devmajor: [0; 8], | |
| devminor: [0; 8], | |
| prefix: [0; 155], | |
| }; | |
| } | |
| } | |
| fn parse_octal(text: &[u8]) -> u32 { | |
| let mut n: u32 = 0; | |
| for x in text.iter() { | |
| if *x == (0 as u8) { | |
| break; | |
| } | |
| n = (n << 3) | ((*x as u32) - ('0' as u32)); | |
| } | |
| return n; | |
| } | |
| pub unsafe fn find_file(name: &str) -> (u32, u32) { | |
| let mut cursor = EFLASH_START; | |
| while cursor < EFLASH_END { | |
| let tar_header: *const TarHeader = transmute(cursor); | |
| cursor += 512; | |
| let tar_name = core::str::from_utf8(&(*tar_header).name).unwrap(); | |
| if tar_name.contains(name) { | |
| let tar_size = parse_octal(&(*tar_header).size); | |
| return (cursor, tar_size); | |
| } else { | |
| let tar_size = parse_octal(&(*tar_header).size); | |
| cursor += (tar_size + 511) & !511; | |
| } | |
| } | |
| dprintf!("Could not find tar entry for '{}'\n", name); | |
| return (0, 0); | |
| } |