blob: f57154c2fa0943987de1c7fcddf809417eb1b944 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::Result;
use assembly_tool::Tool;
use camino::Utf8PathBuf;
/// A builder that receives a sparse FVM, and prepares it for nand flashing.
///
/// ```
/// let builder = NandFvmBuilder {
/// output: Utf8PathBuf::from("path/to/output.blk"),
/// sparse_fvm: Utf8PathBuf::from("path/to/fvm.sparse.blk"),
/// max_disk_size: None,
/// compression: None,
/// page_size: 0,
/// oob_size: 0,
/// pages_per_block: 0,
/// block_count: 0,
/// };
/// builder.build();
/// ```
pub struct NandFvmBuilder {
/// The fvm host tool.
pub tool: Box<dyn Tool>,
/// The path to write the FVM to.
pub output: Utf8PathBuf,
/// The path to the sparse FVM on the host.
pub sparse_fvm: Utf8PathBuf,
/// The maximum disk size for the sparse FVM.
/// The build will fail if the sparse FVM is larger than this.
pub max_disk_size: Option<u64>,
/// The compression algorithm to use.
pub compression: Option<String>,
/// The nand page size.
pub page_size: u64,
/// The out of bound size.
pub oob_size: u64,
/// The pages per block.
pub pages_per_block: u64,
/// The number of blocks.
pub block_count: u64,
}
impl NandFvmBuilder {
/// Build the FVM.
pub fn build(self) -> Result<()> {
let args = self.build_args()?;
self.tool.run(&args)
}
fn build_args(&self) -> Result<Vec<String>> {
let mut args: Vec<String> = Vec::new();
args.push(self.output.to_string());
args.push("ftl-raw-nand".to_string());
// Append key and value to the `args` if the value is present.
fn maybe_append_value(
args: &mut Vec<String>,
key: impl AsRef<str>,
value: Option<impl std::string::ToString>,
) {
if let Some(value) = value {
args.push(format!("--{}", key.as_ref()));
args.push(value.to_string());
}
}
maybe_append_value(&mut args, "nand-page-size", Some(self.page_size));
maybe_append_value(&mut args, "nand-oob-size", Some(self.oob_size));
maybe_append_value(&mut args, "nand-pages-per-block", Some(self.pages_per_block));
maybe_append_value(&mut args, "nand-block-count", Some(self.block_count));
maybe_append_value(&mut args, "max-disk-size", self.max_disk_size);
maybe_append_value(&mut args, "compress", self.compression.as_ref());
// A quirk of the FVM tool means the sparse argument *must* go last.
maybe_append_value(&mut args, "sparse", Some(self.sparse_fvm.to_string()));
Ok(args)
}
}
#[cfg(test)]
mod tests {
use super::*;
use assembly_tool::testing::FakeToolProvider;
use assembly_tool::ToolProvider;
#[test]
fn nand_args() {
let tools = FakeToolProvider::default();
let fvm_tool = tools.get_tool("fvm").unwrap();
let builder = NandFvmBuilder {
tool: fvm_tool,
output: "mypath".into(),
sparse_fvm: "sparsepath".into(),
max_disk_size: Some(500),
compression: Some("supercompress".into()),
page_size: 1,
oob_size: 2,
pages_per_block: 3,
block_count: 4,
};
let args = builder.build_args().unwrap();
assert_eq!(
args,
[
"mypath",
"ftl-raw-nand",
"--nand-page-size",
"1",
"--nand-oob-size",
"2",
"--nand-pages-per-block",
"3",
"--nand-block-count",
"4",
"--max-disk-size",
"500",
"--compress",
"supercompress",
"--sparse",
"sparsepath",
]
);
}
}