Skip to content

Commit 18a4e38

Browse files
JurajSadelMabezDev
andauthored
Check if bootloader has app descriptor (#872)
* Check if bootloader has app descriptor * changelog * refactor * another refactor * Update espflash/src/image_format/esp_idf.rs Co-authored-by: Scott Mabin <[email protected]> --------- Co-authored-by: Scott Mabin <[email protected]>
1 parent b8eb162 commit 18a4e38

File tree

7 files changed

+46
-1
lines changed

7 files changed

+46
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- Add support for the ESP32-C5 (#863)
2929
- `--after` options now work with `espflash board-info`, `espflash read-flash` and `espflash checksum-md5` (#867)
3030
- Add support for serial port configuration files. (#777)
31+
- Add a `check-app-descriptor` bool option to `ImageArgs` and add the flag to `flash` commad(#872)
3132

3233
### Changed
3334

cargo-espflash/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use espflash::{
1515
*,
1616
},
1717
flasher::FlashSize,
18+
image_format::check_idf_bootloader,
1819
logging::initialize_logger,
1920
targets::{Chip, XtalFrequency},
2021
update::check_for_update,
@@ -318,6 +319,11 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
318319
// Read the ELF data from the build path and load it to the target.
319320
let elf_data = fs::read(build_ctx.artifact_path.clone()).into_diagnostic()?;
320321

322+
// Check if the ELF contains the app descriptor, if required.
323+
if args.flash_args.image.check_app_descriptor.unwrap_or(true) {
324+
check_idf_bootloader(&elf_data)?;
325+
}
326+
321327
let mut monitor_args = args.flash_args.monitor_args;
322328
monitor_args.elf = Some(build_ctx.artifact_path.clone());
323329

espflash/src/bin/espflash.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use espflash::{
1010
*,
1111
},
1212
flasher::FlashSize,
13+
image_format::check_idf_bootloader,
1314
logging::initialize_logger,
1415
targets::{Chip, XtalFrequency},
1516
update::check_for_update,
@@ -235,6 +236,11 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
235236
// Read the ELF data from the build path and load it to the target.
236237
let elf_data = fs::read(&args.image).into_diagnostic()?;
237238

239+
// Check if the ELF contains the app descriptor, if required.
240+
if args.flash_args.image.check_app_descriptor.unwrap_or(true) {
241+
check_idf_bootloader(&elf_data)?;
242+
}
243+
238244
print_board_info(&mut flasher)?;
239245
ensure_chip_compatibility(chip, Some(elf_data.as_slice()))?;
240246

espflash/src/cli/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ pub struct ImageArgs {
253253
/// MMU page size.
254254
#[arg(long, value_name = "MMU_PAGE_SIZE", value_parser = parse_u32)]
255255
pub mmu_page_size: Option<u32>,
256+
/// Flag to check the app descriptor in bootloader
257+
#[arg(long, default_value = "true", value_parser = clap::value_parser!(bool))]
258+
pub check_app_descriptor: Option<bool>,
256259
}
257260

258261
#[derive(Debug, Args)]

espflash/src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,12 @@ pub enum Error {
253253
help("Make sure you set the correct flash size with the `--flash-size` option")
254254
)]
255255
PartitionTableDoesNotFit(FlashSize),
256+
257+
#[error(
258+
"The app descriptor is not present in the project. You need to add the https://github.com/esp-rs/esp-hal/tree/main/esp-bootloader-esp-idf to your project."
259+
)]
260+
#[diagnostic(code(espflash::app_desc::app_descriptor_not_present))]
261+
AppDescriptorNotPresent,
256262
}
257263

258264
#[cfg(feature = "serialport")]

espflash/src/image_format/esp_idf.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ use std::{borrow::Cow, ffi::c_char, io::Write, iter::once, mem::size_of};
55
use bytemuck::{Pod, Zeroable, bytes_of, from_bytes, pod_read_unaligned};
66
use esp_idf_part::{AppType, DataType, Flags, Partition, PartitionTable, SubType, Type};
77
use log::warn;
8-
use object::{Endianness, Object, ObjectSection, read::elf::ElfFile32 as ElfFile};
8+
use miette::{IntoDiagnostic, Result};
9+
use object::{
10+
Endianness,
11+
File,
12+
Object,
13+
ObjectSection,
14+
ObjectSymbol,
15+
read::elf::ElfFile32 as ElfFile,
16+
};
917
use sha2::{Digest, Sha256};
1018

1119
use super::{Segment, ram_segments, rom_segments};
@@ -666,6 +674,19 @@ where
666674
s
667675
}
668676

677+
/// Check if the provided ELF contains the app descriptor required by [the IDF bootloader](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/bootloader.html).
678+
pub fn check_idf_bootloader(elf_data: &Vec<u8>) -> Result<()> {
679+
let object = File::parse(elf_data.as_slice()).into_diagnostic()?;
680+
let section = object.section_by_name(".rodata_desc").is_some();
681+
let symbol = object.symbols().any(|sym| sym.name() == Ok("esp_app_desc"));
682+
683+
if !section || !symbol {
684+
return Err(Error::AppDescriptorNotPresent).into_diagnostic();
685+
}
686+
687+
Ok(())
688+
}
689+
669690
#[cfg(test)]
670691
mod tests {
671692
use super::*;

espflash/src/image_format/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use crate::targets::Chip;
2222
mod esp_idf;
2323
mod metadata;
2424

25+
pub use esp_idf::check_idf_bootloader;
26+
2527
/// A segment of code from the source ELF
2628
#[derive(Default, Clone, Eq)]
2729
pub struct Segment<'a> {

0 commit comments

Comments
 (0)