mirror of
https://github.com/spacemeowx2/blflash.git
synced 2024-10-04 05:39:47 +00:00
feat: add partition bin
This commit is contained in:
parent
fa1865987e
commit
004fdf12bc
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -87,9 +87,11 @@ name = "blflash"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc",
|
||||
"deku",
|
||||
"directories-next",
|
||||
"env_logger",
|
||||
"hex",
|
||||
"indicatif",
|
||||
"log",
|
||||
"main_error",
|
||||
@ -112,6 +114,12 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build_const"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
@ -193,6 +201,15 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||
dependencies = [
|
||||
"build_const",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.10.2"
|
||||
@ -384,6 +401,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.0.1"
|
||||
|
@ -26,3 +26,5 @@ byteorder = "1.3.4"
|
||||
sha2 = "0.9.2"
|
||||
structopt = { version = "0.3.21", features = ["paw"] }
|
||||
paw = "1.0.0"
|
||||
crc = "1.8.1"
|
||||
hex = "0.4.2"
|
||||
|
94
blflash/src/chip/bl602/cfg/partition_cfg_2M.toml
Normal file
94
blflash/src/chip/bl602/cfg/partition_cfg_2M.toml
Normal file
@ -0,0 +1,94 @@
|
||||
[pt_table]
|
||||
#partition table is 4K in size
|
||||
address0 = 0xE000
|
||||
address1 = 0xF000
|
||||
|
||||
[[pt_entry]]
|
||||
type = 0
|
||||
name = "FW"
|
||||
device = 0
|
||||
address0 = 0x10000
|
||||
size0 = 0xC8000
|
||||
address1 = 0xD8000
|
||||
size1 = 0x88000
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
[[pt_entry]]
|
||||
type = 2
|
||||
name = "mfg"
|
||||
device = 0
|
||||
address0 = 0x160000
|
||||
size0 = 0x32000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
[[pt_entry]]
|
||||
type = 3
|
||||
name = "media"
|
||||
device = 0
|
||||
address0 = 0x192000
|
||||
size0 = 0x57000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
[[pt_entry]]
|
||||
type = 4
|
||||
name = "PSM"
|
||||
device = 0
|
||||
address0 = 0x1E9000
|
||||
size0 = 0x8000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
[[pt_entry]]
|
||||
type = 5
|
||||
name = "KEY"
|
||||
device = 0
|
||||
address0 = 0x1F1000
|
||||
size0 = 0x2000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
[[pt_entry]]
|
||||
type = 6
|
||||
name = "DATA"
|
||||
device = 0
|
||||
address0 = 0x1F3000
|
||||
size0 = 0x5000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
|
||||
[[pt_entry]]
|
||||
type = 7
|
||||
name = "factory"
|
||||
device = 0
|
||||
address0 = 0x1F8000
|
||||
size0 = 0x7000
|
||||
address1 = 0
|
||||
size1 = 0
|
||||
# compressed image must set len,normal image can left it to 0
|
||||
len = 0
|
||||
|
||||
#if user want to put RF calibration data on flash, uncomment following pt entry
|
||||
#[[pt_entry]]
|
||||
#type = 8
|
||||
#name = "rf_para"
|
||||
#device = 0
|
||||
#address0 = 0x1FF000
|
||||
#size0 = 0x1000
|
||||
#address1 = 0
|
||||
#size1 = 0
|
||||
## compressed image must set len,normal image can left it to 0
|
||||
#len = 0
|
BIN
blflash/src/chip/bl602/image/boot2image.bin
Normal file
BIN
blflash/src/chip/bl602/image/boot2image.bin
Normal file
Binary file not shown.
@ -1,16 +1,38 @@
|
||||
use super::{Chip, CodeSegment, FlashSegment};
|
||||
use crate::{Error, image::PartitionCfg};
|
||||
use deku::prelude::*;
|
||||
|
||||
const EFLASH_LOADER: &'static [u8] = include_bytes!("image/eflash_loader_40m.bin");
|
||||
pub const DEFAULT_PARTITION_CFG: &'static [u8] = include_bytes!("cfg/partition_cfg_2M.toml");
|
||||
pub const BOOT2IMAGE: &'static [u8] = include_bytes!("image/boot2image.bin");
|
||||
pub const EFLASH_LOADER: &'static [u8] = include_bytes!("image/eflash_loader_40m.bin");
|
||||
const ROM_START: u32 = 0x23000000;
|
||||
// 16MB
|
||||
const ROM_END: u32 = 0x23000000 + 0x1000000;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Bl602;
|
||||
|
||||
impl Bl602 {
|
||||
fn addr_is_flash(&self, addr: u32) -> bool {
|
||||
addr >= ROM_START && addr < ROM_END
|
||||
}
|
||||
pub fn with_boot2(
|
||||
&self,
|
||||
mut partition_cfg: PartitionCfg,
|
||||
bin: &[u8],
|
||||
) -> Result<Vec<FlashSegment>, Error> {
|
||||
partition_cfg.update()?;
|
||||
let partition_cfg = partition_cfg.to_bytes()?;
|
||||
|
||||
let segments = vec![
|
||||
CodeSegment::from_slice(0x0, &BOOT2IMAGE),
|
||||
CodeSegment::from_slice(0xe000, &partition_cfg),
|
||||
CodeSegment::from_slice(0xf000, &partition_cfg),
|
||||
// CodeSegment::from_slice(0x10000, &c),
|
||||
// CodeSegment::from_slice(0x1f8000, &d),
|
||||
];
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Chip for Bl602 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
mod bl602;
|
||||
pub mod bl602;
|
||||
pub use bl602::Bl602;
|
||||
pub use crate::elf::{FirmwareImage, CodeSegment};
|
||||
pub use crate::flasher::FlashSegment;
|
||||
|
@ -25,6 +25,8 @@ pub enum Error {
|
||||
RomError(RomError),
|
||||
#[error("Parse error")]
|
||||
ParseError(#[from] deku::error::DekuError),
|
||||
#[error("Parse toml error")]
|
||||
TomlError(#[from] toml::de::Error),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
|
@ -37,13 +37,14 @@ pub struct Flasher {
|
||||
|
||||
impl Flasher {
|
||||
pub fn connect(
|
||||
chip: impl Chip + 'static,
|
||||
serial: impl SerialPort + 'static,
|
||||
speed: Option<BaudRate>,
|
||||
) -> Result<Self, Error> {
|
||||
let mut flasher = Flasher {
|
||||
connection: Connection::new(serial),
|
||||
boot_info: protocol::BootInfo::default(),
|
||||
chip: Box::new(Bl602),
|
||||
chip: Box::new(chip),
|
||||
};
|
||||
flasher.connection.set_baud(speed.unwrap_or(DEFAULT_BAUDRATE))?;
|
||||
flasher.start_connection()?;
|
||||
|
3
blflash/src/image/mod.rs
Normal file
3
blflash/src/image/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod partition;
|
||||
|
||||
pub use partition::PartitionCfg;
|
75
blflash/src/image/partition.rs
Normal file
75
blflash/src/image/partition.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use serde::Deserialize;
|
||||
use deku::prelude::*;
|
||||
use std::iter;
|
||||
use std::io::Write;
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, DekuWrite, Default)]
|
||||
#[deku(magic = b"\x42\x46\x50\x54\x00\x00")]
|
||||
pub struct PartitionCfg {
|
||||
#[serde(skip)]
|
||||
#[deku(update = "self.pt_entry.len()")]
|
||||
pub entry_len: u32,
|
||||
#[serde(skip)]
|
||||
#[deku(update = "0")]
|
||||
_unused1: u16,
|
||||
#[serde(skip)]
|
||||
#[deku(update = "self.header_checksum()")]
|
||||
pub checksum: u32,
|
||||
#[deku(skip)]
|
||||
pub pt_table: Table,
|
||||
pub pt_entry: Vec<Entry>,
|
||||
#[serde(skip)]
|
||||
#[deku(update = "self.checksum()")]
|
||||
pub file_checksum: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, DekuWrite, Default)]
|
||||
pub struct Table {
|
||||
pub address0: u32,
|
||||
pub address1: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, DekuWrite, Default)]
|
||||
pub struct Entry {
|
||||
#[deku(bytes = "3")]
|
||||
pub r#type: u32,
|
||||
#[deku(writer = "Entry::write_name(name, output)")]
|
||||
pub name: String,
|
||||
pub address0: u32,
|
||||
pub address1: u32,
|
||||
pub size0: u32,
|
||||
pub size1: u32,
|
||||
pub len: u32,
|
||||
#[serde(skip)]
|
||||
pub _unused1: u32,
|
||||
}
|
||||
|
||||
impl PartitionCfg {
|
||||
fn header_checksum(&self) -> u32 {
|
||||
let data = self.to_bytes().unwrap();
|
||||
crc::crc32::checksum_ieee(&data[0..12])
|
||||
}
|
||||
fn checksum(&self) -> u32 {
|
||||
let data = self.to_bytes().unwrap();
|
||||
crc::crc32::checksum_ieee(&data[16..16+36*self.pt_entry.len()])
|
||||
}
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
fn write_name(
|
||||
name: &str,
|
||||
output: &mut BitVec<Msb0, u8>,
|
||||
) -> Result<(), DekuError> {
|
||||
if name.len() > 8 {
|
||||
return Err(DekuError::Unexpected("name too long".to_string()))
|
||||
}
|
||||
let bytes = name
|
||||
.bytes()
|
||||
.chain(iter::repeat(0))
|
||||
.take(8 + 1) // last is null?
|
||||
.collect::<Vec<_>>();
|
||||
output.write_all(&bytes).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
mod config;
|
||||
mod flasher;
|
||||
mod connection;
|
||||
mod chip;
|
||||
pub mod chip;
|
||||
mod error;
|
||||
mod image;
|
||||
pub mod elf;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::fs::read;
|
||||
|
||||
use blflash::{Config, Flasher, Error};
|
||||
use blflash::{Config, Flasher, Error, chip::bl602::{self, Bl602}};
|
||||
use main_error::MainError;
|
||||
use serial::BaudRate;
|
||||
use env_logger::Env;
|
||||
@ -15,6 +15,11 @@ struct FlashOpt {
|
||||
/// Bin file
|
||||
#[structopt(parse(from_os_str))]
|
||||
image: PathBuf,
|
||||
/// Path to partition_cfg.toml, default to be partition/partition_cfg_2M.toml
|
||||
partition_cfg: Option<PathBuf>,
|
||||
/// With boot2
|
||||
#[structopt(short, long)]
|
||||
without_boot2: bool,
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
@ -37,34 +42,59 @@ enum Opt {
|
||||
|
||||
fn flash(opt: FlashOpt) -> Result<(), Error> {
|
||||
let serial = serial::open(&opt.port)?;
|
||||
let mut flasher = Flasher::connect(serial, Some(BaudRate::Baud115200))?;
|
||||
let chip = Bl602;
|
||||
|
||||
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
||||
log::trace!("Boot info: {:x?}", flasher.boot_info());
|
||||
// use blflash::elf::CodeSegment;
|
||||
// let a = read("image/boot2image.bin")?;
|
||||
// let b = read("image/partition.bin")?;
|
||||
// let c = read("image/fwimage.bin")?;
|
||||
// let d = read("image/ro_params.dtb")?;
|
||||
// let segments = vec![
|
||||
// CodeSegment::from_slice(0x0, &a),
|
||||
// CodeSegment::from_slice(0xe000, &b),
|
||||
// CodeSegment::from_slice(0xf000, &b),
|
||||
// CodeSegment::from_slice(0x10000, &c),
|
||||
// CodeSegment::from_slice(0x1f8000, &d),
|
||||
// ];
|
||||
// flasher.load_segments(segments.into_iter())?;
|
||||
let input_bytes = read(&opt.image)?;
|
||||
flasher.load_elf_to_flash(&input_bytes)?;
|
||||
if !opt.without_boot2 {
|
||||
let partition_cfg = opt
|
||||
.partition_cfg
|
||||
.map(read)
|
||||
.unwrap_or_else(|| Ok(bl602::DEFAULT_PARTITION_CFG.to_vec()))?;
|
||||
let partition_cfg = toml::from_slice(&partition_cfg)?;
|
||||
|
||||
let bin = read(&opt.image)?;
|
||||
let segments = chip.with_boot2(
|
||||
partition_cfg,
|
||||
&bin
|
||||
)?;
|
||||
let mut flasher = Flasher::connect(
|
||||
chip,
|
||||
serial,
|
||||
Some(BaudRate::Baud115200)
|
||||
)?;
|
||||
|
||||
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
||||
log::trace!("Boot info: {:x?}", flasher.boot_info());
|
||||
|
||||
flasher.load_segments(segments.into_iter())?;
|
||||
|
||||
flasher.reset()?;
|
||||
} else {
|
||||
let mut flasher = Flasher::connect(
|
||||
chip,
|
||||
serial,
|
||||
Some(BaudRate::Baud115200)
|
||||
)?;
|
||||
|
||||
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
||||
log::trace!("Boot info: {:x?}", flasher.boot_info());
|
||||
|
||||
let input_bytes = read(&opt.image)?;
|
||||
flasher.load_elf_to_flash(&input_bytes)?;
|
||||
|
||||
flasher.reset()?;
|
||||
}
|
||||
|
||||
flasher.reset()?;
|
||||
log::info!("Success");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check(opt: CheckOpt) -> Result<(), Error> {
|
||||
let serial = serial::open(&opt.port)?;
|
||||
let mut flasher = Flasher::connect(serial, Some(BaudRate::Baud115200))?;
|
||||
let mut flasher = Flasher::connect(
|
||||
Bl602,
|
||||
serial,
|
||||
Some(BaudRate::Baud115200),
|
||||
)?;
|
||||
|
||||
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
||||
log::trace!("Boot info: {:x?}", flasher.boot_info());
|
||||
|
Loading…
Reference in New Issue
Block a user