Skip to content

Commit 0700010

Browse files
authored
Merge pull request #41 from jessebraham/bootloader
Add support for providing custom bootloaders
2 parents 1bdc265 + 779721a commit 0700010

File tree

8 files changed

+54
-15
lines changed

8 files changed

+54
-15
lines changed

cargo-espflash/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ FLAGS:
2121
-V, --version Prints version information
2222
2323
OPTIONS:
24-
--example <EXAMPLE> Example to build and flash
25-
--features <FEATURES> Comma delimited list of build features
26-
--speed <SPEED> Baud rate at which to flash target device
24+
--bootloader <PATH> Path to a binary (.bin) bootloader file
25+
--example <EXAMPLE> Example to build and flash
26+
--features <FEATURES> Comma delimited list of build features
27+
--partition-table <PATH> Path to a CSV file containing partition table
28+
--speed <SPEED> Baud rate at which to flash target device
2729
2830
ARGS:
2931
<SERIAL> Serial port connected to target device

cargo-espflash/src/main.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ fn main() -> anyhow::Result<()> {
3636
.long("release")
3737
.help("Build the application using the release profile"),
3838
)
39+
.arg(
40+
Arg::with_name("bootloader")
41+
.long("bootloader")
42+
.takes_value(true)
43+
.value_name("PATH")
44+
.help("Path to a binary (.bin) bootloader file"),
45+
)
3946
.arg(
4047
Arg::with_name("example")
4148
.long("example")
@@ -135,6 +142,16 @@ fn main() -> anyhow::Result<()> {
135142
return Ok(());
136143
}
137144

145+
// If the '--bootloader' option is provided, load the binary file at the
146+
// specified path.
147+
let bootloader = if let Some(path) = matches.value_of("bootloader") {
148+
let path = fs::canonicalize(path)?;
149+
let data = fs::read(path)?;
150+
Some(data)
151+
} else {
152+
None
153+
};
154+
138155
// If the '--partition-table' option is provided, load the partition table from
139156
// the CSV at the specified path.
140157
let partition_table = if let Some(path) = matches.value_of("partition_table") {
@@ -154,7 +171,7 @@ fn main() -> anyhow::Result<()> {
154171
if matches.is_present("ram") {
155172
flasher.load_elf_to_ram(&elf_data)?;
156173
} else {
157-
flasher.load_elf_to_flash(&elf_data, partition_table)?;
174+
flasher.load_elf_to_flash(&elf_data, bootloader, partition_table)?;
158175
}
159176

160177
// We're all done!

espflash/src/chip/esp32.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,15 @@ impl ChipType for Esp32 {
5151

5252
fn get_flash_segments<'a>(
5353
image: &'a FirmwareImage,
54+
bootloader: Option<Vec<u8>>,
5455
partition_table: Option<PartitionTable>,
5556
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a> {
56-
let bootloader = include_bytes!("../../bootloader/esp32-bootloader.bin");
57+
let bootloader = if let Some(bytes) = bootloader {
58+
bytes
59+
} else {
60+
let bytes = include_bytes!("../../bootloader/esp32-bootloader.bin");
61+
bytes.to_vec()
62+
};
5763

5864
let partition_table = if let Some(table) = partition_table {
5965
table
@@ -161,7 +167,7 @@ impl ChipType for Esp32 {
161167
Box::new(
162168
once(Ok(RomSegment {
163169
addr: BOOT_ADDR,
164-
data: Cow::Borrowed(bootloader),
170+
data: Cow::Owned(bootloader),
165171
}))
166172
.chain(once(Ok(RomSegment {
167173
addr: PARTION_ADDR,
@@ -181,7 +187,7 @@ fn test_esp32_rom() {
181187

182188
let image = FirmwareImage::from_data(&input_bytes).unwrap();
183189

184-
let segments = Esp32::get_flash_segments(&image, None)
190+
let segments = Esp32::get_flash_segments(&image, None, None)
185191
.collect::<Result<Vec<_>, Error>>()
186192
.unwrap();
187193

espflash/src/chip/esp32c3.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,15 @@ impl ChipType for Esp32c3 {
5252

5353
fn get_flash_segments<'a>(
5454
image: &'a FirmwareImage,
55+
bootloader: Option<Vec<u8>>,
5556
partition_table: Option<PartitionTable>,
5657
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a> {
57-
let bootloader = include_bytes!("../../bootloader/esp32c3-bootloader.bin");
58+
let bootloader = if let Some(bytes) = bootloader {
59+
bytes
60+
} else {
61+
let bytes = include_bytes!("../../bootloader/esp32c3-bootloader.bin");
62+
bytes.to_vec()
63+
};
5864

5965
let partition_table = if let Some(table) = partition_table {
6066
table
@@ -162,7 +168,7 @@ impl ChipType for Esp32c3 {
162168
Box::new(
163169
once(Ok(RomSegment {
164170
addr: BOOT_ADDR,
165-
data: Cow::Borrowed(bootloader),
171+
data: Cow::Owned(bootloader),
166172
}))
167173
.chain(once(Ok(RomSegment {
168174
addr: PARTITION_ADDR,

espflash/src/chip/esp8266.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl ChipType for Esp8266 {
3434

3535
fn get_flash_segments<'a>(
3636
image: &'a FirmwareImage,
37+
_bootloader: Option<Vec<u8>>,
3738
_partition_table: Option<PartitionTable>,
3839
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a> {
3940
// irom goes into a separate plain bin
@@ -144,7 +145,7 @@ fn test_esp8266_rom() {
144145

145146
let image = FirmwareImage::from_data(&input_bytes).unwrap();
146147

147-
let segments = Esp8266::get_flash_segments(&image, None)
148+
let segments = Esp8266::get_flash_segments(&image, None, None)
148149
.collect::<Result<Vec<_>, Error>>()
149150
.unwrap();
150151

espflash/src/chip/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub trait ChipType {
2929
/// Get the firmware segments for writing an image to flash
3030
fn get_flash_segments<'a>(
3131
image: &'a FirmwareImage,
32+
bootloader: Option<Vec<u8>>,
3233
partition_table: Option<PartitionTable>,
3334
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a>;
3435

@@ -113,12 +114,13 @@ impl Chip {
113114
pub fn get_flash_segments<'a>(
114115
&self,
115116
image: &'a FirmwareImage,
117+
bootloader: Option<Vec<u8>>,
116118
partition_table: Option<PartitionTable>,
117119
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a> {
118120
match self {
119-
Chip::Esp32 => Esp32::get_flash_segments(image, partition_table),
120-
Chip::Esp32c3 => Esp32c3::get_flash_segments(image, partition_table),
121-
Chip::Esp8266 => Esp8266::get_flash_segments(image, None),
121+
Chip::Esp32 => Esp32::get_flash_segments(image, bootloader, partition_table),
122+
Chip::Esp32c3 => Esp32c3::get_flash_segments(image, bootloader, partition_table),
123+
Chip::Esp8266 => Esp8266::get_flash_segments(image, None, None),
122124
}
123125
}
124126

espflash/src/flasher.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,18 @@ impl Flasher {
554554
pub fn load_elf_to_flash(
555555
&mut self,
556556
elf_data: &[u8],
557+
bootloader: Option<Vec<u8>>,
557558
partition_table: Option<PartitionTable>,
558559
) -> Result<(), Error> {
559560
self.enable_flash(self.spi_params)?;
561+
560562
let mut image = FirmwareImage::from_data(elf_data).map_err(|_| Error::InvalidElf)?;
561563
image.flash_size = self.flash_size();
562564

563-
for segment in self.chip.get_flash_segments(&image, partition_table) {
565+
for segment in self
566+
.chip
567+
.get_flash_segments(&image, bootloader, partition_table)
568+
{
564569
let segment = segment?;
565570
let addr = segment.addr;
566571
let block_count = (segment.data.len() + FLASH_WRITE_SIZE - 1) / FLASH_WRITE_SIZE;

espflash/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn main() -> Result<()> {
6262
if ram {
6363
flasher.load_elf_to_ram(&input_bytes)?;
6464
} else {
65-
flasher.load_elf_to_flash(&input_bytes, None)?;
65+
flasher.load_elf_to_flash(&input_bytes, None, None)?;
6666
}
6767

6868
Ok(())

0 commit comments

Comments
 (0)