diff --git a/blflash/src/chip/bl602/mod.rs b/blflash/src/chip/bl602/mod.rs index 81e34c6..be6abcd 100644 --- a/blflash/src/chip/bl602/mod.rs +++ b/blflash/src/chip/bl602/mod.rs @@ -1,4 +1,4 @@ -use super::{Chip, CodeSegment, FlashSegment}; +use super::{Chip, CodeSegment, RomSegment}; use crate::{Error, image::{PartitionCfg, BootHeaderCfg}}; use deku::prelude::*; @@ -22,7 +22,7 @@ impl Bl602 { mut partition_cfg: PartitionCfg, mut bootheader_cfg: BootHeaderCfg, bin: &[u8], - ) -> Result, Error> { + ) -> Result, Error> { partition_cfg.update()?; let partition_cfg = partition_cfg.to_bytes()?; @@ -31,10 +31,10 @@ impl Bl602 { log::trace!("{}", hex::encode(&boot2image[0..200])); let _segments = vec![ - FlashSegment::from_slice(0x0, &boot2image), - FlashSegment::from_slice(0xe000, &partition_cfg), - FlashSegment::from_slice(0xf000, &partition_cfg), - FlashSegment::from_slice(0x10000, &fw_image), + RomSegment::from_vec(0x0, boot2image), + RomSegment::from_vec(0xe000, partition_cfg.clone()), + RomSegment::from_vec(0xf000, partition_cfg), + RomSegment::from_vec(0x10000, fw_image.clone()), // FlashSegment::from_slice(0x1f8000, &d), ]; @@ -47,12 +47,9 @@ impl Chip for Bl602 { EFLASH_LOADER } - fn get_flash_segment<'a>(&self, code_segment: CodeSegment<'a>) -> Option> { + fn get_flash_segment<'a>(&self, code_segment: CodeSegment<'a>) -> Option> { if self.addr_is_flash(code_segment.addr) { - Some(FlashSegment { - addr: code_segment.addr - ROM_START, - code_segment, - }) + Some(RomSegment::from_code_segment(code_segment.addr - ROM_START, code_segment)) } else { None } diff --git a/blflash/src/chip/mod.rs b/blflash/src/chip/mod.rs index 9e1b916..42815a7 100644 --- a/blflash/src/chip/mod.rs +++ b/blflash/src/chip/mod.rs @@ -1,9 +1,8 @@ pub mod bl602; pub use bl602::Bl602; -pub use crate::elf::{FirmwareImage, CodeSegment}; -pub use crate::flasher::FlashSegment; +pub use crate::elf::{FirmwareImage, CodeSegment, RomSegment}; pub trait Chip { fn get_eflash_loader(&self) -> &[u8]; - fn get_flash_segment<'a>(&self, code_segment: CodeSegment<'a>) -> Option>; + fn get_flash_segment<'a>(&self, code_segment: CodeSegment<'a>) -> Option>; } diff --git a/blflash/src/elf.rs b/blflash/src/elf.rs index b70681f..aed5205 100644 --- a/blflash/src/elf.rs +++ b/blflash/src/elf.rs @@ -62,6 +62,12 @@ impl<'a> CodeSegment<'a> { } } +impl<'a> AsRef<[u8]> for CodeSegment<'a> { + fn as_ref(&self) -> &[u8] { + self.data + } +} + impl PartialEq for CodeSegment<'_> { fn eq(&self, other: &Self) -> bool { self.addr.eq(&other.addr) @@ -80,10 +86,21 @@ pub struct RomSegment<'a> { pub data: Cow<'a, [u8]>, } -pub fn update_checksum(data: &[u8], mut checksum: u8) -> u8 { - for byte in data { - checksum ^= *byte; +impl<'a> RomSegment<'a> { + pub fn size(&self) -> u32 { + self.data.len() as u32 + } + pub fn from_vec(addr: u32, data: Vec) -> Self { + RomSegment { + addr, + data: Cow::Owned(data), + } + } + pub fn from_code_segment(addr: u32, code_segment: CodeSegment<'a>) -> RomSegment<'a> + { + Self { + addr, + data: Cow::Borrowed(code_segment.data), + } } - - checksum } \ No newline at end of file diff --git a/blflash/src/flasher.rs b/blflash/src/flasher.rs index c1a55fc..daa3708 100644 --- a/blflash/src/flasher.rs +++ b/blflash/src/flasher.rs @@ -1,4 +1,4 @@ -use crate::{elf::CodeSegment, connection::{Connection, DEFAULT_BAUDRATE}}; +use crate::{connection::{Connection, DEFAULT_BAUDRATE}, elf::RomSegment}; use crate::Error; use crate::chip::Chip; use crate::elf::FirmwareImage; @@ -9,33 +9,6 @@ use indicatif::HumanBytes; use sha2::{Sha256, Digest}; use std::thread::sleep; -pub struct FlashSegment<'a> { - pub addr: u32, - pub code_segment: CodeSegment<'a>, -} - -#[allow(dead_code)] -impl<'a> FlashSegment<'a> { - fn addr(&self) -> u32 { - self.addr - } - fn virt_addr(&self) -> u32 { - self.code_segment.addr - } - fn data(&self) -> &[u8] { - self.code_segment.data - } - fn size(&self) -> u32 { - self.code_segment.size - } - pub fn from_slice>(addr: u32, data: &'a D) -> Self { - FlashSegment { - addr, - code_segment: CodeSegment::from_slice(addr, data), - } - } -} - pub struct Flasher { connection: Connection, boot_info: protocol::BootInfo, @@ -65,20 +38,17 @@ impl Flasher { &self.boot_info } - pub fn load_segments<'a>(&'a mut self, segments: impl Iterator>) -> Result<(), Error> { + pub fn load_segments<'a>(&'a mut self, segments: impl Iterator>) -> 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()); - } - log::info!("Erase flash addr: {:x} size: {}", segment.addr(), segment.size()); - self.flash_erase(segment.addr(), segment.addr() + segment.size())?; - let local_hash = Sha256::digest(&segment.data()[0..segment.size() as usize]); + log::info!("Erase flash addr: {:x} size: {}", segment.addr, segment.size()); + self.flash_erase(segment.addr, segment.addr + segment.size())?; + let local_hash = Sha256::digest(&segment.data[0..segment.size() as usize]); - let mut reader = Cursor::new(segment.data()); + let mut reader = Cursor::new(&segment.data); let mut cur = segment.addr; let start = Instant::now(); @@ -102,22 +72,19 @@ impl Flasher { Ok(()) } - pub fn check_segments<'a>(&'a mut self, segments: impl Iterator>) -> Result<(), Error> { + pub fn check_segments<'a>(&'a mut self, segments: impl Iterator>) -> 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 local_hash = Sha256::digest(&segment.data[0..segment.size() as usize]); - let sha256 = self.sha256_read(segment.addr(), segment.size())?; + 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); + log::warn!("{:x} sha256 not match: {:x?} != {:x?}", segment.addr, sha256, local_hash); } else { - log::info!("{:x} sha256 match", segment.addr()); + log::info!("{:x} sha256 match", segment.addr); } } Ok(())