Skip to content
Snippets Groups Projects
Commit ddcd1374 authored by Michael Hauspie's avatar Michael Hauspie
Browse files

Start adding a link command

parent 7b17bbaf
Branches
Tags
1 merge request!1Add a new `link` subcommand
...@@ -325,6 +325,12 @@ dependencies = [ ...@@ -325,6 +325,12 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "elf"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
...@@ -755,6 +761,14 @@ dependencies = [ ...@@ -755,6 +761,14 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "pip-mpu-relocate"
version = "0.1.0"
dependencies = [
"elf",
"thiserror",
]
[[package]] [[package]]
name = "pip-tool" name = "pip-tool"
version = "0.1.0" version = "0.1.0"
...@@ -762,6 +776,8 @@ dependencies = [ ...@@ -762,6 +776,8 @@ dependencies = [
"anyhow", "anyhow",
"cargo-scaffold", "cargo-scaffold",
"clap", "clap",
"elf",
"pip-mpu-relocate",
] ]
[[package]] [[package]]
......
...@@ -19,3 +19,6 @@ name = "pip-tool" ...@@ -19,3 +19,6 @@ name = "pip-tool"
anyhow = "1.0.81" anyhow = "1.0.81"
cargo-scaffold = "0.12.0" cargo-scaffold = "0.12.0"
clap = "4.5.2" clap = "4.5.2"
elf = "0.7.4"
pip-mpu-relocate = { path = "../pip-mpu-relocate" }
...@@ -2,35 +2,43 @@ ...@@ -2,35 +2,43 @@
//! //!
//! Internally, it uses cargo-scaffold to create a new folder from a git template //! Internally, it uses cargo-scaffold to create a new folder from a git template
use anyhow::Result;
use clap::Parser; use clap::Parser;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::Result;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
pub struct Opts { pub struct Opts {
/// The path where to generate your project /// The path where to generate your crate
project_path: PathBuf, crate_path: PathBuf,
/// The name of the generated project. If omitted, deduced from /// The name of the generated project. If omitted, deduced from
/// the project_path parameter /// the project_path parameter
#[arg(long, short)] #[arg(long, short)]
project_name: Option<String> crate_name: Option<String>,
} }
const PIP_MPU_TEMPLATE_PATH: &str =
const PIP_MPU_TEMPLATE_PATH: &str = "https://gitlab.univ-lille.fr/2xs/pip/pip-mpu-armv7-template.git"; "https://gitlab.univ-lille.fr/2xs/pip/pip-mpu-armv7-template.git";
pub fn generate(opts: Opts) -> Result<()> { pub fn generate(opts: Opts) -> Result<()> {
let crate_name = match opts.crate_name {
Some(name) => name,
None => opts
.crate_path
.file_name()
.unwrap()
.to_os_string()
.into_string()
.unwrap()
};
let scaffold_opts = cargo_scaffold::Opts::builder(PIP_MPU_TEMPLATE_PATH) let scaffold_opts = cargo_scaffold::Opts::builder(PIP_MPU_TEMPLATE_PATH)
.parameters(vec!["crate_name=TODO_CHANGE", "project-name=TODO_CHANGE"]) .parameters(vec![
format!("crate_name={}", crate_name),
])
.force(true) .force(true)
.project_name(match opts.project_name { .project_name(crate_name)
Some(name) => name, .target_dir(opts.crate_path);
None => opts.project_path.file_name().unwrap().to_os_string().into_string().unwrap(),
})
.target_dir(opts.project_path);
cargo_scaffold::ScaffoldDescription::new(scaffold_opts)?.scaffold() cargo_scaffold::ScaffoldDescription::new(scaffold_opts)?.scaffold()
} }
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
mod generate; mod generate;
mod link;
use anyhow::Result; use anyhow::Result;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
...@@ -16,11 +17,15 @@ pub struct Opts { ...@@ -16,11 +17,15 @@ pub struct Opts {
pub enum PipToolSubcommand { pub enum PipToolSubcommand {
/// Generate a new pip partition project /// Generate a new pip partition project
Generate(generate::Opts), Generate(generate::Opts),
/// Link elf files together and generate a binary blob ready to be
/// flashed/loaded
Link(link::Opts),
} }
pub fn execute(opts: Opts) -> Result<()> { pub fn execute(opts: Opts) -> Result<()> {
match opts.command { match opts.command {
PipToolSubcommand::Generate(gen_opts) => generate::generate(gen_opts)? PipToolSubcommand::Generate(opts) => generate::generate(opts)?,
PipToolSubcommand::Link(opts) => link::link(opts)?,
} }
Ok(()) Ok(())
} }
//! This module performs the binary file generation for the user
//! partition code
//!
//! It takes at least 2 elf files:
//! - CRT0 : the crt0 (elf) built from the `pip-mpu-crt0` crate
//! - USER_CODE : the user code (elf) built from the user code rust crate
//!
//! If only 2 elf files are provided, it will generate a binary file, suitable for beeing loaded
//! by xipfs
//!
//! It can optionaly take pip mpu elf file and, in that case, it
//! generates a binary that includes Pip MPU and the user code as root
//! partition
use anyhow::Result;
use clap::Parser;
use elf::endian::AnyEndian;
use std::path::PathBuf;
use pip_mpu_relocate::reloc::RelIter;
use pip_mpu_relocate::relocate::relocate;
use pip_mpu_relocate::symbols::SymbolsQuery;
use std::io::Write;
/// Options for the link subcommand
#[derive(Parser, Debug)]
pub struct Opts {
/// Path to CRT0 elf file
crt0_elf: PathBuf,
/// Path to the usr code elf file
user_code_elf: PathBuf,
/// Path to the output binary file to generate
output: PathBuf,
/// Path the Pipcore MPU elf file
#[arg(long, short)]
pip_elf: Option<PathBuf>
}
pub fn link(opts: Opts) -> Result<()> {
// First, open and parse both crt0 and user_code elf files
let crt0_elf_file = std::fs::read(&opts.crt0_elf)?;
let crt0_elf_data = crt0_elf_file.as_slice();
let crt0_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(crt0_elf_data)?;
let user_code_elf_file = std::fs::read(&opts.user_code_elf)?;
let user_code_elf_data = user_code_elf_file.as_slice();
let user_code_elf = elf::ElfBytes::<AnyEndian>::minimal_parse(user_code_elf_data)?;
// Then open Pip elf file if necessary
let pip_elf_data = match opts.pip_elf {
None => None,
Some(pip_path) => {
Some(std::fs::read(&pip_path)?)
}
};
let pip_elf = match pip_elf_data {
None => None,
Some(ref vec) => Some(elf::ElfBytes::<AnyEndian>::minimal_parse(vec)?),
};
// When reaching here, all files were opened and parsed
// we can safely open the output file
let mut output = std::fs::File::create(opts.output)?;
writeln!(output, "Yeah it works")?;
Ok(())
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment