From e36d5a8a1579bf706aafca181dc87bd5cecec7b3 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 4 Sep 2020 23:16:06 +0200 Subject: [PATCH] esp32 work --- Cargo.lock | 72 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/chip/esp32.rs | 23 +++++++++----- src/chip/esp8266.rs | 3 +- src/elf.rs | 10 ++---- tests/data/esp32.bin | Bin 28624 -> 145504 bytes 6 files changed, 93 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19bb04c..056748d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,15 @@ dependencies = [ "syn", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "bytemuck" version = "1.4.0" @@ -49,6 +58,18 @@ dependencies = [ "syn", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + [[package]] name = "ctor" version = "0.1.15" @@ -65,6 +86,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "espflash" version = "0.1.0" @@ -75,11 +105,22 @@ dependencies = [ "pico-args", "pretty_assertions", "serial", + "sha2", "slip-codec", "thiserror", "xmas-elf", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "ioctl-rs" version = "0.1.6" @@ -101,6 +142,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb63bb1e282e0b6aba0addb1f0e87cb5181ea68142b2dfd21ba108f8e8088a64" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "output_vt100" version = "0.1.2" @@ -188,6 +235,19 @@ dependencies = [ "serial-core", ] +[[package]] +name = "sha2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +dependencies = [ + "block-buffer", + "cfg-if", + "cpuid-bool", + "digest", + "opaque-debug", +] + [[package]] name = "slip-codec" version = "0.1.2" @@ -234,12 +294,24 @@ dependencies = [ "syn", ] +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index aaa1156..8921722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ thiserror = "1.0.20" pico-args = "0.3.4" main_error = "0.1.1" binread = "1.1.1" +sha2 = "0.9.1" [dev-dependencies] pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/src/chip/esp32.rs b/src/chip/esp32.rs index 0644e64..43319ce 100644 --- a/src/chip/esp32.rs +++ b/src/chip/esp32.rs @@ -3,6 +3,7 @@ use crate::elf::{update_checksum, CodeSegment, FirmwareImage, RomSegment, ESP_CH use crate::Error; use bytemuck::__core::iter::once; use bytemuck::{bytes_of, Pod, Zeroable}; +use sha2::{Digest, Sha256}; use std::borrow::Cow; use std::io::Write; @@ -67,6 +68,8 @@ impl ChipType for ESP32 { let mut checksum = ESP_CHECKSUM_MAGIC; + let _ = image.segments().collect::>(); + let flash_segments = image.rom_segments(Chip::Esp32); let mut ram_segments = image.ram_segments(Chip::Esp32); @@ -78,6 +81,7 @@ impl ChipType for ESP32 { if pad_len > 0 { if pad_len > SEG_HEADER_LEN { if let Some(ram_segment) = ram_segments.next() { + println!("ram addr: {:#x}, len: {:#x}", segment.addr, segment.size); checksum = save_segment(&mut data, &ram_segment, checksum)?; segment_count += 1; continue; @@ -101,7 +105,6 @@ impl ChipType for ESP32 { } for segment in ram_segments { - println!("addr: {:#x}, len: {:#x}", segment.addr, segment.size); checksum = save_segment(&mut data, &segment, checksum)?; segment_count += 1; } @@ -114,7 +117,11 @@ impl ChipType for ESP32 { // since we added some dummy segments, we need to patch the segment count data[1] = segment_count as u8; - dbg!(segment_count); + + let mut hasher = Sha256::new(); + hasher.update(&data); + let hash = hasher.finalize(); + data.write(&hash)?; Ok(RomSegment { addr: 0x1000, @@ -129,8 +136,12 @@ impl ChipType for ESP32 { const IROM_ALIGN: u32 = 65536; const SEG_HEADER_LEN: u32 = 8; +/// Actual alignment (in data bytes) required for a segment header: positioned so that +/// after we write the next 8 byte header, file_offs % IROM_ALIGN == segment.addr % IROM_ALIGN +/// +/// (this is because the segment's vaddr may not be IROM_ALIGNed, more likely is aligned +/// IROM_ALIGN+0x18 to account for the binary file header fn get_segment_padding(offset: usize, segment: &CodeSegment) -> u32 { - println!("addr: {:#x}", segment.addr); let align_past = (segment.addr % IROM_ALIGN) - SEG_HEADER_LEN; let pad_len = (IROM_ALIGN - ((offset as u32) % IROM_ALIGN)) + align_past; if pad_len == 0 || pad_len == IROM_ALIGN { @@ -183,14 +194,12 @@ fn save_segment(data: &mut Vec, segment: &CodeSegment, checksum: u8) -> Resu #[test] fn test_esp32_rom() { use bytemuck::from_bytes; - + use pretty_assertions::assert_eq; use std::fs::read; let input_bytes = read("./tests/data/esp32").unwrap(); let expected_bin = read("./tests/data/esp32.bin").unwrap(); - dbg!(from_bytes::(&expected_bin[0..8])); - let image = FirmwareImage::from_data(&input_bytes).unwrap(); let segments = ESP32::get_flash_segments(&image) @@ -200,5 +209,5 @@ fn test_esp32_rom() { assert_eq!(1, segments.len()); let buff = segments[0].data.as_ref(); assert_eq!(expected_bin.len(), buff.len()); - assert_eq!(expected_bin.as_slice(), buff); + assert_eq!(&expected_bin.as_slice(), &buff); } diff --git a/src/chip/esp8266.rs b/src/chip/esp8266.rs index e96533e..1b009ed 100644 --- a/src/chip/esp8266.rs +++ b/src/chip/esp8266.rs @@ -88,9 +88,8 @@ impl ChipType for ESP8266 { #[test] fn test_esp8266_rom() { - use std::fs::read; - use pretty_assertions::assert_eq; + use std::fs::read; let input_bytes = read("./tests/data/esp8266").unwrap(); let expected_bin = read("./tests/data/esp8266.bin").unwrap(); diff --git a/src/elf.rs b/src/elf.rs index f5e3381..e7deb8a 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -65,14 +65,10 @@ impl<'a> FirmwareImage<'a> { pub fn segments(&'a self) -> impl Iterator> + 'a { self.elf .program_iter() - .filter(|section| { - section.file_size() > 0 - && section.get_type() == Ok(Type::Load) - && section.flags().is_execute() - }) + .filter(|header| header.file_size() > 0 && header.get_type() == Ok(Type::Load)) .flat_map(move |header| { - let addr = header.physical_addr() as u32; - let size = header.mem_size() as u32; + let addr = header.virtual_addr() as u32; + let size = header.file_size() as u32; let data = match header.get_data(&self.elf) { Ok(SegmentData::Undefined(data)) => data, _ => return None, diff --git a/tests/data/esp32.bin b/tests/data/esp32.bin index c921c27a71ee76b989855befbec2388b81903652..32676970b6728b9812fdd5b35564f4252dd2dd26 100644 GIT binary patch delta 8306 zcmeI%dr(x@9l-Is?(z~YyRf_;vamcB77$jDM5Xr-QAwGINhO$KCzwEJ0##HJGa2he zikaZy6+bgE*A@&Gzui4fWw)VnZ%0=qD(T=BIne0L*KXh#I{yy;k>;v)UHmf+4SgiLj42ooA5``SpFIRkCpv7qN!n&;rmGVx?bVoz)9+RNmK2S4`GsP9$1?0Jh7`Y~rj}gtpn?$+(x%T&w1kAR7 zFQCl4DOz}g0`E2HR#g=V$Up&BVl5uTW;9|4zKaeR_%VKpUc7^I_&rAO58Q+)Toqx6 zMH=#O4_0G69zlJ$s*7zDp2L20;xJyvN%Z4=e1Iz$#Tcd#VpT;HQjmjU2vp)>Y(X=2 zVIK~n8?WI_yoEE?JXKtv@DZ-!25uvefw~oOa3U8aHr3k{e95feBB_l~#S_?$-5A9f z4qytM2#Hk1D&k>8QC>%U9mzO}6zU#D4vHc06#Dt@ef)y5i}*CL4VCyHf>ZV|g@^cJ z85SWFQFxyEE}U9W`a*BuF6-A9^yu!gaki~5?CHJh4(JPfeebpdU-j$nl-K_XKesi{ zKHkvM`sB8)D;&8F{klO!OA$tm?I-3*;r+6=_1;)Qv+T&60`V|*tn$lT);#;&M8 zMStQHT7JHw^rp{j>@-m^_Quv4r=xA=v2ZlK={u;~65k%MQ zdTDRCV+);g>*=IjCf^4WgNeT+$_FH}ogTa0Zp{)}8Tn!)f!u43s}8XC%)6&ma@!T9?SKW zx%{|(=YRa=f9&Uf^y%*d{yyOE17DFourtx2FvGlu(Ga&``TB`RFWL#zFHwzGN>T$` zsc%<|vn6i5_lzY>jBC^0GZsY-jCgpEq>RgmJNzKL(44v*sryupq% z6HgF#6PvlDtqh}Ipgg)v6_d-N8RL=+XR6{du|7o=CzvwnE8}%Jp^}rSzS-ErI9k5% zHSw9Anwo0kQ^0hm6-O}y2h$ok)tZ^aL@52_JqbL#VWR`Ar-i%%$~3=YraVX3-Y|UB z)sf3t%p`~#wGI4UZA@c|i0P_H>7rbZc1%yFD6K?WzAR4%O)#iG$~7G&jx%#PQ^4tm z4_OS<$B6~$s?oHnSdY)4&mqb!w6-)=w6NiK;d5~|`7GmO<705OiJY0_5(g0HpbvV4cV%gd rC)HB9rnd2|k)Qvu%#{6kz}||rmw)x!qK(frei-({3+}52Ub*>i*VHJ! delta 4385 zcmd_teNYtV9l-H@4v^&~9&n%_5DxDSP+s(o5Qw6?7&M?p$pjN)QbB|fqp?>dQ0L1yb7SjFUh3 zt2^`I_q^@1&pyxIKFg&+x$B~cy%u1Sa^ht5hV&nYC^hTa8)lK^sWIzH1a*;^jpjmG z^(Pu+PP{WiR(oP)RU=^{U8w=DSmFFN(rOw85rv^p7*B%%V=IZ6)DnF+aq-)mV$1gAMsB_<09iH zEFu#yc7iQRD~=d;tAndX_eJAsDK-9;HTJ)Cj1J&!5`3xZhV7l7=jPMiLx36 zD^l?|@~|AwqYSU08gJqkco)ryvPV5k;uCy^E?mGBe2ZZO&Xm;%#3KcnScpOtqXaMG zRn(#m`)~lQ@Zto%L@zGm2JXV&mM*Jio2<@&19LGSORy5Fu^yZ8W1H+fHC>$b^JLp) z^*tQI5gbK|gQ4Lh>4n5DVj;1Hcmc(vcMz}O2ly5xlzo7g@hWQZA%>|7B;GE9BM zqYe=c=4>B{cc|EgMOcPnoT9u3_a~KSvM=zE{ymd=cMrKZ*Y-^A^geU|o=INchYjHW zef@35`p08&_4*2T)y5xgnP*M2@_MaF(3KG4js#uvCWv49^^qvCiWtjs>vuJZi55mh zomC`Ss;MxxTTU6T@cz*%f=uR)2^(+MY*{-uQ|z5Hv9LTY7d5Lxg!y&bbuH5&@B9CnCVAq^Bvqu@gdE;~fUlL1Miw;4t>Dw2rCK2%n*VdEBS?gDGYmU3%~ zB&n27rTjD<7#|i@V?EPet4k72+jvKA8Ya=;Dh*`fKJrtDM#GCq;zyR76y#A5j5v_@ zu1^-L0?d6AHrs|mSv#2~vJzU-bj3=uPNFgG^T;%kCMjJ{)3w-iQD~FWbtRvIWni$< zc>Z~k#$A#3?noC4{5<{hW%W69kHy!CH|ELe*0H!@p{$0ZWGtRn*(?=V%^361g!FjX z_lTRn>uBOh*8kC|QTB13tnS6T_$vc3^7n|L#B8jghFhk@^pOV$M0$Jl( zdcsog)Rk;1YN!n-lGk*na7OQ3`tR?=q5}3U*y%~DcM0cI_qwX8imh8Rwr-Q`E?s-m zB^Eo}uFB>$% zcVx66%%bnP=pXZ9k5~P zP5h{Lp_i`*JKJ+EKladUzAA{eObNGcOsUB4++EMDgptojGi9~YbftAVdD?zK{06rW6s;?sWd6)Y0iMNLxUn6( z@hQ4-07o!@o4AMBF|0iDVZt+5i%ked6(X=5b!fo*IE2G!kI_9!2Z^uIhbtJwU6^L@ z4nid2k%Y&v2t}Ado3+FZcpba&K7Nf)(TxGzh7Uop3o7My!WBAfaL@R$(1p z!SG_f2wAA5EZ_?8f0G&=!xNXplR|kI(`h_qt8txob`9sW@)R7!NqmidT*W^yf}lih z2#+EK*&hBZ#!9?|N;KjiTJbx4hOf{IHwN%e_|N3+3_CKAgFGz5b0|Y4Uc(OTMk79e zoxvX>dRq8Xna{&S`~*jF499T-9rzrb_yVVK24~TObNDm*aS7E7tQH?}w{5sg*)`mP zj{7jNbp;~G#`=elcm!rlLpvwM6Rohpfn>}=D$+3rPGlkr*_ej~Q1K*|U?&4vPOK-s zL~LbA+jxg>CY{3TF!w1BYe*)Jmwg+t*(Iy>Y^3I7NqS+r_iPx^=aZy_xBvEx@6zo6 zW3x3j+QzZi$9vUy69^99$jC@7M;LotG2TKuB(^qV4<6mv!lfqief+=D!$4X*bW}t^ z3M4KxH<@W<5OJ9dj53wHv9a~Ri1n=7AhC*Qe?&-C#vX@q_&xg+85Z%JAQx% zwUhW*F8`*@Wl7M1KwhIgL_c@7toi&+S)RMIcoJvp$`Foc$!ZZ-K8TJKeij^=9A=Ip zdMm|MY^K-06N5S2kFv$kYoC*!1Xr!XZR)CV2lp_H5eV9u;Ew=Iap`eN`4U-`$ryW8 zD6s{rnTB?k?)@sjLQQk