-
Notifications
You must be signed in to change notification settings - Fork 115
Add a runner for libtock2 examples. #365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
2c45730
Add a runner for libtock2 examples.
4f34598
Install Ninja in the CI workflow, as QEMU now requires it.
e2505b5
Remove the libtock-rs 1.0 integration tests, as they do not pass with…
dc96125
Address review feedback:
22b0cc6
runner: Add support for multiple platforms in the QEMU deployer.
a67900f
Add a `kernel-opentitan` make action that builds an OpenTitan kernel …
46916e1
Fix variable name in the QEMU deployer: tab_path -> tbf_path, and cla…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[package] | ||
authors = ["Tock Project Developers <[email protected]>"] | ||
description = """Tool used to run libtock-rs process binaries.""" | ||
edition = "2018" | ||
license = "Apache-2.0 OR MIT" | ||
name = "runner" | ||
publish = false | ||
repository = "https://www.github.com/tock/libtock-rs" | ||
version = "0.1.0" | ||
|
||
[dependencies] | ||
clap = { features = ["derive"], version = "3.0.10" } | ||
elf = "0.0.10" | ||
libc = "0.2.113" | ||
termion = "1.5.6" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
use super::Cli; | ||
use std::fs::{metadata, remove_file}; | ||
use std::io::ErrorKind; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
|
||
// Converts the ELF file specified on the command line into TBF and TAB files, | ||
// and returns the paths to those files. | ||
pub fn convert_elf(cli: &Cli) -> OutFiles { | ||
let package_name = cli.elf.file_stem().expect("ELF must be a file"); | ||
let mut tab_path = cli.elf.clone(); | ||
tab_path.set_extension("tab"); | ||
let protected_size = TBF_HEADER_SIZE.to_string(); | ||
if cli.verbose { | ||
println!("Package name: {:?}", package_name); | ||
println!("TAB path: {}", tab_path.display()); | ||
println!("Protected region size: {}", protected_size); | ||
} | ||
let stack_size = read_stack_size(cli); | ||
let elf = cli.elf.as_os_str(); | ||
let mut tbf_path = cli.elf.clone(); | ||
tbf_path.set_extension("tbf"); | ||
if cli.verbose { | ||
println!("ELF file: {:?}", elf); | ||
println!("TBF path: {}", tbf_path.display()); | ||
} | ||
|
||
// If elf2tab returns a successful status but does not write to the TBF | ||
// file, then we run the risk of using an outdated TBF file, creating a | ||
// hard-to-debug situation. Therefore, we delete the TBF file, forcing | ||
// elf2tab to create it, and later verify that it exists. | ||
if let Err(io_error) = remove_file(&tbf_path) { | ||
// Ignore file-no-found errors, panic on any other error. | ||
if io_error.kind() != ErrorKind::NotFound { | ||
panic!("Unable to remove the TBF file. Error: {}", io_error); | ||
} | ||
} | ||
|
||
let mut command = Command::new("elf2tab"); | ||
#[rustfmt::skip] | ||
command.args([ | ||
// TODO: libtock-rs' crates are designed for Tock 2.1's Allow interface, | ||
// so we should increment this as soon as the Tock kernel will accept a | ||
// 2.1 app. | ||
"--kernel-major".as_ref(), "2".as_ref(), | ||
"--kernel-minor".as_ref(), "0".as_ref(), | ||
"-n".as_ref(), package_name, | ||
"-o".as_ref(), tab_path.as_os_str(), | ||
"--protected-region-size".as_ref(), protected_size.as_ref(), | ||
"--stack".as_ref(), stack_size.as_ref(), | ||
elf, | ||
]); | ||
if cli.verbose { | ||
command.arg("-v"); | ||
println!("elf2tab command: {:?}", command); | ||
println!("Spawning elf2tab"); | ||
} | ||
let mut child = command.spawn().expect("failed to spawn elf2tab"); | ||
let status = child.wait().expect("failed to wait for elf2tab"); | ||
if cli.verbose { | ||
println!("elf2tab finished. {}", status); | ||
} | ||
assert!(status.success(), "elf2tab returned an error. {}", status); | ||
|
||
// Verify that elf2tab created the TBF file, and that it is a file. | ||
match metadata(&tbf_path) { | ||
Err(io_error) => { | ||
if io_error.kind() == ErrorKind::NotFound { | ||
panic!("elf2tab did not create {}", tbf_path.display()); | ||
} | ||
panic!( | ||
"Unable to query metadata for {}: {}", | ||
tbf_path.display(), | ||
io_error | ||
); | ||
} | ||
Ok(metadata) => { | ||
assert!(metadata.is_file(), "{} is not a file", tbf_path.display()); | ||
} | ||
} | ||
|
||
OutFiles { tab_path, tbf_path } | ||
} | ||
|
||
// Paths to the files output by elf2tab. | ||
pub struct OutFiles { | ||
pub tab_path: PathBuf, | ||
pub tbf_path: PathBuf, | ||
} | ||
|
||
// The amount of space to reserve for the TBF header. This must match the | ||
// TBF_HEADER_SIZE value in the layout file for the platform, which is currently | ||
// 0x48 for all platforms. | ||
const TBF_HEADER_SIZE: u32 = 0x48; | ||
alistair23 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Reads the stack size, and returns it as a String for use on elf2tab's command | ||
// line. | ||
fn read_stack_size(cli: &Cli) -> String { | ||
let file = elf::File::open_path(&cli.elf).expect("Unable to open ELF"); | ||
for section in file.sections { | ||
// This section name comes from runtime/libtock_layout.ld, and it | ||
// matches the size (and location) of the process binary's stack. | ||
if section.shdr.name == ".stack" { | ||
let stack_size = section.shdr.size.to_string(); | ||
if cli.verbose { | ||
println!("Found .stack section, size: {}", stack_size); | ||
} | ||
return stack_size; | ||
} | ||
} | ||
|
||
panic!("Unable to find the .stack section in {}", cli.elf.display()); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
mod elf2tab; | ||
mod output_processor; | ||
mod qemu; | ||
mod tockloader; | ||
|
||
use clap::{ArgEnum, Parser}; | ||
use std::env::{var, VarError}; | ||
use std::path::PathBuf; | ||
|
||
/// Converts ELF binaries into Tock Binary Format binaries and runs them on a | ||
/// Tock system. | ||
#[derive(Debug, Parser)] | ||
pub struct Cli { | ||
/// Where to deploy the process binary. If not specified, runner will only | ||
/// make a TBF file and not attempt to run it. | ||
#[clap(arg_enum, long, short)] | ||
deploy: Option<Deploy>, | ||
|
||
/// The executable to convert into Tock Binary Format and run. | ||
elf: PathBuf, | ||
|
||
/// Whether to output verbose debugging information to the console. | ||
#[clap(long, short)] | ||
verbose: bool, | ||
} | ||
|
||
#[derive(ArgEnum, Clone, Copy, Debug)] | ||
pub enum Deploy { | ||
Qemu, | ||
Tockloader, | ||
} | ||
|
||
fn main() { | ||
let cli = Cli::parse(); | ||
let paths = elf2tab::convert_elf(&cli); | ||
let deploy = match cli.deploy { | ||
None => return, | ||
Some(deploy) => deploy, | ||
}; | ||
let platform = match var("LIBTOCK_PLATFORM") { | ||
Err(VarError::NotPresent) => { | ||
panic!("LIBTOCK_PLATFORM must be specified to deploy") | ||
} | ||
Err(VarError::NotUnicode(platform)) => { | ||
panic!("Non-UTF-8 LIBTOCK_PLATFORM value: {:?}", platform) | ||
} | ||
Ok(platform) => platform, | ||
}; | ||
if cli.verbose { | ||
println!("Detected platform {}", platform); | ||
} | ||
let child = match deploy { | ||
Deploy::Qemu => qemu::deploy(&cli, platform, paths.tbf_path), | ||
Deploy::Tockloader => tockloader::deploy(&cli, platform, paths.tab_path), | ||
}; | ||
output_processor::process(&cli, child); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.