Skip to content

Commit 682d7da

Browse files
committed
esp32 image format: allow override of header params
* Pull the default header from the esp-idf generated bootloader. * Modify the header if required. * Use the same header for the app, with the entry point changed.
1 parent 1d1a390 commit 682d7da

File tree

3 files changed

+43
-27
lines changed

3 files changed

+43
-27
lines changed

espflash/src/elf.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,17 @@ impl FromStr for FlashFrequency {
7979
pub struct FirmwareImage<'a> {
8080
pub entry: u32,
8181
pub elf: ElfFile<'a>,
82-
pub flash_mode: FlashMode,
83-
pub flash_size: FlashSize,
84-
pub flash_frequency: FlashFrequency,
82+
pub flash_mode: Option<FlashMode>,
83+
pub flash_size: Option<FlashSize>,
84+
pub flash_frequency: Option<FlashFrequency>,
8585
}
8686

8787
impl<'a> FirmwareImage<'a> {
8888
pub fn new(
8989
elf: ElfFile<'a>,
90-
flash_mode: FlashMode,
91-
flash_size: FlashSize,
92-
flash_frequency: FlashFrequency,
90+
flash_mode: Option<FlashMode>,
91+
flash_size: Option<FlashSize>,
92+
flash_frequency: Option<FlashFrequency>,
9393
) -> Self {
9494
Self {
9595
entry: elf.header.pt2.entry_point() as u32,
@@ -184,11 +184,7 @@ impl<'a> FirmwareImageBuilder<'a> {
184184
pub fn build(&self) -> Result<FirmwareImage<'a>, Error> {
185185
let elf = ElfFile::new(self.data).map_err(ElfError::from)?;
186186

187-
let flash_mode = self.flash_mode.unwrap_or(FlashMode::Dio);
188-
let flash_size = self.flash_size.unwrap_or(FlashSize::Flash4Mb);
189-
let flash_freq = self.flash_freq.unwrap_or(FlashFrequency::Flash40M);
190-
191-
let image = FirmwareImage::new(elf, flash_mode, flash_size, flash_freq);
187+
let image = FirmwareImage::new(elf, self.flash_mode, self.flash_size, self.flash_freq);
192188

193189
Ok(image)
194190
}

espflash/src/image_format/esp32bootloader.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{borrow::Cow, io::Write, iter::once};
22

3-
use bytemuck::{bytes_of, Pod, Zeroable, from_bytes};
3+
use bytemuck::{bytes_of, from_bytes, Pod, Zeroable};
44
use sha2::{Digest, Sha256};
55

66
use crate::{
@@ -41,22 +41,41 @@ impl<'a> Esp32BootloaderFormat<'a> {
4141

4242
let mut data = Vec::new();
4343

44-
let header = EspCommonHeader {
45-
magic: ESP_MAGIC,
46-
segment_count: 0,
47-
flash_mode: image.flash_mode as u8,
48-
flash_config: encode_flash_size(image.flash_size)? + image.flash_frequency as u8,
49-
entry: image.entry,
50-
};
51-
52-
// Update the bootloader header
53-
let current: EspCommonHeader = *from_bytes(&bootloader[0..8]);
54-
if current.magic != ESP_MAGIC {
44+
// fetch the generated header from the bootloader
45+
let mut header: EspCommonHeader = *from_bytes(&bootloader[0..8]);
46+
if header.magic != ESP_MAGIC {
5547
return Err(Error::InvalidBootloader);
5648
}
57-
bootloader.to_mut()[2..4].copy_from_slice(&bytes_of(&header)[2..4]);
49+
// update the header if a user has specified any custom arguments
50+
if image.flash_frequency.is_some()
51+
|| image.flash_mode.is_some()
52+
|| image.flash_size.is_some()
53+
{
54+
if let Some(mode) = image.flash_mode {
55+
header.flash_mode = mode as u8;
56+
bootloader.to_mut()[2] = bytes_of(&header)[2];
57+
}
58+
match (image.flash_size, image.flash_frequency) {
59+
(Some(s), Some(f)) => {
60+
header.flash_config = encode_flash_size(s)? + f as u8;
61+
bootloader.to_mut()[3] = bytes_of(&header)[3];
62+
}
63+
(Some(s), None) => {
64+
header.flash_config = encode_flash_size(s)? + (header.flash_config & 0x0F);
65+
bootloader.to_mut()[3] = bytes_of(&header)[3];
66+
}
67+
(None, Some(f)) => {
68+
header.flash_config = (header.flash_config & 0xF0) + f as u8;
69+
bootloader.to_mut()[3] = bytes_of(&header)[3];
70+
}
71+
(None, None) => {} // nothing to update
72+
}
73+
}
5874

5975
// write the header of the app
76+
// use the same settings as the bootloader
77+
// just update the entry point
78+
header.entry = image.entry;
6079
data.write_all(bytes_of(&header))?;
6180

6281
let extended_header = ExtendedHeader {

espflash/src/image_format/esp8266.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
error::{Error, FlashDetectError},
88
flasher::FlashSize,
99
image_format::{EspCommonHeader, ImageFormat, SegmentHeader, ESP_MAGIC},
10-
Chip,
10+
Chip, FlashFrequency, FlashMode,
1111
};
1212

1313
const IROM_MAP_START: u32 = 0x40200000;
@@ -33,8 +33,9 @@ impl<'a> Esp8266Format<'a> {
3333
let header = EspCommonHeader {
3434
magic: ESP_MAGIC,
3535
segment_count: image.ram_segments(Chip::Esp8266).count() as u8,
36-
flash_mode: image.flash_mode as u8,
37-
flash_config: encode_flash_size(image.flash_size)? + image.flash_frequency as u8,
36+
flash_mode: image.flash_mode.unwrap_or(FlashMode::Dio) as u8,
37+
flash_config: encode_flash_size(image.flash_size.unwrap_or(FlashSize::Flash4Mb))?
38+
+ image.flash_frequency.unwrap_or(FlashFrequency::Flash40M) as u8,
3839
entry: image.entry,
3940
};
4041
common_data.write_all(bytes_of(&header))?;

0 commit comments

Comments
 (0)