diff --git a/CHANGELOG.md b/CHANGELOG.md index d981d6bd..8c01c10d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - Remove support for the ESP8266 (#576) +- Remove the direct boot image format (#577) ## [2.1.0] - 2023-10-03 diff --git a/cargo-espflash/src/main.rs b/cargo-espflash/src/main.rs index 2b8174b7..3f7ebbe0 100644 --- a/cargo-espflash/src/main.rs +++ b/cargo-espflash/src/main.rs @@ -16,7 +16,6 @@ use espflash::{ }, error::Error as EspflashError, flasher::{parse_partition_table, FlashData, FlashSettings}, - image_format::ImageFormatKind, logging::initialize_logger, targets::{Chip, XtalFrequency}, update::check_for_update, @@ -185,9 +184,6 @@ struct FlashArgs { #[derive(Debug, Args)] #[non_exhaustive] struct SaveImageArgs { - /// Image format to flash - #[arg(long, value_enum)] - pub format: Option, #[clap(flatten)] build_args: BuildArgs, #[clap(flatten)] @@ -327,7 +323,6 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> { bootloader, partition_table, args.flash_args.partition_table_offset, - args.flash_args.format, args.flash_args.target_app_partition, flash_settings, args.flash_args.min_chip_rev, @@ -557,9 +552,6 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> { // Since we have no `Flasher` instance and as such cannot print the board // information, we will print whatever information we _do_ have. println!("Chip type: {}", args.save_image_args.chip); - if let Some(format) = args.format { - println!("Image format: {:?}", format); - } println!("Merge: {}", args.save_image_args.merge); println!("Skip padding: {}", args.save_image_args.skip_padding); if let Some(path) = &args.save_image_args.bootloader { @@ -579,7 +571,6 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> { bootloader.as_deref(), partition_table.as_deref(), args.save_image_args.partition_table_offset, - args.format, args.save_image_args.target_app_partition, flash_settings, args.save_image_args.min_chip_rev, diff --git a/espflash/src/bin/espflash.rs b/espflash/src/bin/espflash.rs index 5780ac51..21902f04 100644 --- a/espflash/src/bin/espflash.rs +++ b/espflash/src/bin/espflash.rs @@ -15,7 +15,6 @@ use espflash::{ }, error::Error, flasher::{parse_partition_table, FlashData, FlashSettings}, - image_format::ImageFormatKind, logging::initialize_logger, targets::{Chip, XtalFrequency}, update::check_for_update, @@ -126,9 +125,6 @@ struct FlashArgs { struct SaveImageArgs { /// ELF image to flash image: PathBuf, - /// Image format to flash - #[arg(long, value_enum)] - format: Option, /// Flashing configuration #[clap(flatten)] pub flash_config_args: FlashConfigArgs, @@ -262,7 +258,6 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> { bootloader, partition_table, args.flash_args.partition_table_offset, - args.flash_args.format, args.flash_args.target_app_partition, flash_settings, args.flash_args.min_chip_rev, @@ -324,9 +319,6 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> { // Since we have no `Flasher` instance and as such cannot print the board // information, we will print whatever information we _do_ have. println!("Chip type: {}", args.save_image_args.chip); - if let Some(format) = args.format { - println!("Image format: {:?}", format); - } println!("Merge: {}", args.save_image_args.merge); println!("Skip padding: {}", args.save_image_args.skip_padding); if let Some(path) = &bootloader { @@ -346,7 +338,6 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> { bootloader, partition_table, args.save_image_args.partition_table_offset, - args.format, args.save_image_args.target_app_partition, flash_settings, args.save_image_args.min_chip_rev, diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index c665badb..536e34ef 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -34,7 +34,6 @@ use crate::{ parse_partition_table, FlashData, FlashFrequency, FlashMode, FlashSize, Flasher, ProgressCallbacks, }, - image_format::ImageFormatKind, interface::Interface, targets::{Chip, XtalFrequency}, }; @@ -140,9 +139,6 @@ pub struct FlashArgs { /// Erase specified data partitions #[arg(long, value_name = "PARTS", value_enum, value_delimiter = ',')] pub erase_data_parts: Option>, - /// Image format to flash - #[arg(long, value_enum)] - pub format: Option, /// Logging format. #[arg(long, short = 'L', default_value = "serial", requires = "monitor")] pub log_format: LogFormat, diff --git a/espflash/src/error.rs b/espflash/src/error.rs index 740c18bd..325ab9bc 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -5,6 +5,11 @@ use std::{ io, }; +use miette::Diagnostic; +use slip_codec::SlipError; +use strum::{FromRepr, VariantNames}; +use thiserror::Error; + #[cfg(feature = "cli")] use crate::cli::monitor::parser::esp_defmt::DefmtError; #[cfg(feature = "serialport")] @@ -12,15 +17,9 @@ use crate::interface::SerialConfigError; use crate::{ command::CommandType, flasher::{FlashFrequency, FlashSize}, - image_format::ImageFormatKind, targets::Chip, }; -use miette::Diagnostic; -use slip_codec::SlipError; -use strum::{FromRepr, VariantNames}; -use thiserror::Error; - /// All possible errors returned by espflash #[derive(Debug, Diagnostic, Error)] #[non_exhaustive] @@ -107,16 +106,6 @@ pub enum Error { #[diagnostic(code(espflash::invalid_bootloader_path))] InvalidBootloaderPath, - #[error("Binary is not set up correctly to support direct boot")] - #[diagnostic( - code(espflash::invalid_direct_boot), - help( - "See the following page for documentation on how to set up your binary for direct boot:\ - https://github.com/espressif/esp32c3-direct-boot-example" - ) - )] - InvalidDirectBootBinary, - #[error("The flash size '{0}' is invalid")] #[diagnostic( code(espflash::invalid_flash_size), @@ -165,13 +154,6 @@ pub enum Error { )] SerialNotFound(String), - #[error("Unrecognized image format '{0}'")] - #[diagnostic( - code(espflash::unknown_format), - help("The following image formats are supported: {}", ImageFormatKind::VARIANTS.join(", ")) - )] - UnknownImageFormat(String), - #[error("The {chip} does not support {feature}")] #[diagnostic(code(espflash::unsupported_feature))] UnsupportedFeature { chip: Chip, feature: String }, @@ -221,10 +203,6 @@ pub enum Error { #[diagnostic(transparent)] RomError(#[from] RomError), - #[error(transparent)] - #[diagnostic(transparent)] - UnsupportedImageFormat(#[from] UnsupportedImageFormatError), - #[cfg(feature = "serialport")] #[error(transparent)] #[diagnostic(transparent)] @@ -517,80 +495,6 @@ impl From<&'static str> for ElfError { } } -/// Unsupported image format error -#[derive(Debug)] -pub struct UnsupportedImageFormatError { - format: ImageFormatKind, - chip: Chip, - revision: Option<(u32, u32)>, - context: Option, -} - -impl UnsupportedImageFormatError { - pub fn new(format: ImageFormatKind, chip: Chip, revision: Option<(u32, u32)>) -> Self { - Self { - format, - chip, - revision, - context: None, - } - } - - /// Return a comma-separated list of supported image formats - fn supported_formats(&self) -> String { - self.chip - .into_target() - .supported_image_formats() - .iter() - .map(|format| format.into()) - .collect::>() - .join(", ") - } - - /// Update the context of the unsupported image format error - pub fn with_context(mut self, ctx: String) -> Self { - self.context.replace(ctx); - - self - } -} - -impl std::error::Error for UnsupportedImageFormatError {} - -impl Display for UnsupportedImageFormatError { - fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - write!( - f, - "Image format {} is not supported by the {}", - self.format, self.chip - )?; - - if let Some((major, minor)) = self.revision { - write!(f, " revision v{major}.{minor}")?; - } - - Ok(()) - } -} - -impl Diagnostic for UnsupportedImageFormatError { - fn code<'a>(&'a self) -> Option> { - Some(Box::new("espflash::unsupported_image_format")) - } - - fn help<'a>(&'a self) -> Option> { - if let Some(ref ctx) = self.context { - Some(Box::new(ctx)) - } else { - Some(Box::new(format!( - "The following image formats are supported by the {}: {}", - self.chip, - self.supported_formats() - ))) - } - } -} - pub(crate) trait ResultExt { /// Mark an error as having occurred during the flashing stage fn flashing(self) -> Self; diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index 41367b59..b65d5173 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -28,7 +28,6 @@ use crate::{ command::{Command, CommandType}, elf::{ElfFirmwareImage, FirmwareImage, RomSegment}, error::{ConnectionError, Error, ResultExt}, - image_format::ImageFormatKind, targets::{Chip, XtalFrequency}, }; #[cfg(feature = "serialport")] @@ -285,7 +284,6 @@ pub struct FlashDataBuilder<'a> { bootloader_path: Option<&'a Path>, partition_table_path: Option<&'a Path>, partition_table_offset: Option, - image_format: Option, target_app_partition: Option, flash_settings: FlashSettings, min_chip_rev: u16, @@ -297,7 +295,6 @@ impl<'a> Default for FlashDataBuilder<'a> { bootloader_path: Default::default(), partition_table_path: Default::default(), partition_table_offset: Default::default(), - image_format: Default::default(), target_app_partition: Default::default(), flash_settings: FlashSettings::default(), min_chip_rev: Default::default(), @@ -329,12 +326,6 @@ impl<'a> FlashDataBuilder<'a> { self } - /// Sets the image format. - pub fn with_image_format(mut self, image_format: ImageFormatKind) -> Self { - self.image_format = Some(image_format); - self - } - /// Sets the label of the target app partition. pub fn with_target_app_partition(mut self, target_app_partition: String) -> Self { self.target_app_partition = Some(target_app_partition); @@ -359,7 +350,6 @@ impl<'a> FlashDataBuilder<'a> { self.bootloader_path, self.partition_table_path, self.partition_table_offset, - self.image_format, self.target_app_partition, self.flash_settings, self.min_chip_rev, @@ -374,7 +364,6 @@ pub struct FlashData { pub bootloader: Option>, pub partition_table: Option, pub partition_table_offset: Option, - pub image_format: Option, pub target_app_partition: Option, pub flash_settings: FlashSettings, pub min_chip_rev: u16, @@ -385,7 +374,6 @@ impl FlashData { bootloader: Option<&Path>, partition_table: Option<&Path>, partition_table_offset: Option, - image_format: Option, target_app_partition: Option, flash_settings: FlashSettings, min_chip_rev: u16, @@ -412,7 +400,6 @@ impl FlashData { bootloader, partition_table, partition_table_offset, - image_format, target_app_partition, flash_settings, min_chip_rev, diff --git a/espflash/src/image_format/idf_bootloader.rs b/espflash/src/image_format.rs similarity index 75% rename from espflash/src/image_format/idf_bootloader.rs rename to espflash/src/image_format.rs index 3f654f54..d1d722cb 100644 --- a/espflash/src/image_format/idf_bootloader.rs +++ b/espflash/src/image_format.rs @@ -1,22 +1,104 @@ +//! ESP-IDF application binary image format + use std::{borrow::Cow, io::Write, iter::once, mem::size_of}; -use bytemuck::{bytes_of, from_bytes}; +use bytemuck::{bytes_of, from_bytes, Pod, Zeroable}; use esp_idf_part::{Partition, PartitionTable, Type}; use sha2::{Digest, Sha256}; use crate::{ elf::{CodeSegment, FirmwareImage, RomSegment}, error::Error, - flasher::FlashSettings, - image_format::{ - update_checksum, ImageFormat, ImageHeader, SegmentHeader, ESP_CHECKSUM_MAGIC, ESP_MAGIC, - WP_PIN_DISABLED, - }, + flasher::{FlashFrequency, FlashMode, FlashSettings, FlashSize}, targets::{Chip, Esp32Params}, }; +const ESP_CHECKSUM_MAGIC: u8 = 0xef; +const ESP_MAGIC: u8 = 0xE9; const IROM_ALIGN: u32 = 0x10000; const SEG_HEADER_LEN: u32 = 8; +const WP_PIN_DISABLED: u8 = 0xEE; + +/// Firmware header used by the ESP-IDF bootloader. +/// +/// ## Header documentation: +/// * [Header](https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/firmware-image-format.html#file-header) +/// * [Extended header](https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/firmware-image-format.html#extended-file-header) +#[derive(Debug, Clone, Copy, Pod, Zeroable)] +#[repr(C, packed)] +#[doc(alias = "esp_image_header_t")] +struct ImageHeader { + magic: u8, + segment_count: u8, + /// Flash read mode (esp_image_spi_mode_t) + flash_mode: u8, + /// ..4 bits are flash chip size (esp_image_flash_size_t) + /// 4.. bits are flash frequency (esp_image_spi_freq_t) + #[doc(alias = "spi_size")] + #[doc(alias = "spi_speed")] + flash_config: u8, + entry: u32, + + // extended header part + wp_pin: u8, + clk_q_drv: u8, + d_cs_drv: u8, + gd_wp_drv: u8, + chip_id: u16, + min_rev: u8, + /// Minimum chip revision supported by image, in format: major * 100 + minor + min_chip_rev_full: u16, + /// Maximal chip revision supported by image, in format: major * 100 + minor + max_chip_rev_full: u16, + reserved: [u8; 4], + append_digest: u8, +} + +impl Default for ImageHeader { + fn default() -> Self { + Self { + magic: ESP_MAGIC, + segment_count: 3, + flash_mode: FlashMode::default() as _, + flash_config: ((FlashSize::default() as u8) << 4) | FlashFrequency::default() as u8, + entry: 0, + wp_pin: WP_PIN_DISABLED, + clk_q_drv: 0, + d_cs_drv: 0, + gd_wp_drv: 0, + chip_id: Default::default(), + min_rev: 0, + min_chip_rev_full: 0, + max_chip_rev_full: u16::MAX, + reserved: Default::default(), + append_digest: 1, + } + } +} + +impl ImageHeader { + /// Updates flash size and speed filed. + pub fn write_flash_config( + &mut self, + size: FlashSize, + freq: FlashFrequency, + chip: Chip, + ) -> Result<(), Error> { + let flash_size = size.encode_flash_size()?; + let flash_speed = freq.encode_flash_frequency(chip)?; + + // bit field + self.flash_config = (flash_size << 4) | flash_speed; + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, Pod, Zeroable)] +#[repr(C, packed)] +struct SegmentHeader { + addr: u32, + length: u32, +} /// Image format for ESP32 family chips using the second-stage bootloader from /// ESP-IDF @@ -188,8 +270,9 @@ impl<'a> IdfBootloaderFormat<'a> { data: Cow::Owned(data), }; - // If the user did not specify a partition offset, we need to assume that the partition - // offset is (first partition offset) - 0x1000, since this is the most common case. + // If the user did not specify a partition offset, we need to assume that the + // partition offset is (first partition offset) - 0x1000, since this is + // the most common case. let partition_table_offset = partition_table_offset.unwrap_or_else(|| { let partitions = partition_table.partitions(); let first_partition = partitions @@ -209,10 +292,8 @@ impl<'a> IdfBootloaderFormat<'a> { partition_table_offset, }) } -} -impl<'a> ImageFormat<'a> for IdfBootloaderFormat<'a> { - fn flash_segments<'b>(&'b self) -> Box> + 'b> + pub fn flash_segments<'b>(&'b self) -> Box> + 'b> where 'a: 'b, { @@ -252,18 +333,18 @@ impl<'a> ImageFormat<'a> for IdfBootloaderFormat<'a> { ) } - fn ota_segments<'b>(&'b self) -> Box> + 'b> + pub fn ota_segments<'b>(&'b self) -> Box> + 'b> where 'a: 'b, { Box::new(once(self.flash_segment.borrow())) } - fn app_size(&self) -> u32 { + pub fn app_size(&self) -> u32 { self.app_size } - fn part_size(&self) -> Option { + pub fn part_size(&self) -> Option { Some(self.part_size) } } @@ -346,47 +427,30 @@ fn save_segment(data: &mut Vec, segment: &CodeSegment, checksum: u8) -> Resu Ok(update_checksum(segment.data(), checksum)) } -#[cfg(test)] -pub mod tests { - use std::fs; +/// Update the checksum with the given data +fn update_checksum(data: &[u8], mut checksum: u8) -> u8 { + for byte in data { + checksum ^= *byte; + } + checksum +} + +#[cfg(test)] +mod tests { use super::*; - use crate::{elf::ElfFirmwareImage, image_format::FlashFrequency}; - - // Copied from: src/targets/esp32.rs - const PARAMS: Esp32Params = Esp32Params::new( - 0x1000, - 0x1_0000, - 0x3f_0000, - 0, - FlashFrequency::_40Mhz, - include_bytes!("../../resources/bootloaders/esp32-bootloader.bin"), - ); #[test] - fn test_idf_bootloader_format() { - let input_bytes = fs::read("tests/resources/esp32_hal_blinky").unwrap(); - let expected_bin = fs::read("tests/resources/esp32_hal_blinky.bin").unwrap(); - - let image = ElfFirmwareImage::try_from(input_bytes.as_slice()).unwrap(); - let flash_image = IdfBootloaderFormat::new( - &image, - Chip::Esp32, - 0, - PARAMS, - None, - None, - None, - None, - FlashSettings::default(), - ) - .unwrap(); - - let segments = flash_image.flash_segments().collect::>(); - assert_eq!(segments.len(), 3); - - let buf = segments[2].data.as_ref(); - assert_eq!(expected_bin.len(), buf.len()); - assert_eq!(expected_bin.as_slice(), buf); + fn test_flash_config_write() { + let mut header = ImageHeader::default(); + header + .write_flash_config(FlashSize::_4Mb, FlashFrequency::_40Mhz, Chip::Esp32c3) + .unwrap(); + assert_eq!(header.flash_config, 0x20); + + header + .write_flash_config(FlashSize::_32Mb, FlashFrequency::_80Mhz, Chip::Esp32s3) + .unwrap(); + assert_eq!(header.flash_config, 0x5F); } } diff --git a/espflash/src/image_format/direct_boot.rs b/espflash/src/image_format/direct_boot.rs deleted file mode 100644 index 9399b12a..00000000 --- a/espflash/src/image_format/direct_boot.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::iter::once; - -use crate::{ - elf::{CodeSegment, FirmwareImage, RomSegment}, - error::Error, - image_format::ImageFormat, -}; - -/// Magic number for Direct boot which should be the first 8 bytes in flash -const DIRECT_BOOT_MAGIC: &[u8] = &[0x1d, 0x04, 0xdb, 0xae, 0x1d, 0x04, 0xdb, 0xae]; - -/// Image format for ESP32 family chips not using a second-stage bootloader -pub struct DirectBootFormat<'a> { - segment: RomSegment<'a>, -} - -impl<'a> DirectBootFormat<'a> { - pub fn new(image: &'a dyn FirmwareImage<'a>, magic_offset: usize) -> Result { - let mut segment = image - .segments_with_load_addresses() - .map(|mut segment| { - // Map the address to the first 4MB of address space - segment.addr %= 0x40_0000; - segment - }) - .fold(CodeSegment::default(), |mut a, b| { - a += &b; - a - }); - - segment.pad_align(4); - - if segment.addr != 0 - || (segment.data().len() >= magic_offset + 8 - && &segment.data()[magic_offset..][..8] != DIRECT_BOOT_MAGIC) - { - return Err(Error::InvalidDirectBootBinary); - } - - Ok(Self { - segment: segment.into(), - }) - } -} - -impl<'a> ImageFormat<'a> for DirectBootFormat<'a> { - fn flash_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b, - { - Box::new(once(self.segment.borrow())) - } - - fn ota_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b, - { - Box::new(once(self.segment.borrow())) - } - - fn app_size(&self) -> u32 { - self.segment.data.len() as u32 - } - - fn part_size(&self) -> Option { - None - } -} - -#[cfg(test)] -pub mod tests { - use std::fs; - - use super::*; - use crate::elf::ElfFirmwareImage; - - #[test] - fn test_direct_boot_format() { - let input_bytes = fs::read("tests/resources/esp32c3_hal_blinky_db").unwrap(); - let expected_bin = fs::read("tests/resources/esp32c3_hal_blinky_db.bin").unwrap(); - - let image = ElfFirmwareImage::try_from(input_bytes.as_slice()).unwrap(); - let flash_image = DirectBootFormat::new(&image, 0).unwrap(); - - let segments = flash_image.flash_segments().collect::>(); - assert_eq!(segments.len(), 1); - - let buf = segments[0].data.as_ref(); - assert_eq!(expected_bin.len(), buf.len()); - assert_eq!(expected_bin.as_slice(), buf); - } -} diff --git a/espflash/src/image_format/mod.rs b/espflash/src/image_format/mod.rs deleted file mode 100644 index a49d52d2..00000000 --- a/espflash/src/image_format/mod.rs +++ /dev/null @@ -1,181 +0,0 @@ -//! ESP-IDF application binary image format - -use std::str::FromStr; - -use bytemuck::{Pod, Zeroable}; -use serde::Deserialize; -use strum::{Display, EnumVariantNames, IntoStaticStr}; - -pub use self::{direct_boot::DirectBootFormat, idf_bootloader::IdfBootloaderFormat}; -use crate::{ - elf::RomSegment, - error::Error, - flasher::{FlashFrequency, FlashMode, FlashSize}, - targets::Chip, -}; - -mod direct_boot; -mod idf_bootloader; - -const ESP_CHECKSUM_MAGIC: u8 = 0xef; -const ESP_MAGIC: u8 = 0xE9; -const WP_PIN_DISABLED: u8 = 0xEE; - -/// Firmware header used by the ESP-IDF bootloader. -/// -/// ## Header documentation: -/// * [Header](https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/firmware-image-format.html#file-header) -/// * [Extended header](https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/firmware-image-format.html#extended-file-header) -#[derive(Debug, Clone, Copy, Pod, Zeroable)] -#[repr(C, packed)] -#[doc(alias = "esp_image_header_t")] -struct ImageHeader { - magic: u8, - segment_count: u8, - /// Flash read mode (esp_image_spi_mode_t) - flash_mode: u8, - /// ..4 bits are flash chip size (esp_image_flash_size_t) - /// 4.. bits are flash frequency (esp_image_spi_freq_t) - #[doc(alias = "spi_size")] - #[doc(alias = "spi_speed")] - flash_config: u8, - entry: u32, - - // extended header part - wp_pin: u8, - clk_q_drv: u8, - d_cs_drv: u8, - gd_wp_drv: u8, - chip_id: u16, - min_rev: u8, - /// Minimum chip revision supported by image, in format: major * 100 + minor - min_chip_rev_full: u16, - /// Maximal chip revision supported by image, in format: major * 100 + minor - max_chip_rev_full: u16, - reserved: [u8; 4], - append_digest: u8, -} - -impl Default for ImageHeader { - fn default() -> Self { - Self { - magic: ESP_MAGIC, - segment_count: 3, - flash_mode: FlashMode::default() as _, - flash_config: ((FlashSize::default() as u8) << 4) | FlashFrequency::default() as u8, - entry: 0, - wp_pin: WP_PIN_DISABLED, - clk_q_drv: 0, - d_cs_drv: 0, - gd_wp_drv: 0, - chip_id: Default::default(), - min_rev: 0, - min_chip_rev_full: 0, - max_chip_rev_full: u16::MAX, - reserved: Default::default(), - append_digest: 1, - } - } -} - -impl ImageHeader { - /// Updates flash size and speed filed. - pub fn write_flash_config( - &mut self, - size: FlashSize, - freq: FlashFrequency, - chip: Chip, - ) -> Result<(), Error> { - let flash_size = size.encode_flash_size()?; - let flash_speed = freq.encode_flash_frequency(chip)?; - - // bit field - self.flash_config = (flash_size << 4) | flash_speed; - Ok(()) - } -} - -#[derive(Debug, Clone, Copy, Pod, Zeroable)] -#[repr(C, packed)] -struct SegmentHeader { - addr: u32, - length: u32, -} - -/// Operations for working with firmware image formats -pub trait ImageFormat<'a>: Send { - /// Get the ROM segments needed when flashing to device - fn flash_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b; - - /// Get the ROM segments to save when exporting for OTA - /// - /// Compared to `flash_segments` this excludes things like bootloader and - /// partition table - fn ota_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b; - - /// The size of the application binary - fn app_size(&self) -> u32; - - /// If applicable, the size of the application partition (if it can be - /// determined) - fn part_size(&self) -> Option; -} - -/// All supported firmware image formats -#[cfg_attr(feature = "cli", derive(clap::ValueEnum))] -#[derive( - Debug, Copy, Clone, Eq, PartialEq, Display, IntoStaticStr, EnumVariantNames, Deserialize, -)] -#[non_exhaustive] -#[strum(serialize_all = "kebab-case")] -#[serde(rename_all = "kebab-case")] -pub enum ImageFormatKind { - /// Use the second-stage bootloader from ESP-IDF - EspBootloader, - /// Use direct boot and do not use a second-stage bootloader at all - DirectBoot, -} - -impl FromStr for ImageFormatKind { - type Err = Error; - - fn from_str(s: &str) -> Result { - match s { - "esp-bootloader" => Ok(Self::EspBootloader), - "direct-boot" => Ok(Self::DirectBoot), - _ => Err(Error::UnknownImageFormat(s.into())), - } - } -} - -/// Update the checksum with the given data -fn update_checksum(data: &[u8], mut checksum: u8) -> u8 { - for byte in data { - checksum ^= *byte; - } - - checksum -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_flash_config_write() { - let mut header = ImageHeader::default(); - header - .write_flash_config(FlashSize::_4Mb, FlashFrequency::_40Mhz, Chip::Esp32c3) - .unwrap(); - assert_eq!(header.flash_config, 0x20); - - header - .write_flash_config(FlashSize::_32Mb, FlashFrequency::_80Mhz, Chip::Esp32s3) - .unwrap(); - assert_eq!(header.flash_config, 0x5F); - } -} diff --git a/espflash/src/targets/esp32.rs b/espflash/src/targets/esp32.rs index 75acd046..1a05317b 100644 --- a/espflash/src/targets/esp32.rs +++ b/espflash/src/targets/esp32.rs @@ -4,9 +4,9 @@ use std::ops::Range; use crate::{connection::Connection, targets::bytes_to_mac_addr}; use crate::{ elf::FirmwareImage, - error::{Error, UnsupportedImageFormatError}, + error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -155,11 +155,7 @@ impl Target for Esp32 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { let booloader: &'static [u8] = match xtal_freq { XtalFrequency::_40Mhz => { include_bytes!("../../resources/bootloaders/esp32-bootloader.bin") @@ -184,20 +180,17 @@ impl Target for Esp32 { booloader, ); - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32, - flash_data.min_chip_rev, - params, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - _ => Err(UnsupportedImageFormatError::new(image_format, Chip::Esp32, None).into()), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32, + flash_data.min_chip_rev, + params, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } #[cfg(feature = "serialport")] diff --git a/espflash/src/targets/esp32c2.rs b/espflash/src/targets/esp32c2.rs index ff707d53..f7d9b1f8 100644 --- a/espflash/src/targets/esp32c2.rs +++ b/espflash/src/targets/esp32c2.rs @@ -6,7 +6,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -88,11 +88,7 @@ impl Target for Esp32c2 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { let booloader: &'static [u8] = match xtal_freq { XtalFrequency::_40Mhz => { println!("Using 40MHz bootloader"); @@ -119,20 +115,17 @@ impl Target for Esp32c2 { booloader, ); - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32c2, - flash_data.min_chip_rev, - params, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - ImageFormatKind::DirectBoot => Ok(Box::new(DirectBootFormat::new(image, 0)?)), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32c2, + flash_data.min_chip_rev, + params, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } #[cfg(feature = "serialport")] @@ -160,10 +153,6 @@ impl Target for Esp32c2 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &[ "riscv32imac-unknown-none-elf", diff --git a/espflash/src/targets/esp32c3.rs b/espflash/src/targets/esp32c3.rs index 5a62d033..31f7cfbf 100644 --- a/espflash/src/targets/esp32c3.rs +++ b/espflash/src/targets/esp32c3.rs @@ -4,9 +4,9 @@ use std::ops::Range; use crate::connection::Connection; use crate::{ elf::FirmwareImage, - error::{Error, UnsupportedImageFormatError}, + error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -80,13 +80,9 @@ impl Target for Esp32c3 { &self, image: &'a dyn FirmwareImage<'a>, flash_data: FlashData, - chip_revision: Option<(u32, u32)>, + _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_40Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32c3, @@ -94,30 +90,17 @@ impl Target for Esp32c3 { }); } - match (image_format, chip_revision) { - (ImageFormatKind::EspBootloader, _) => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32c3, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - (ImageFormatKind::DirectBoot, None | Some((_, 3..))) => { - Ok(Box::new(DirectBootFormat::new(image, 0)?)) - } - _ => Err( - UnsupportedImageFormatError::new(image_format, Chip::Esp32c3, chip_revision) - .with_context(format!( - "The {} only supports direct-boot starting with revision 3 (v0.3)", - Chip::Esp32c3, - )) - .into(), - ), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32c3, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } fn spi_registers(&self) -> SpiRegisters { @@ -132,10 +115,6 @@ impl Target for Esp32c3 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &[ "riscv32imac-unknown-none-elf", diff --git a/espflash/src/targets/esp32c6.rs b/espflash/src/targets/esp32c6.rs index 4b0587ba..082bfcb9 100644 --- a/espflash/src/targets/esp32c6.rs +++ b/espflash/src/targets/esp32c6.rs @@ -6,7 +6,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -77,11 +77,7 @@ impl Target for Esp32c6 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_40Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32c6, @@ -89,20 +85,17 @@ impl Target for Esp32c6 { }); } - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32c6, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - ImageFormatKind::DirectBoot => Ok(Box::new(DirectBootFormat::new(image, 0x0)?)), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32c6, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } fn spi_registers(&self) -> SpiRegisters { @@ -117,10 +110,6 @@ impl Target for Esp32c6 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &["riscv32imac-esp-espidf", "riscv32imac-unknown-none-elf"] } diff --git a/espflash/src/targets/esp32h2.rs b/espflash/src/targets/esp32h2.rs index f62f60f7..c0a3ec57 100644 --- a/espflash/src/targets/esp32h2.rs +++ b/espflash/src/targets/esp32h2.rs @@ -1,5 +1,4 @@ -use std::collections::HashMap; -use std::ops::Range; +use std::{collections::HashMap, ops::Range}; #[cfg(feature = "serialport")] use crate::connection::Connection; @@ -7,7 +6,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -85,11 +84,7 @@ impl Target for Esp32h2 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_32Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32h2, @@ -97,20 +92,17 @@ impl Target for Esp32h2 { }); } - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32h2, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - ImageFormatKind::DirectBoot => Ok(Box::new(DirectBootFormat::new(image, 0x0)?)), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32h2, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } fn spi_registers(&self) -> SpiRegisters { @@ -125,10 +117,6 @@ impl Target for Esp32h2 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &["riscv32imac-esp-espidf", "riscv32imac-unknown-none-elf"] } diff --git a/espflash/src/targets/esp32p4.rs b/espflash/src/targets/esp32p4.rs index 7c93efdf..a500028f 100644 --- a/espflash/src/targets/esp32p4.rs +++ b/espflash/src/targets/esp32p4.rs @@ -6,7 +6,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -75,11 +75,7 @@ impl Target for Esp32p4 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_40Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32p4, @@ -87,20 +83,17 @@ impl Target for Esp32p4 { }); } - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32p4, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - ImageFormatKind::DirectBoot => Ok(Box::new(DirectBootFormat::new(image, 0x0)?)), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32p4, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } fn spi_registers(&self) -> SpiRegisters { @@ -115,10 +108,6 @@ impl Target for Esp32p4 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &["riscv32imafc-esp-espidf", "riscv32imafc-unknown-none-elf"] } diff --git a/espflash/src/targets/esp32s2.rs b/espflash/src/targets/esp32s2.rs index 0ca7a833..ef9c5a4f 100644 --- a/espflash/src/targets/esp32s2.rs +++ b/espflash/src/targets/esp32s2.rs @@ -4,9 +4,9 @@ use std::ops::Range; use crate::{connection::Connection, targets::MAX_RAM_BLOCK_SIZE}; use crate::{ elf::FirmwareImage, - error::{Error, UnsupportedImageFormatError}, + error::Error, flasher::{FlashData, FlashFrequency, FLASH_WRITE_SIZE}, - image_format::{IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -150,11 +150,7 @@ impl Target for Esp32s2 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_40Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32s2, @@ -162,20 +158,17 @@ impl Target for Esp32s2 { }); } - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32s2, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - _ => Err(UnsupportedImageFormatError::new(image_format, Chip::Esp32s2, None).into()), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32s2, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } #[cfg(feature = "serialport")] diff --git a/espflash/src/targets/esp32s3.rs b/espflash/src/targets/esp32s3.rs index 54396e14..59798c69 100644 --- a/espflash/src/targets/esp32s3.rs +++ b/espflash/src/targets/esp32s3.rs @@ -6,7 +6,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency}, - image_format::{DirectBootFormat, IdfBootloaderFormat, ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, targets::{Chip, Esp32Params, ReadEFuse, SpiRegisters, Target, XtalFrequency}, }; @@ -101,11 +101,7 @@ impl Target for Esp32s3 { flash_data: FlashData, _chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - + ) -> Result, Error> { if xtal_freq != XtalFrequency::_40Mhz { return Err(Error::UnsupportedFeature { chip: Chip::Esp32s3, @@ -113,20 +109,17 @@ impl Target for Esp32s3 { }); } - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new( - image, - Chip::Esp32s3, - flash_data.min_chip_rev, - PARAMS, - flash_data.partition_table, - flash_data.partition_table_offset, - flash_data.target_app_partition, - flash_data.bootloader, - flash_data.flash_settings, - )?)), - ImageFormatKind::DirectBoot => Ok(Box::new(DirectBootFormat::new(image, 0x400)?)), - } + IdfBootloaderFormat::new( + image, + Chip::Esp32s3, + flash_data.min_chip_rev, + PARAMS, + flash_data.partition_table, + flash_data.partition_table_offset, + flash_data.target_app_partition, + flash_data.bootloader, + flash_data.flash_settings, + ) } fn spi_registers(&self) -> SpiRegisters { @@ -141,10 +134,6 @@ impl Target for Esp32s3 { } } - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader, ImageFormatKind::DirectBoot] - } - fn supported_build_targets(&self) -> &[&str] { &["xtensa-esp32s3-none-elf", "xtensa-esp32s3-espidf"] } diff --git a/espflash/src/targets/mod.rs b/espflash/src/targets/mod.rs index daea7cad..99b5898f 100644 --- a/espflash/src/targets/mod.rs +++ b/espflash/src/targets/mod.rs @@ -29,7 +29,7 @@ use crate::{ elf::FirmwareImage, error::Error, flasher::{FlashData, FlashFrequency, SpiAttachParams, FLASH_WRITE_SIZE}, - image_format::{ImageFormat, ImageFormatKind}, + image_format::IdfBootloaderFormat, }; /// Max partition size is 16 MB @@ -354,7 +354,7 @@ pub trait Target: ReadEFuse { flash_data: FlashData, chip_revision: Option<(u32, u32)>, xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error>; + ) -> Result, Error>; #[cfg(feature = "serialport")] /// What is the MAC address? @@ -378,11 +378,6 @@ pub trait Target: ReadEFuse { /// SPI register addresses for a chip fn spi_registers(&self) -> SpiRegisters; - /// Image formats supported by a chip - fn supported_image_formats(&self) -> &[ImageFormatKind] { - &[ImageFormatKind::EspBootloader] - } - /// Build targets supported by a chip fn supported_build_targets(&self) -> &[&str]; diff --git a/espflash/tests/README.md b/espflash/tests/README.md index 97269c91..aae6340c 100644 --- a/espflash/tests/README.md +++ b/espflash/tests/README.md @@ -2,20 +2,6 @@ This document describes how the test files under `tests/resources` were generated, so that they can be re-generated in the future if needed. -## Direct Boot - -```bash -$ git clone https://github.com/esp-rs/esp-hal -$ cd esp-hal/esp32c3-hal/ -$ cargo build --release --features=direct-boot --example=blinky -``` - -The ELF file is located at `target/riscv32imc-unknown-none-elf/release/examples/blinky` - -```bash -$ espflash save-image --format=direct-boot --chip=esp32c3 esp32c3_hal_blinky_db.bin esp32c3_hal_blinky_db -``` - ## IDF Bootloader ```bash diff --git a/espflash/tests/resources/esp32c3_hal_blinky_db b/espflash/tests/resources/esp32c3_hal_blinky_db deleted file mode 100755 index da70d19a..00000000 Binary files a/espflash/tests/resources/esp32c3_hal_blinky_db and /dev/null differ diff --git a/espflash/tests/resources/esp32c3_hal_blinky_db.bin b/espflash/tests/resources/esp32c3_hal_blinky_db.bin deleted file mode 100644 index 63e88c73..00000000 Binary files a/espflash/tests/resources/esp32c3_hal_blinky_db.bin and /dev/null differ diff --git a/espflash/tests/resources/esp8266_hal_blinky b/espflash/tests/resources/esp8266_hal_blinky deleted file mode 100755 index d4a542f3..00000000 Binary files a/espflash/tests/resources/esp8266_hal_blinky and /dev/null differ diff --git a/espflash/tests/resources/esp8266_hal_blinky.bin b/espflash/tests/resources/esp8266_hal_blinky.bin deleted file mode 100644 index 695c9eac..00000000 Binary files a/espflash/tests/resources/esp8266_hal_blinky.bin and /dev/null differ