mirror of
https://github.com/spacemeowx2/blflash.git
synced 2024-10-06 06:39:51 +00:00
implement flash
This commit is contained in:
parent
79cdf21fa9
commit
e13e0a830e
66
Cargo.lock
generated
66
Cargo.lock
generated
@ -81,11 +81,21 @@ dependencies = [
|
|||||||
"pico-args",
|
"pico-args",
|
||||||
"serde",
|
"serde",
|
||||||
"serial",
|
"serial",
|
||||||
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml 0.5.7",
|
"toml 0.5.7",
|
||||||
"xmas-elf",
|
"xmas-elf",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.4"
|
version = "1.3.4"
|
||||||
@ -146,6 +156,12 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpuid-bool"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
@ -203,6 +219,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "directories-next"
|
name = "directories-next"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@ -277,6 +302,16 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8"
|
checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
@ -397,6 +432,12 @@ version = "0.22.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pico-args"
|
name = "pico-args"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -538,6 +579,19 @@ dependencies = [
|
|||||||
"serial-core",
|
"serial-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"cpuid-bool",
|
||||||
|
"digest",
|
||||||
|
"opaque-debug",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
@ -648,6 +702,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
@ -660,6 +720,12 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
@ -24,3 +24,4 @@ log = "0.4.11"
|
|||||||
env_logger = "0.8.2"
|
env_logger = "0.8.2"
|
||||||
deku = "0.9.1"
|
deku = "0.9.1"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
|
sha2 = "0.9.2"
|
||||||
|
@ -1,11 +1,32 @@
|
|||||||
use super::Chip;
|
use super::{Chip, CodeSegment, FirmwareImage};
|
||||||
|
|
||||||
pub const EFLASH_LOADER: &'static [u8] = include_bytes!("eflash_loader_40m.bin");
|
const EFLASH_LOADER: &'static [u8] = include_bytes!("eflash_loader_40m.bin");
|
||||||
|
const ROM_START: u32 = 0x21000000;
|
||||||
|
const ROM_END: u32 = 0x21000000 + 0x20000;
|
||||||
|
|
||||||
pub struct Bl602;
|
pub struct Bl602;
|
||||||
|
|
||||||
|
impl Bl602 {
|
||||||
|
fn addr_is_flash(&self, addr: u32) -> bool {
|
||||||
|
addr >= ROM_START && addr < ROM_END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Chip for Bl602 {
|
impl Chip for Bl602 {
|
||||||
fn get_eflash_loader(&self) -> &[u8] {
|
fn get_eflash_loader(&self) -> &[u8] {
|
||||||
EFLASH_LOADER
|
EFLASH_LOADER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_flash_segments<'a>(&self, image: &'a FirmwareImage) -> Vec<CodeSegment<'a>> {
|
||||||
|
image.segments().filter_map(|s| {
|
||||||
|
if self.addr_is_flash(s.addr) {
|
||||||
|
Some(CodeSegment {
|
||||||
|
addr: s.addr - ROM_START,
|
||||||
|
..s
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
mod bl602;
|
mod bl602;
|
||||||
pub use bl602::Bl602;
|
pub use bl602::Bl602;
|
||||||
|
pub use crate::elf::{FirmwareImage, CodeSegment};
|
||||||
|
|
||||||
pub trait Chip {
|
pub trait Chip {
|
||||||
fn get_eflash_loader(&self) -> &[u8];
|
fn get_eflash_loader(&self) -> &[u8];
|
||||||
|
fn get_flash_segments<'a>(&self, image: &'a FirmwareImage) -> Vec<CodeSegment<'a>>;
|
||||||
}
|
}
|
||||||
|
78
blflash/src/elf.rs
Normal file
78
blflash/src/elf.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use xmas_elf::program::{SegmentData, Type};
|
||||||
|
use xmas_elf::ElfFile;
|
||||||
|
|
||||||
|
pub struct FirmwareImage<'a> {
|
||||||
|
pub entry: u32,
|
||||||
|
pub elf: ElfFile<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FirmwareImage<'a> {
|
||||||
|
pub fn from_data(data: &'a [u8]) -> Result<Self, &'static str> {
|
||||||
|
Ok(Self::from_elf(ElfFile::new(data)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_elf(elf: ElfFile<'a>) -> Self {
|
||||||
|
FirmwareImage {
|
||||||
|
entry: elf.header.pt2.entry_point() as u32,
|
||||||
|
elf,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entry(&self) -> u32 {
|
||||||
|
self.elf.header.pt2.entry_point() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn segments(&'a self) -> impl Iterator<Item = CodeSegment<'a>> + 'a {
|
||||||
|
self.elf
|
||||||
|
.program_iter()
|
||||||
|
.filter(|header| {
|
||||||
|
header.file_size() > 0 && header.get_type() == Ok(Type::Load) && header.offset() > 0
|
||||||
|
})
|
||||||
|
.flat_map(move |header| {
|
||||||
|
let addr = header.virtual_addr() as u32;
|
||||||
|
let size = header.file_size() as u32;
|
||||||
|
let data = match header.get_data(&self.elf) {
|
||||||
|
Ok(SegmentData::Undefined(data)) => data,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
Some(CodeSegment { addr, data, size })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Ord, Eq)]
|
||||||
|
/// A segment of code from the source elf
|
||||||
|
pub struct CodeSegment<'a> {
|
||||||
|
pub addr: u32,
|
||||||
|
pub size: u32,
|
||||||
|
pub data: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for CodeSegment<'_> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.addr.eq(&other.addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for CodeSegment<'_> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
self.addr.partial_cmp(&other.addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A segment of data to write to the flash
|
||||||
|
pub struct RomSegment<'a> {
|
||||||
|
pub addr: u32,
|
||||||
|
pub data: Cow<'a, [u8]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_checksum(data: &[u8], mut checksum: u8) -> u8 {
|
||||||
|
for byte in data {
|
||||||
|
checksum ^= *byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
use crate::connection::{Connection, DEFAULT_BAUDRATE};
|
use crate::connection::{Connection, DEFAULT_BAUDRATE};
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use crate::chip::{Chip, Bl602};
|
use crate::chip::{Chip, Bl602};
|
||||||
use crate::image::BinReader;
|
use crate::elf::FirmwareImage;
|
||||||
use serial::{BaudRate, SerialPort};
|
use serial::{BaudRate, SerialPort};
|
||||||
use std::{time::{Duration, Instant}, io::{Cursor, Read}};
|
use std::{time::{Duration, Instant}, io::{Cursor, Read}};
|
||||||
use deku::prelude::*;
|
use deku::prelude::*;
|
||||||
use indicatif::{HumanBytes};
|
use indicatif::{HumanBytes};
|
||||||
|
use sha2::{Sha256, Digest};
|
||||||
|
use std::thread::sleep;
|
||||||
|
|
||||||
pub struct Flasher {
|
pub struct Flasher {
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
@ -35,13 +37,43 @@ impl Flasher {
|
|||||||
&self.boot_info
|
&self.boot_info
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_elf_to_flash(&mut self, _input: &[u8]) -> Result<(), Error> {
|
pub fn load_elf_to_flash(&mut self, elf_data: &[u8]) -> Result<(), Error> {
|
||||||
let loader = self.chip.get_eflash_loader().to_vec();
|
self.load_eflash_loader()?;
|
||||||
self.load_bin(&loader)?;
|
self.handshake()?;
|
||||||
|
|
||||||
|
let image = FirmwareImage::from_data(elf_data).map_err(|_| Error::InvalidElf)?;
|
||||||
|
for segment in self.chip.get_flash_segments(&image) {
|
||||||
|
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]);
|
||||||
|
|
||||||
|
let mut reader = Cursor::new(segment.data);
|
||||||
|
let mut cur = segment.addr;
|
||||||
|
|
||||||
|
log::info!("Program flash... {:x}", local_hash);
|
||||||
|
loop {
|
||||||
|
let size = self.flash_program(cur, &mut reader)?;
|
||||||
|
if size == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cur += size;
|
||||||
|
}
|
||||||
|
self.flash_program_check()?;
|
||||||
|
log::info!("Program done");
|
||||||
|
|
||||||
|
let sha256 = self.sha256_read(segment.addr, segment.size)?;
|
||||||
|
if sha256 != &local_hash[..] {
|
||||||
|
log::warn!("sha256 not match: {:x?} != {:x?}", sha256, local_hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_bin(&mut self, input: &[u8]) -> Result<(), Error> {
|
pub fn load_eflash_loader(&mut self) -> Result<(), Error> {
|
||||||
|
let input = self.chip.get_eflash_loader().to_vec();
|
||||||
let len = input.len();
|
let len = input.len();
|
||||||
let mut reader = Cursor::new(input);
|
let mut reader = Cursor::new(input);
|
||||||
self.load_boot_header(&mut reader)?;
|
self.load_boot_header(&mut reader)?;
|
||||||
@ -60,6 +92,62 @@ impl Flasher {
|
|||||||
|
|
||||||
self.check_image()?;
|
self.check_image()?;
|
||||||
self.run_image()?;
|
self.run_image()?;
|
||||||
|
sleep(Duration::from_millis(200));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sha256_read(&mut self, addr: u32, len: u32) -> Result<[u8; 32], Error> {
|
||||||
|
let mut req = protocol::Sha256Read {
|
||||||
|
addr,
|
||||||
|
len,
|
||||||
|
};
|
||||||
|
req.update()?;
|
||||||
|
self.connection.write_all(&req.to_bytes()?)?;
|
||||||
|
self.connection.flush()?;
|
||||||
|
|
||||||
|
let data = self.connection.read_response(34)?;
|
||||||
|
let (_, data) = protocol::Sha256ReadResp::from_bytes((&data, 0))?;
|
||||||
|
|
||||||
|
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(&mut self, addr: u32, reader: &mut impl Read) -> Result<u32, Error> {
|
||||||
|
let mut data = vec![0u8; 4000];
|
||||||
|
let size = reader.read(&mut data)?;
|
||||||
|
if size == 0 {
|
||||||
|
return Ok(0)
|
||||||
|
}
|
||||||
|
data.truncate(size);
|
||||||
|
let mut req = protocol::FlashProgram {
|
||||||
|
addr,
|
||||||
|
data,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
req.update()?;
|
||||||
|
self.connection.write_all(&req.to_bytes()?)?;
|
||||||
|
self.connection.flush()?;
|
||||||
|
self.connection.read_response(0)?;
|
||||||
|
|
||||||
|
Ok(size as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flash_erase(&mut self, start: u32, end: u32) -> Result<(), Error> {
|
||||||
|
let mut req = protocol::FlashErase {
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
};
|
||||||
|
req.update()?;
|
||||||
|
self.connection.write_all(&req.to_bytes()?)?;
|
||||||
|
self.connection.flush()?;
|
||||||
|
self.connection.read_response(0)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -112,7 +200,7 @@ impl Flasher {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_segment_data(&mut self, reader: &mut impl Read) -> Result<usize, Error> {
|
fn load_segment_data(&mut self, reader: &mut impl Read) -> Result<u32, Error> {
|
||||||
let mut segment_data = vec![0u8; 4000];
|
let mut segment_data = vec![0u8; 4000];
|
||||||
let size = reader.read(&mut segment_data)?;
|
let size = reader.read(&mut segment_data)?;
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
@ -128,7 +216,7 @@ impl Flasher {
|
|||||||
self.connection.flush()?;
|
self.connection.flush()?;
|
||||||
self.connection.read_response(0)?;
|
self.connection.read_response(0)?;
|
||||||
|
|
||||||
Ok(size)
|
Ok(size as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_boot_info(&mut self) -> Result<protocol::BootInfo, Error> {
|
fn get_boot_info(&mut self) -> Result<protocol::BootInfo, Error> {
|
||||||
@ -182,6 +270,7 @@ mod protocol {
|
|||||||
pub const GET_BOOT_INFO: &[u8] = &[0x10, 0x00, 0x00, 0x00];
|
pub const GET_BOOT_INFO: &[u8] = &[0x10, 0x00, 0x00, 0x00];
|
||||||
pub const CHECK_IMAGE: &[u8] = &[0x19, 0x00, 0x00, 0x00];
|
pub const CHECK_IMAGE: &[u8] = &[0x19, 0x00, 0x00, 0x00];
|
||||||
pub const RUN_IMAGE: &[u8] = &[0x1a, 0x00, 0x00, 0x00];
|
pub const RUN_IMAGE: &[u8] = &[0x1a, 0x00, 0x00, 0x00];
|
||||||
|
pub const FLASH_PROGRAM_CHRCK: &[u8] = &[0x3a, 0x00, 0x00, 0x00];
|
||||||
pub const LOAD_BOOT_HEADER_LEN: usize = 176;
|
pub const LOAD_BOOT_HEADER_LEN: usize = 176;
|
||||||
pub const LOAD_SEGMENT_HEADER_LEN: usize = 16;
|
pub const LOAD_SEGMENT_HEADER_LEN: usize = 16;
|
||||||
|
|
||||||
@ -217,4 +306,39 @@ mod protocol {
|
|||||||
pub segment_data_len: u16,
|
pub segment_data_len: u16,
|
||||||
pub segment_data: Vec<u8>,
|
pub segment_data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, DekuWrite, Default)]
|
||||||
|
#[deku(magic = b"\x30\x00\x08\x00", endian = "little")]
|
||||||
|
pub struct FlashErase {
|
||||||
|
pub start: u32,
|
||||||
|
pub end: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, DekuWrite, Default)]
|
||||||
|
#[deku(magic = b"\x31\x00", endian = "little")]
|
||||||
|
pub struct FlashProgram {
|
||||||
|
#[deku(update = "self.len()")]
|
||||||
|
pub len: u16,
|
||||||
|
pub addr: u32,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlashProgram {
|
||||||
|
fn len(&self) -> u16 {
|
||||||
|
self.data.len() as u16 + 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, DekuWrite, Default)]
|
||||||
|
#[deku(magic = b"\x3d\x00\x08\x00", endian = "little")]
|
||||||
|
pub struct Sha256Read {
|
||||||
|
pub addr: u32,
|
||||||
|
pub len: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, DekuRead)]
|
||||||
|
#[deku(magic = b"\x20\x00")]
|
||||||
|
pub struct Sha256ReadResp {
|
||||||
|
pub digest: [u8; 32],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ mod connection;
|
|||||||
mod chip;
|
mod chip;
|
||||||
mod error;
|
mod error;
|
||||||
mod image;
|
mod image;
|
||||||
|
mod elf;
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use flasher::Flasher;
|
pub use flasher::Flasher;
|
||||||
|
@ -32,6 +32,12 @@ fn main() -> Result<(), MainError> {
|
|||||||
serial = config.connection.serial;
|
serial = config.connection.serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let input: String = match elf {
|
||||||
|
Some(input) => input,
|
||||||
|
_ => return help(),
|
||||||
|
};
|
||||||
|
let input_bytes = read(&input)?;
|
||||||
|
|
||||||
let serial: String = match serial {
|
let serial: String = match serial {
|
||||||
Some(serial) => serial,
|
Some(serial) => serial,
|
||||||
_ => return help(),
|
_ => return help(),
|
||||||
@ -41,13 +47,9 @@ fn main() -> Result<(), MainError> {
|
|||||||
let mut flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(500_000)))?;
|
let mut flasher = Flasher::connect(serial, Some(BaudRate::BaudOther(500_000)))?;
|
||||||
|
|
||||||
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
log::info!("Bootrom version: {}", flasher.boot_info().bootrom_version);
|
||||||
|
|
||||||
let input: String = match elf {
|
|
||||||
Some(input) => input,
|
|
||||||
_ => return help(),
|
|
||||||
};
|
|
||||||
let input_bytes = read(&input)?;
|
|
||||||
flasher.load_elf_to_flash(&input_bytes)?;
|
flasher.load_elf_to_flash(&input_bytes)?;
|
||||||
|
|
||||||
|
log::info!("Success");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user