mirror of
https://github.com/spacemeowx2/blflash.git
synced 2025-02-22 06:41:18 +00:00
tested
This commit is contained in:
parent
e13e0a830e
commit
f8efd5ea81
@ -51,6 +51,17 @@ pub struct CodeSegment<'a> {
|
||||
pub data: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> CodeSegment<'a> {
|
||||
pub fn from_slice<D: AsRef<[u8]>>(addr: u32, data: &'a D) -> Self {
|
||||
let data = data.as_ref();
|
||||
CodeSegment {
|
||||
addr,
|
||||
data: &data,
|
||||
size: data.len() as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for CodeSegment<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.addr.eq(&other.addr)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::connection::{Connection, DEFAULT_BAUDRATE};
|
||||
use crate::{elf::CodeSegment, connection::{Connection, DEFAULT_BAUDRATE}};
|
||||
use crate::Error;
|
||||
use crate::chip::{Chip, Bl602};
|
||||
use crate::elf::FirmwareImage;
|
||||
@ -27,7 +27,7 @@ impl Flasher {
|
||||
};
|
||||
flasher.connection.set_baud(speed.unwrap_or(DEFAULT_BAUDRATE))?;
|
||||
flasher.start_connection()?;
|
||||
flasher.connection.set_timeout(Duration::from_secs(3))?;
|
||||
flasher.connection.set_timeout(Duration::from_secs(10))?;
|
||||
flasher.boot_info = flasher.get_boot_info()?;
|
||||
|
||||
Ok(flasher)
|
||||
@ -37,12 +37,12 @@ impl Flasher {
|
||||
&self.boot_info
|
||||
}
|
||||
|
||||
pub fn load_elf_to_flash(&mut self, elf_data: &[u8]) -> Result<(), Error> {
|
||||
pub fn load_segments<'a>(&'a mut self, segments: impl Iterator<Item=CodeSegment<'a>>) -> Result<(), Error> {
|
||||
self.load_eflash_loader()?;
|
||||
self.connection.set_baud(BaudRate::BaudOther(2_000_000))?;
|
||||
self.handshake()?;
|
||||
|
||||
let image = FirmwareImage::from_data(elf_data).map_err(|_| Error::InvalidElf)?;
|
||||
for segment in self.chip.get_flash_segments(&image) {
|
||||
for segment in segments {
|
||||
if segment.size != segment.data.len() as u32 {
|
||||
log::warn!("size mismatch {} != {}", segment.size, segment.data.len());
|
||||
}
|
||||
@ -53,16 +53,18 @@ impl Flasher {
|
||||
let mut reader = Cursor::new(segment.data);
|
||||
let mut cur = segment.addr;
|
||||
|
||||
let start = Instant::now();
|
||||
log::info!("Program flash... {:x}", local_hash);
|
||||
loop {
|
||||
let size = self.flash_program(cur, &mut reader)?;
|
||||
// log::trace!("program {:x} {:x}", cur, size);
|
||||
cur += size;
|
||||
if size == 0 {
|
||||
break
|
||||
}
|
||||
cur += size;
|
||||
}
|
||||
self.flash_program_check()?;
|
||||
log::info!("Program done");
|
||||
let elapsed = start.elapsed();
|
||||
log::info!("Program done {:?} {}/s", elapsed, HumanBytes((segment.size as f64 / elapsed.as_millis() as f64 * 1000.0) as u64));
|
||||
|
||||
let sha256 = self.sha256_read(segment.addr, segment.size)?;
|
||||
if sha256 != &local_hash[..] {
|
||||
@ -72,6 +74,34 @@ impl Flasher {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_segments<'a>(&'a mut self, segments: impl Iterator<Item=CodeSegment<'a>>) -> Result<(), Error> {
|
||||
self.load_eflash_loader()?;
|
||||
self.connection.set_baud(BaudRate::BaudOther(2_000_000))?;
|
||||
self.handshake()?;
|
||||
|
||||
for segment in segments {
|
||||
if segment.size != segment.data.len() as u32 {
|
||||
log::warn!("size mismatch {} != {}", segment.size, segment.data.len());
|
||||
}
|
||||
let local_hash = Sha256::digest(&segment.data[0..segment.size as usize]);
|
||||
|
||||
let sha256 = self.sha256_read(segment.addr, segment.size)?;
|
||||
if sha256 != &local_hash[..] {
|
||||
log::warn!("{:x} sha256 not match: {:x?} != {:x?}", segment.addr, sha256, local_hash);
|
||||
} else {
|
||||
log::info!("{:x} sha256 match", segment.addr);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_elf_to_flash(&mut self, elf_data: &[u8]) -> Result<(), Error> {
|
||||
let image = FirmwareImage::from_data(elf_data).map_err(|_| Error::InvalidElf)?;
|
||||
let segs = self.chip.get_flash_segments(&image);
|
||||
self.load_segments(segs.into_iter())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_eflash_loader(&mut self) -> Result<(), Error> {
|
||||
let input = self.chip.get_eflash_loader().to_vec();
|
||||
let len = input.len();
|
||||
@ -112,12 +142,12 @@ impl Flasher {
|
||||
Ok(data.digest)
|
||||
}
|
||||
|
||||
fn flash_program_check(&mut self) -> Result<(), Error> {
|
||||
self.connection.write_all(protocol::FLASH_PROGRAM_CHRCK)?;
|
||||
self.connection.flush()?;
|
||||
self.connection.read_response(0)?;
|
||||
Ok(())
|
||||
}
|
||||
// fn flash_program_check(&mut self) -> Result<(), Error> {
|
||||
// self.connection.write_all(protocol::FLASH_PROGRAM_CHRCK)?;
|
||||
// self.connection.flush()?;
|
||||
// self.connection.read_response(0)?;
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
fn flash_program(&mut self, addr: u32, reader: &mut impl Read) -> Result<u32, Error> {
|
||||
let mut data = vec![0u8; 4000];
|
||||
@ -270,7 +300,7 @@ mod protocol {
|
||||
pub const GET_BOOT_INFO: &[u8] = &[0x10, 0x00, 0x00, 0x00];
|
||||
pub const CHECK_IMAGE: &[u8] = &[0x19, 0x00, 0x00, 0x00];
|
||||
pub const RUN_IMAGE: &[u8] = &[0x1a, 0x00, 0x00, 0x00];
|
||||
pub const FLASH_PROGRAM_CHRCK: &[u8] = &[0x3a, 0x00, 0x00, 0x00];
|
||||
// pub const FLASH_PROGRAM_CHRCK: &[u8] = &[0x3a, 0x00, 0x00, 0x00];
|
||||
pub const LOAD_BOOT_HEADER_LEN: usize = 176;
|
||||
pub const LOAD_SEGMENT_HEADER_LEN: usize = 16;
|
||||
|
||||
|
@ -4,7 +4,7 @@ mod connection;
|
||||
mod chip;
|
||||
mod error;
|
||||
mod image;
|
||||
mod elf;
|
||||
pub mod elf;
|
||||
|
||||
pub use config::Config;
|
||||
pub use flasher::Flasher;
|
||||
|
@ -44,9 +44,25 @@ fn main() -> Result<(), MainError> {
|
||||
};
|
||||
|
||||
let serial = serial::open(&serial)?;
|
||||
let mut flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(500_000)))?;
|
||||
let mut flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(512_000)))?;
|
||||
|
||||
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())?;
|
||||
// flasher.check_segments(segments.into_iter())?;
|
||||
flasher.load_elf_to_flash(&input_bytes)?;
|
||||
|
||||
log::info!("Success");
|
||||
|
Loading…
x
Reference in New Issue
Block a user