Skip to content

Commit 007881f

Browse files
authored
Bail from flashing a partition table to too-small flash (#830)
* Don't flash unbootable partition table * Attempt to test
1 parent 8aa91ef commit 007881f

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Add `--output-format` option to monitor (#818)
2222
- Added chip detection based on security info, where supported (#814)
2323
- `espflash` can detect the chip from ESP-HAL metadata to prevent flashing firmware built for a different device. Reqires `esp-hal` 1.0.0-beta.0 (presumably, yet to be released) (#816)
24+
- `espflash` no longer allows flashing a too-big partition table (#830)
2425

2526
### Changed
2627

espflash/src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ pub enum Error {
228228
help("Ensure that the device is connected and your host recognizes the serial adapter")
229229
)]
230230
FirmwareChipMismatch { elf: String, detected: Chip },
231+
232+
#[error("The partition table does not fit into the flash ({0})")]
233+
#[diagnostic(
234+
code(espflash::partition_table::does_not_fit),
235+
help("Make sure you set the correct flash size with the `--flash-size` option")
236+
)]
237+
PartitionTableDoesNotFit(FlashSize),
231238
}
232239

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

espflash/src/image_format/esp_idf.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ impl<'a> IdfBootloaderFormat<'a> {
130130
default_partition_table(&params, flash_data.flash_settings.size.map(|v| v.size()))
131131
});
132132

133+
if partition_table
134+
.partitions()
135+
.iter()
136+
.map(|p| p.size())
137+
.sum::<u32>()
138+
> flash_data.flash_settings.size.unwrap_or_default().size()
139+
{
140+
return Err(Error::PartitionTableDoesNotFit(
141+
flash_data.flash_settings.size.unwrap_or_default(),
142+
));
143+
}
144+
133145
let mut bootloader = if let Some(bytes) = flash_data.bootloader {
134146
Cow::Owned(bytes)
135147
} else {
@@ -406,7 +418,7 @@ fn segment_padding(offset: usize, segment: &Segment<'_>) -> u32 {
406418
let align_past = (segment.addr - SEG_HEADER_LEN) % IROM_ALIGN;
407419
let pad_len = ((IROM_ALIGN - ((offset as u32) % IROM_ALIGN)) + align_past) % IROM_ALIGN;
408420

409-
if pad_len == 0 || pad_len == IROM_ALIGN {
421+
if pad_len % IROM_ALIGN == 0 {
410422
0
411423
} else if pad_len > SEG_HEADER_LEN {
412424
pad_len - SEG_HEADER_LEN

espflash/tests/data/partitions.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Name, Type, SubType, Offset, Size, Flags
2+
nvs, data, nvs, 0x9000, 0x6000,
3+
phy_init, data, phy, 0xf000, 0x1000,
4+
factory, app, factory, 0x10000, 4M,

espflash/tests/scripts/flash.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
#!/usr/bin/env bash
22
app="espflash/tests/data/$1"
3+
part_table="espflash/tests/data/partitions.csv"
4+
5+
# espflash should not flash a partition table that is too big
6+
result=$(timeout 15s espflash flash --no-skip --monitor --non-interactive $app --flash-size 2mb --partition-table $part_table 2>&1)
7+
echo "$result"
8+
if [[ $result =~ "Flashing has completed!" ]]; then
9+
echo "Flashing should have failed!"
10+
exit 1
11+
fi
12+
if [[ $result =~ "espflash::partition_table::does_not_fit" ]]; then
13+
echo "Flashing failed as expected!"
14+
else
15+
echo "Flashing has failed but not with the expected error!"
16+
exit 1
17+
fi
318

419
if [[ "$1" == "esp32c6" ]]; then
520
# With manual log-format

0 commit comments

Comments
 (0)