Merge "Create host-side tool to attach bootconfig to initrd image"
This commit is contained in:
commit
5f7b640f82
|
@ -0,0 +1,13 @@
|
|||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
rust_binary_host {
|
||||
name: "initrd_bootconfig",
|
||||
srcs: ["src/main.rs"],
|
||||
rustlibs: [
|
||||
"libanyhow",
|
||||
"libstructopt",
|
||||
],
|
||||
prefer_rlib: true,
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2022, The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Append bootconfig to initrd image
|
||||
use anyhow::Result;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
|
||||
const FOOTER_ALIGNMENT: usize = 4;
|
||||
const ZEROS: [u8; 4] = [0u8; 4_usize];
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
struct Args {
|
||||
/// Output
|
||||
#[structopt(parse(from_os_str), long = "output")]
|
||||
output: PathBuf,
|
||||
/// Initrd (without bootconfig)
|
||||
#[structopt(parse(from_os_str))]
|
||||
initrd: PathBuf,
|
||||
/// Bootconfig
|
||||
#[structopt(parse(from_os_str))]
|
||||
bootconfigs: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
fn get_checksum(file_path: &PathBuf) -> Result<u32> {
|
||||
File::open(file_path)?.bytes().map(|x| Ok(x? as u32)).sum()
|
||||
}
|
||||
|
||||
// Bootconfig is attached to the initrd in the following way:
|
||||
// [initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
|
||||
fn attach_bootconfig(initrd: PathBuf, bootconfigs: Vec<PathBuf>, output: PathBuf) -> Result<()> {
|
||||
let mut output_file = File::create(&output)?;
|
||||
let mut initrd_file = File::open(&initrd)?;
|
||||
let initrd_size: usize = initrd_file.metadata()?.len().try_into()?;
|
||||
let mut bootconfig_size: usize = 0;
|
||||
let mut checksum: u32 = 0;
|
||||
|
||||
std::io::copy(&mut initrd_file, &mut output_file)?;
|
||||
for bootconfig in bootconfigs {
|
||||
let mut bootconfig_file = File::open(&bootconfig)?;
|
||||
std::io::copy(&mut bootconfig_file, &mut output_file)?;
|
||||
bootconfig_size += bootconfig_file.metadata()?.len() as usize;
|
||||
checksum += get_checksum(&bootconfig)?;
|
||||
}
|
||||
|
||||
let padding_size: usize = FOOTER_ALIGNMENT - (initrd_size + bootconfig_size) % FOOTER_ALIGNMENT;
|
||||
output_file.write_all(&ZEROS[..padding_size])?;
|
||||
output_file.write_all(&((padding_size + bootconfig_size) as u32).to_le_bytes())?;
|
||||
output_file.write_all(&checksum.to_le_bytes())?;
|
||||
output_file.write_all(b"#BOOTCONFIG\n")?;
|
||||
output_file.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_main() -> Result<()> {
|
||||
let args = Args::from_args_safe()?;
|
||||
attach_bootconfig(args.initrd, args.bootconfigs, args.output)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
try_main().unwrap()
|
||||
}
|
Loading…
Reference in New Issue