mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
extend image builder to handle baking in statics
This commit is contained in:
parent
8d19be2784
commit
024c8131bc
3 changed files with 55 additions and 34 deletions
|
|
@ -26,6 +26,7 @@ pkcs8 = { version = "0.8.0", features = ["pem"] }
|
|||
base64 = "0.20.0"
|
||||
rand = "0.8.5"
|
||||
aes-gcm-siv = "0.11.1"
|
||||
bao1x-api = { path = "../libs/bao1x-api" }
|
||||
|
||||
[[bin]]
|
||||
name = "copy-object"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
|
||||
use tools::elf;
|
||||
|
|
@ -10,16 +10,34 @@ fn main() {
|
|||
env_logger::init();
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() < 2 {
|
||||
println!("Usage: {} input.elf [output.bin]", args.get(0).unwrap_or(&"copy-object".to_owned()));
|
||||
println!(
|
||||
"Usage: {} input.elf [output.bin] [--bao1x]",
|
||||
args.get(0).unwrap_or(&"copy-object".to_owned())
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let input_filename = Path::new(args.get(1).unwrap()).to_path_buf();
|
||||
let output_filename = args.get(2).map(|x| Path::new(x).to_path_buf()).unwrap_or_else(|| {
|
||||
|
||||
// Parse remaining arguments
|
||||
let mut output_filename: Option<PathBuf> = None;
|
||||
let mut bao1x_flag = false;
|
||||
|
||||
for arg in args.iter().skip(2) {
|
||||
if arg == "--bao1x" {
|
||||
bao1x_flag = true;
|
||||
} else if output_filename.is_none() {
|
||||
output_filename = Some(Path::new(arg).to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
// Set default output filename if none provided
|
||||
let output_filename = output_filename.unwrap_or_else(|| {
|
||||
let mut output_filename = input_filename.clone();
|
||||
output_filename.set_extension("bin");
|
||||
output_filename
|
||||
});
|
||||
|
||||
if output_filename == input_filename {
|
||||
eprintln!("Input and output filename are the same: {}", output_filename.display());
|
||||
eprintln!("Specify an output path, or change the suffix of your input file from \".bin\"");
|
||||
|
|
@ -33,6 +51,26 @@ fn main() {
|
|||
eprintln!("Couldn't create output file {}: {}", output_filename.display(), e);
|
||||
process::exit(1);
|
||||
});
|
||||
if bao1x_flag {
|
||||
let mut statics = bao1x_api::StaticsInRom {
|
||||
jump_instruction: bao1x_api::JUMP_INSTRUCTION,
|
||||
version: bao1x_api::STATICS_IN_ROM_VERSION,
|
||||
valid_pokes: 0,
|
||||
data_origin: 0,
|
||||
data_size_bytes: 0,
|
||||
poke_table: [(0u32, 0u32); 30],
|
||||
};
|
||||
statics.data_origin = pd.data_offset;
|
||||
statics.data_size_bytes = pd.clear_size;
|
||||
statics.valid_pokes = pd.poke_table.len() as u16;
|
||||
for (&entry, dest) in pd.poke_table.iter().zip(statics.poke_table.iter_mut()) {
|
||||
*dest = entry;
|
||||
}
|
||||
f.write(statics.as_bytes()).unwrap_or_else(|e| {
|
||||
eprintln!("Couldn't write data to {}: {}", output_filename.display(), e);
|
||||
process::exit(1);
|
||||
});
|
||||
}
|
||||
f.write_all(&pd.program).unwrap_or_else(|e| {
|
||||
eprintln!("Couldn't write data to {}: {}", output_filename.display(), e);
|
||||
process::exit(1);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ pub struct ProgramDescription {
|
|||
/// Size of .data section
|
||||
pub data_size: u32,
|
||||
|
||||
/// Poke table for data section; in (address, data) tuples. Addresses are in `u32` format
|
||||
/// because we're packing them for a target that is 32-bits, which may be different from the host.
|
||||
pub poke_table: Vec<(u32, u32)>,
|
||||
|
||||
/// Size of region to be zero-ized by the loader
|
||||
pub clear_size: u32,
|
||||
|
||||
/// Size of the .bss section
|
||||
pub bss_size: u32,
|
||||
|
||||
|
|
@ -156,6 +163,7 @@ pub fn process_program(b: &[u8], rom_only: bool) -> Result<ProgramDescription, E
|
|||
let elf = ElfFile::new(&b).map_err(|x| ElfReadError::ParseElfError(x))?;
|
||||
let entry_point = elf.header.pt2.entry_point() as u32;
|
||||
let mut program_data = Cursor::new(Vec::new());
|
||||
let mut poke_table = Vec::<(u32, u32)>::new();
|
||||
|
||||
let mut size = 0;
|
||||
let mut data_offset = 0;
|
||||
|
|
@ -328,42 +336,12 @@ pub fn process_program(b: &[u8], rom_only: bool) -> Result<ProgramDescription, E
|
|||
debug!("Program size: {} bytes", observed_size);
|
||||
|
||||
if data_offset as usize % size_of::<u32>() == 0 {
|
||||
const SPACING: &'static str = " ";
|
||||
let mut non_zero_tuples = Vec::<(usize, u32)>::new();
|
||||
for (i, chunk) in data_copy.chunks_exact(4).enumerate() {
|
||||
let word = u32::from_le_bytes(chunk.try_into().unwrap());
|
||||
if word != 0 {
|
||||
non_zero_tuples.push((i, word));
|
||||
poke_table.push((i as u32, word));
|
||||
}
|
||||
}
|
||||
println!("Code for loader/baremetal integration:\n");
|
||||
println!("// Define the .data region - bootstrap baremetal using these hard-coded parameters.");
|
||||
println!("const DATA_ORIGIN: usize = 0x{:x};", data_offset);
|
||||
println!(
|
||||
"const DATA_SIZE_BYTES: usize = 0x{:x};",
|
||||
// round up to the nearest u32 word. Includes .data, .bss, .stack, .heap - regions to be zero'd.
|
||||
((data_size + bss_size) as usize + size_of::<u32>() - 1) & !(size_of::<u32>() - 1)
|
||||
);
|
||||
let mut init_str = String::new();
|
||||
init_str.push_str(&format!("const DATA_INIT: [(usize, u32); {}] = [\n", non_zero_tuples.len()));
|
||||
for (offset, data) in non_zero_tuples {
|
||||
init_str.push_str(&format!("{}(0x{:x}, 0x{:x}),\n", SPACING, offset, data));
|
||||
}
|
||||
init_str.push_str(&format!("];"));
|
||||
print!("{}", init_str);
|
||||
let boilerplate = r#"
|
||||
// Clear .data, .bss, .stack, .heap regions & setup .data values
|
||||
unsafe {
|
||||
let data_ptr = DATA_ORIGIN as *mut u32;
|
||||
for i in 0..DATA_SIZE_BYTES / size_of::<u32>() {
|
||||
data_ptr.add(i).write_volatile(0);
|
||||
}
|
||||
for (offset, data) in DATA_INIT {
|
||||
data_ptr.add(offset).write_volatile(data);
|
||||
}
|
||||
}
|
||||
"#;
|
||||
println!("\n{}", boilerplate);
|
||||
} else {
|
||||
println!(
|
||||
"Data section is not word-aligned, check objdump in detail for how to initialize the section"
|
||||
|
|
@ -377,6 +355,10 @@ unsafe {
|
|||
text_offset,
|
||||
text_size,
|
||||
bss_size,
|
||||
// round up to the nearest u32 word. Includes .data, .bss, .stack, .heap - regions to be zero'd.
|
||||
clear_size: (((data_size + bss_size) as usize + size_of::<u32>() - 1) & !(size_of::<u32>() - 1))
|
||||
as u32,
|
||||
poke_table,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue