├── .gitignore ├── Cargo.toml ├── .github └── workflows │ └── rust.yml ├── README.md ├── Cargo.lock └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "espsegs" 3 | version = "0.1.0" 4 | edition = "2021" 5 | rust-version = "1.65" 6 | readme = "README.md" 7 | repository = "https://github.com/bjoernQ/espsegs" 8 | 9 | [dependencies] 10 | object = "0.31.1" 11 | clap = { version = "4.3.0", features = ["derive"] } 12 | 13 | [features] 14 | default = [] 15 | expert = [] 16 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Continuous Integration 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | paths-ignore: 9 | - "**/README.md" 10 | pull_request: 11 | paths-ignore: 12 | - "**/README.md" 13 | 14 | env: 15 | CARGO_TERM_COLOR: always 16 | 17 | jobs: 18 | cargo-checks: 19 | name: Cargo checks | ${{ matrix.os }} | ${{ matrix.action.command }} 20 | runs-on: ${{ matrix.os }} 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | os: [ubuntu-latest, windows-latest, macos-latest] 25 | action: 26 | - command: check 27 | - command: fmt 28 | args: --all -- --check 29 | - command: clippy 30 | args: --all-targets --all-features --workspace -- -D warnings 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v4 34 | - name: Setup Rust toolchain 35 | uses: dtolnay/rust-toolchain@stable 36 | - name: Enable caching 37 | uses: Swatinem/rust-cache@v2 38 | - name: Cargo command 39 | run: cargo ${{ matrix.action.command }} ${{ matrix.action.args }} 40 | 41 | msrv: 42 | name: MSRV check 43 | runs-on: ubuntu-latest 44 | steps: 45 | - name: Checkout repository 46 | uses: actions/checkout@v4 47 | - name: Setup Rust toolchain 48 | uses: dtolnay/rust-toolchain@stable 49 | with: 50 | toolchain: 1.65.0 51 | - name: Enable caching 52 | uses: Swatinem/rust-cache@v2 53 | - name: Cargo check 54 | run: cargo check 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # espsegs 2 | 3 | ## Installation 4 | 5 | ``` 6 | cargo install --git https://github.com/bjoernQ/espsegs 7 | ``` 8 | 9 | ## Usage 10 | 11 | ``` 12 | Usage: espsegs [OPTIONS] --chip 13 | 14 | Arguments: 15 | 16 | 17 | Options: 18 | -c, --chip 19 | -s, --flash-size [possible values: 256KB, 512KB, 1MB, 2MB, 4MB, 8MB, 16MB, 32MB, 64MB, 128MB, 256MB] 20 | -w, --width [default: 120] 21 | -h, --help Print help (see more with '--help') 22 | -V, --version Print version 23 | 24 | ``` 25 | 26 | ### Example 27 | 28 | ``` 29 | ❯ espsegs \projects\esp\esp-wifi\target\riscv32imc-unknown-none-elf\release\examples\embassy_dhcp --chip esp32c3 30 | 31 | .text_dummy 3c000000 458784 DROM [█████████████ ] 32 | .rodata 3c070020 53060 DROM [ █ ] 33 | .rodata.wifi 3c07cf64 21756 DROM [ ▏ ] 34 | 35 | .rwdata_dumm 3fc80000 16948 DRAM [██████ ] 36 | .data 3fc84238 4652 DRAM [ █ ] 37 | .bss 3fc85468 121544 DRAM [ ████████████████████████████████████████████ ] 38 | .data.wifi 3fca2f30 360 DRAM [ ▏ ] 39 | 40 | .trap 40380000 3188 IRAM [ ▏ ] 41 | .rwtext 40380c74 2080 IRAM [ ▏ ] 42 | .rwtext.wifi 40381494 11680 IRAM [ ███ ] 43 | 44 | .text_init 42000020 244 IROM [▏ ] 45 | .text 42000114 402684 IROM [███████████ ] 46 | ``` 47 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "anstream" 13 | version = "0.3.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" 16 | dependencies = [ 17 | "anstyle", 18 | "anstyle-parse", 19 | "anstyle-query", 20 | "anstyle-wincon", 21 | "colorchoice", 22 | "is-terminal", 23 | "utf8parse", 24 | ] 25 | 26 | [[package]] 27 | name = "anstyle" 28 | version = "1.0.1" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" 31 | 32 | [[package]] 33 | name = "anstyle-parse" 34 | version = "0.2.1" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" 37 | dependencies = [ 38 | "utf8parse", 39 | ] 40 | 41 | [[package]] 42 | name = "anstyle-query" 43 | version = "1.0.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 46 | dependencies = [ 47 | "windows-sys", 48 | ] 49 | 50 | [[package]] 51 | name = "anstyle-wincon" 52 | version = "1.0.1" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" 55 | dependencies = [ 56 | "anstyle", 57 | "windows-sys", 58 | ] 59 | 60 | [[package]] 61 | name = "bitflags" 62 | version = "2.3.3" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" 65 | 66 | [[package]] 67 | name = "byteorder" 68 | version = "1.4.3" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 71 | 72 | [[package]] 73 | name = "cc" 74 | version = "1.0.79" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 77 | 78 | [[package]] 79 | name = "cfg-if" 80 | version = "1.0.0" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 83 | 84 | [[package]] 85 | name = "clap" 86 | version = "4.3.15" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "8f644d0dac522c8b05ddc39aaaccc5b136d5dc4ff216610c5641e3be5becf56c" 89 | dependencies = [ 90 | "clap_builder", 91 | "clap_derive", 92 | "once_cell", 93 | ] 94 | 95 | [[package]] 96 | name = "clap_builder" 97 | version = "4.3.15" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "af410122b9778e024f9e0fb35682cc09cc3f85cad5e8d3ba8f47a9702df6e73d" 100 | dependencies = [ 101 | "anstream", 102 | "anstyle", 103 | "clap_lex", 104 | "strsim", 105 | ] 106 | 107 | [[package]] 108 | name = "clap_derive" 109 | version = "4.3.12" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" 112 | dependencies = [ 113 | "heck", 114 | "proc-macro2", 115 | "quote", 116 | "syn", 117 | ] 118 | 119 | [[package]] 120 | name = "clap_lex" 121 | version = "0.5.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" 124 | 125 | [[package]] 126 | name = "colorchoice" 127 | version = "1.0.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 130 | 131 | [[package]] 132 | name = "crc32fast" 133 | version = "1.3.2" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 136 | dependencies = [ 137 | "cfg-if", 138 | ] 139 | 140 | [[package]] 141 | name = "errno" 142 | version = "0.3.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" 145 | dependencies = [ 146 | "errno-dragonfly", 147 | "libc", 148 | "windows-sys", 149 | ] 150 | 151 | [[package]] 152 | name = "errno-dragonfly" 153 | version = "0.1.2" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 156 | dependencies = [ 157 | "cc", 158 | "libc", 159 | ] 160 | 161 | [[package]] 162 | name = "espsegs" 163 | version = "0.1.0" 164 | dependencies = [ 165 | "clap", 166 | "object", 167 | ] 168 | 169 | [[package]] 170 | name = "flate2" 171 | version = "1.0.26" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" 174 | dependencies = [ 175 | "crc32fast", 176 | "miniz_oxide", 177 | ] 178 | 179 | [[package]] 180 | name = "heck" 181 | version = "0.4.1" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 184 | 185 | [[package]] 186 | name = "hermit-abi" 187 | version = "0.3.2" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 190 | 191 | [[package]] 192 | name = "is-terminal" 193 | version = "0.4.9" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" 196 | dependencies = [ 197 | "hermit-abi", 198 | "rustix", 199 | "windows-sys", 200 | ] 201 | 202 | [[package]] 203 | name = "libc" 204 | version = "0.2.147" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 207 | 208 | [[package]] 209 | name = "linux-raw-sys" 210 | version = "0.4.3" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" 213 | 214 | [[package]] 215 | name = "memchr" 216 | version = "2.5.0" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 219 | 220 | [[package]] 221 | name = "miniz_oxide" 222 | version = "0.7.1" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 225 | dependencies = [ 226 | "adler", 227 | ] 228 | 229 | [[package]] 230 | name = "object" 231 | version = "0.31.1" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" 234 | dependencies = [ 235 | "flate2", 236 | "memchr", 237 | "ruzstd", 238 | ] 239 | 240 | [[package]] 241 | name = "once_cell" 242 | version = "1.18.0" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 245 | 246 | [[package]] 247 | name = "proc-macro2" 248 | version = "1.0.66" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 251 | dependencies = [ 252 | "unicode-ident", 253 | ] 254 | 255 | [[package]] 256 | name = "quote" 257 | version = "1.0.31" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" 260 | dependencies = [ 261 | "proc-macro2", 262 | ] 263 | 264 | [[package]] 265 | name = "rustix" 266 | version = "0.38.4" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" 269 | dependencies = [ 270 | "bitflags", 271 | "errno", 272 | "libc", 273 | "linux-raw-sys", 274 | "windows-sys", 275 | ] 276 | 277 | [[package]] 278 | name = "ruzstd" 279 | version = "0.3.1" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" 282 | dependencies = [ 283 | "byteorder", 284 | "thiserror", 285 | "twox-hash", 286 | ] 287 | 288 | [[package]] 289 | name = "static_assertions" 290 | version = "1.1.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 293 | 294 | [[package]] 295 | name = "strsim" 296 | version = "0.10.0" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 299 | 300 | [[package]] 301 | name = "syn" 302 | version = "2.0.26" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" 305 | dependencies = [ 306 | "proc-macro2", 307 | "quote", 308 | "unicode-ident", 309 | ] 310 | 311 | [[package]] 312 | name = "thiserror" 313 | version = "1.0.43" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" 316 | dependencies = [ 317 | "thiserror-impl", 318 | ] 319 | 320 | [[package]] 321 | name = "thiserror-impl" 322 | version = "1.0.43" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" 325 | dependencies = [ 326 | "proc-macro2", 327 | "quote", 328 | "syn", 329 | ] 330 | 331 | [[package]] 332 | name = "twox-hash" 333 | version = "1.6.3" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" 336 | dependencies = [ 337 | "cfg-if", 338 | "static_assertions", 339 | ] 340 | 341 | [[package]] 342 | name = "unicode-ident" 343 | version = "1.0.11" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 346 | 347 | [[package]] 348 | name = "utf8parse" 349 | version = "0.2.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 352 | 353 | [[package]] 354 | name = "windows-sys" 355 | version = "0.48.0" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 358 | dependencies = [ 359 | "windows-targets", 360 | ] 361 | 362 | [[package]] 363 | name = "windows-targets" 364 | version = "0.48.1" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" 367 | dependencies = [ 368 | "windows_aarch64_gnullvm", 369 | "windows_aarch64_msvc", 370 | "windows_i686_gnu", 371 | "windows_i686_msvc", 372 | "windows_x86_64_gnu", 373 | "windows_x86_64_gnullvm", 374 | "windows_x86_64_msvc", 375 | ] 376 | 377 | [[package]] 378 | name = "windows_aarch64_gnullvm" 379 | version = "0.48.0" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 382 | 383 | [[package]] 384 | name = "windows_aarch64_msvc" 385 | version = "0.48.0" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 388 | 389 | [[package]] 390 | name = "windows_i686_gnu" 391 | version = "0.48.0" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 394 | 395 | [[package]] 396 | name = "windows_i686_msvc" 397 | version = "0.48.0" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 400 | 401 | [[package]] 402 | name = "windows_x86_64_gnu" 403 | version = "0.48.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 406 | 407 | [[package]] 408 | name = "windows_x86_64_gnullvm" 409 | version = "0.48.0" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 412 | 413 | [[package]] 414 | name = "windows_x86_64_msvc" 415 | version = "0.48.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 418 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{error::Error, fs, path::PathBuf, process::exit}; 2 | 3 | use clap::{Parser, ValueEnum}; 4 | use object::{Object, ObjectSection}; 5 | 6 | #[derive(Clone, Copy, Debug, ValueEnum)] 7 | #[value(rename_all = "SCREAMING_SNAKE_CASE")] 8 | pub enum FlashSize { 9 | /// 256 KB 10 | _256Kb, 11 | /// 512 KB 12 | _512Kb, 13 | /// 1 MB 14 | _1Mb, 15 | /// 2 MB 16 | _2Mb, 17 | /// 4 MB 18 | _4Mb, 19 | /// 8 MB 20 | _8Mb, 21 | /// 16 MB 22 | _16Mb, 23 | /// 32 MB 24 | _32Mb, 25 | /// 64 MB 26 | _64Mb, 27 | /// 128 MB 28 | _128Mb, 29 | /// 256 MB 30 | _256Mb, 31 | } 32 | 33 | impl FlashSize { 34 | fn bytes(self) -> u64 { 35 | match self { 36 | FlashSize::_256Kb => 256 * 1024, 37 | FlashSize::_512Kb => 512 * 1024, 38 | FlashSize::_1Mb => 1024 * 1024, 39 | FlashSize::_2Mb => 2 * 1024 * 1024, 40 | FlashSize::_4Mb => 4 * 1024 * 1024, 41 | FlashSize::_8Mb => 8 * 1024 * 1024, 42 | FlashSize::_16Mb => 16 * 1024 * 1024, 43 | FlashSize::_32Mb => 32 * 1024 * 1024, 44 | FlashSize::_64Mb => 64 * 1024 * 1024, 45 | FlashSize::_128Mb => 128 * 1024 * 1024, 46 | FlashSize::_256Mb => 256 * 1024 * 1024, 47 | } 48 | } 49 | } 50 | 51 | #[derive(Parser, Debug)] 52 | #[command(author, version, about, long_about = None)] 53 | struct Args { 54 | file: PathBuf, 55 | 56 | #[arg(short, long)] 57 | chip: String, 58 | 59 | #[arg(short = 's', long, value_name = "SIZE", value_enum)] 60 | flash_size: Option, 61 | 62 | #[arg(short = 'w', long, default_value = "120")] 63 | width: usize, 64 | } 65 | 66 | fn normalize(chip_name: &str) -> String { 67 | chip_name.replace('-', "").to_ascii_lowercase() 68 | } 69 | 70 | fn main() -> Result<(), Box> { 71 | let args = Args::parse(); 72 | 73 | let bin_data = fs::read(args.file)?; 74 | let obj_file = object::File::parse(&*bin_data)?; 75 | let sections = obj_file.sections(); 76 | 77 | let mut sections: Vec = sections 78 | .into_iter() 79 | .filter(|section| section.address() != 0 && section.size() != 0) 80 | .collect(); 81 | sections.sort_by(|a, b| a.address().partial_cmp(&b.address()).unwrap()); 82 | 83 | let chip = normalize(&args.chip); 84 | let chip_memory = MEMORY.iter().find(|m| normalize(m.name) == chip); 85 | 86 | let Some(chip_memory) = chip_memory else { 87 | println!("Unknown chip"); 88 | exit(1); 89 | }; 90 | 91 | let mut last_region = usize::MAX; 92 | 93 | // Calculate max section name width for the first column 94 | let mut section_name_max_width = 0; 95 | for section in sections.iter() { 96 | let name = section.name().unwrap(); 97 | if name.len() > section_name_max_width { 98 | section_name_max_width = name.len(); 99 | } 100 | } 101 | 102 | for section in sections { 103 | let region = chip_memory.regions.iter().find(|region| { 104 | region.start <= section.address() 105 | && region.end(args.flash_size) >= (section.address() + section.size()) 106 | }); 107 | 108 | if let Some(region) = ®ion { 109 | if region.id != last_region { 110 | println!(); 111 | last_region = region.id; 112 | } 113 | } 114 | 115 | print!( 116 | "{:width$} {:8x} {:7}", 117 | section.name().unwrap(), 118 | section.address(), 119 | section.size(), 120 | width = section_name_max_width, 121 | ); 122 | 123 | if let Some(region) = ®ion { 124 | print!(" {:8} ", region.name); 125 | print_memory( 126 | region.start, 127 | region.end(args.flash_size), 128 | section.address(), 129 | section.size(), 130 | args.width - section_name_max_width - 26, // 26 = `address` + `size` + spaces + brackets + region name 131 | ); 132 | } 133 | 134 | println!(); 135 | } 136 | 137 | Ok(()) 138 | } 139 | 140 | fn print_memory( 141 | region_start: u64, 142 | region_end: u64, 143 | block_start: u64, 144 | block_size: u64, 145 | width: usize, 146 | ) { 147 | let region_size = region_end - region_start; 148 | let offset = 149 | ((width as f64 / region_size as f64) * (block_start as f64 - region_start as f64)) as usize; 150 | let w = ((width as f64 / region_size as f64) * block_size as f64) as usize; 151 | 152 | let small = w == 0; 153 | let w = w.max(1); 154 | 155 | print!("["); 156 | 157 | for _ in 0..offset { 158 | print!(" "); 159 | } 160 | for _ in 0..w { 161 | if small { 162 | print!("\u{258f}"); 163 | } else { 164 | print!("\u{2588}"); 165 | } 166 | } 167 | for _ in 0..(width - w - offset) { 168 | print!(" "); 169 | } 170 | print!("]"); 171 | } 172 | 173 | pub struct Memory { 174 | name: &'static str, 175 | regions: &'static [MemoryRegion], 176 | } 177 | 178 | pub struct MemoryRegion { 179 | id: usize, 180 | name: &'static str, 181 | start: u64, 182 | length: u64, 183 | } 184 | 185 | impl MemoryRegion { 186 | pub fn end(&self, flash_size: Option) -> u64 { 187 | let length = match self.name.ends_with("ROM") && flash_size.is_some() { 188 | true => flash_size.unwrap().bytes(), 189 | false => self.length, 190 | }; 191 | 192 | self.start + length 193 | } 194 | } 195 | 196 | #[cfg(not(feature = "expert"))] 197 | const MEMORY: &[Memory] = &[ 198 | Memory { 199 | name: "ESP32", 200 | regions: &[ 201 | MemoryRegion { 202 | id: 0, 203 | name: "DRAM", 204 | start: 0x3FFB0000, 205 | length: 176 * 1024, 206 | }, 207 | MemoryRegion { 208 | id: 1, 209 | name: "IRAM", 210 | start: 0x40080000, 211 | length: 128 * 1024, 212 | }, 213 | MemoryRegion { 214 | id: 2, 215 | name: "DROM", 216 | start: 0x3F400000, 217 | length: 4 * 1024 * 1024, 218 | }, 219 | MemoryRegion { 220 | id: 3, 221 | name: "IROM", 222 | start: 0x400D0000, 223 | length: 4 * 1024 * 1024, 224 | }, 225 | ], 226 | }, 227 | Memory { 228 | name: "ESP32-S2", 229 | regions: &[ 230 | MemoryRegion { 231 | id: 0, 232 | name: "DRAM", 233 | start: 0x3FFB0000, 234 | length: 0x40000000 - 0x3FFB0000, 235 | }, 236 | MemoryRegion { 237 | id: 1, 238 | name: "IRAM", 239 | start: 0x40020000, 240 | length: 0x40070000 - 0x40020000, 241 | }, 242 | MemoryRegion { 243 | id: 2, 244 | name: "DROM", 245 | start: 0x3F000000, 246 | length: 0x3FF80000 - 0x3F000000, 247 | }, 248 | MemoryRegion { 249 | id: 3, 250 | name: "IROM", 251 | start: 0x40080000, 252 | length: 0x40800000 - 0x40080000, 253 | }, 254 | ], 255 | }, 256 | Memory { 257 | name: "ESP32-S3", 258 | regions: &[ 259 | MemoryRegion { 260 | id: 0, 261 | name: "DRAM", 262 | start: 0x3FC8_8000, 263 | length: 0x3FCE_FFFF - 0x3FC8_8000, 264 | }, 265 | MemoryRegion { 266 | id: 1, 267 | name: "IRAM", 268 | start: 0x4037_8000, 269 | length: 0x403D_FFFF - 0x4037_8000, 270 | }, 271 | MemoryRegion { 272 | id: 2, 273 | name: "DROM", 274 | start: 0x3C00_0000, 275 | length: 0x3DFF_FFFF - 0x3C00_0000, 276 | }, 277 | MemoryRegion { 278 | id: 3, 279 | name: "IROM", 280 | start: 0x4200_0000, 281 | length: 0x43FF_FFFF - 0x4200_0000, 282 | }, 283 | ], 284 | }, 285 | Memory { 286 | name: "ESP32-C2", 287 | regions: &[ 288 | MemoryRegion { 289 | id: 0, 290 | name: "DRAM", 291 | start: 0x3FCA0000, 292 | length: 0x3FCE0000 - 0x3FCA0000, 293 | }, 294 | MemoryRegion { 295 | id: 1, 296 | name: "IRAM", 297 | start: 0x4037C000, 298 | length: 0x403C0000 - 0x4037C000, 299 | }, 300 | MemoryRegion { 301 | id: 2, 302 | name: "DROM", 303 | start: 0x3C000000, 304 | length: 0x3C400000 - 0x3C000000, 305 | }, 306 | MemoryRegion { 307 | id: 3, 308 | name: "IROM", 309 | start: 0x42000000, 310 | length: 0x42400000 - 0x42000000, 311 | }, 312 | ], 313 | }, 314 | Memory { 315 | name: "ESP32-C3", 316 | regions: &[ 317 | MemoryRegion { 318 | id: 0, 319 | name: "DRAM", 320 | start: 0x3FC80000, 321 | length: 0x50000, 322 | }, 323 | MemoryRegion { 324 | id: 1, 325 | name: "IRAM", 326 | start: 0x4037C000, 327 | length: 400 * 1024, 328 | }, 329 | MemoryRegion { 330 | id: 2, 331 | name: "DROM", 332 | start: 0x3C000000, 333 | length: 0x400000, 334 | }, 335 | MemoryRegion { 336 | id: 3, 337 | name: "IROM", 338 | start: 0x42000000, 339 | length: 0x400000, 340 | }, 341 | ], 342 | }, 343 | Memory { 344 | name: "ESP32-C6", 345 | regions: &[ 346 | MemoryRegion { 347 | id: 0, 348 | name: "RAM", 349 | start: 0x40800000, 350 | length: 0x40880000 - 0x40800000, 351 | }, 352 | MemoryRegion { 353 | id: 1, 354 | name: "ROM", 355 | start: 0x42000000, 356 | length: 0x10000 << 8, 357 | }, 358 | ], 359 | }, 360 | Memory { 361 | name: "ESP32-H2", 362 | regions: &[ 363 | MemoryRegion { 364 | id: 0, 365 | name: "DRAM", 366 | start: 0x40800000, 367 | length: 0x40850000 - 0x40800000, 368 | }, 369 | MemoryRegion { 370 | id: 1, 371 | name: "ROM", 372 | start: 0x42000000, 373 | length: 0x10000 << 8, 374 | }, 375 | ], 376 | }, 377 | ]; 378 | 379 | #[cfg(feature = "expert")] 380 | const MEMORY: &[Memory] = &[ 381 | Memory { 382 | name: "ESP32", 383 | regions: &[ 384 | MemoryRegion { 385 | id: 0, 386 | name: "DROM", 387 | start: 0x3F400000, 388 | length: 4 * 1024 * 1024, 389 | }, 390 | MemoryRegion { 391 | id: 1, 392 | name: "IROM", 393 | start: 0x400D0000, 394 | length: 4 * 1024 * 1024, 395 | }, 396 | MemoryRegion { 397 | id: 2, 398 | name: "DRTC_FAST", 399 | start: 0x3FF8_0000, 400 | length: 0x3FF8_1FFF - 0x3FF8_0000, 401 | }, 402 | MemoryRegion { 403 | id: 3, 404 | name: "DRAM2", 405 | start: 0x3FFA_E000, 406 | length: 0x3FFD_FFFF - 0x3FFA_E000, 407 | }, 408 | MemoryRegion { 409 | id: 4, 410 | name: "DRAM1", 411 | start: 0x3FFE_0000, 412 | length: 0x3FFF_FFFF - 0x3FFE_0000, 413 | }, 414 | MemoryRegion { 415 | id: 5, 416 | name: "Cache", 417 | start: 0x4007_0000, 418 | length: 0x4007_FFFF - 0x4007_0000, 419 | }, 420 | MemoryRegion { 421 | id: 6, 422 | name: "IRAM0", 423 | start: 0x4008_0000, 424 | length: 0x4009_FFFF - 0x4008_0000, 425 | }, 426 | MemoryRegion { 427 | id: 7, 428 | name: "IRAM1", 429 | start: 0x400A_0000, 430 | length: 0x400A_FFFF - 0x400A_0000, 431 | }, 432 | MemoryRegion { 433 | id: 8, 434 | name: "IRAM1*", 435 | start: 0x400B_8000, 436 | length: 0x400B_FFFF - 0x400B_8000, 437 | }, 438 | MemoryRegion { 439 | id: 9, 440 | name: "IRTC_FAST", 441 | start: 0x400C_0000, 442 | length: 0x400C_1FFF - 0x400C_0000, 443 | }, 444 | MemoryRegion { 445 | id: 10, 446 | name: "RTC_SLOW", 447 | start: 0x5000_0000, 448 | length: 0x5000_1FFF - 0x5000_0000, 449 | }, 450 | ], 451 | }, 452 | Memory { 453 | name: "ESP32-S2", 454 | regions: &[ 455 | MemoryRegion { 456 | id: 0, 457 | name: "DROM", 458 | start: 0x3F000000, 459 | length: 0x3FF80000 - 0x3F000000, 460 | }, 461 | MemoryRegion { 462 | id: 1, 463 | name: "IROM", 464 | start: 0x40080000, 465 | length: 0x40800000 - 0x40080000, 466 | }, 467 | MemoryRegion { 468 | id: 2, 469 | name: "DRTC_FAST", 470 | start: 0x3FF9_E000, 471 | length: 0x3FF9_FFFF - 0x3FF9_E000, 472 | }, 473 | MemoryRegion { 474 | id: 3, 475 | name: "DRAM0", 476 | start: 0x3FFB_0000, 477 | length: 0x3FFB_7FFF - 0x3FFB_0000, 478 | }, 479 | MemoryRegion { 480 | id: 4, 481 | name: "DRAM1", 482 | start: 0x3FFB_8000, 483 | length: 0x3FFF_FFFF - 0x3FFB_8000, 484 | }, 485 | MemoryRegion { 486 | id: 5, 487 | name: "IRAM0", 488 | start: 0x4002_0000, 489 | length: 0x4002_7FFF - 0x4002_0000, 490 | }, 491 | MemoryRegion { 492 | id: 6, 493 | name: "IRAM1", 494 | start: 0x4002_8000, 495 | length: 0x4006_FFFF - 0x4002_8000, 496 | }, 497 | MemoryRegion { 498 | id: 7, 499 | name: "IRTC_FAST", 500 | start: 0x4007_0000, 501 | length: 0x4007_1FFF - 0x4007_0000, 502 | }, 503 | MemoryRegion { 504 | id: 8, 505 | name: "RTC_SLOW", 506 | start: 0x5000_0000, 507 | length: 0x5000_1FFF - 0x5000_0000, 508 | }, 509 | ], 510 | }, 511 | Memory { 512 | name: "ESP32-S3", 513 | regions: &[ 514 | MemoryRegion { 515 | id: 0, 516 | name: "DROM", 517 | start: 0x3C00_0000, 518 | length: 0x3DFF_FFFF - 0x3C00_0000, 519 | }, 520 | MemoryRegion { 521 | id: 1, 522 | name: "IROM", 523 | start: 0x4200_0000, 524 | length: 0x43FF_FFFF - 0x4200_0000, 525 | }, 526 | MemoryRegion { 527 | id: 2, 528 | name: "DRAM1", 529 | start: 0x3FC8_8000, 530 | length: 0x3FCE_FFFF - 0x3FC8_8000, 531 | }, 532 | MemoryRegion { 533 | id: 3, 534 | name: "DRAM2", 535 | start: 0x3FCF_0000, 536 | length: 0x3FCF_FFFF - 0x3FCF_0000, 537 | }, 538 | MemoryRegion { 539 | id: 4, 540 | name: "IRAM1", 541 | start: 0x4037_0000, 542 | length: 0x4037_7FFF - 0x4037_0000, 543 | }, 544 | MemoryRegion { 545 | id: 5, 546 | name: "IRAM2", 547 | start: 0x4037_8000, 548 | length: 0x403D_FFFF - 0x4037_8000, 549 | }, 550 | MemoryRegion { 551 | id: 6, 552 | name: "RTC_SLOW", 553 | start: 0x5000_0000, 554 | length: 0x5000_1FFF - 0x5000_0000, 555 | }, 556 | MemoryRegion { 557 | id: 7, 558 | name: "RTC_FAST", 559 | start: 0x600F_E000, 560 | length: 0x600F_FFFF - 0x600F_E000, 561 | }, 562 | ], 563 | }, 564 | Memory { 565 | name: "ESP32-C2", 566 | regions: &[ 567 | MemoryRegion { 568 | id: 0, 569 | name: "DROM", 570 | start: 0x3C000000, 571 | length: 0x3C400000 - 0x3C000000, 572 | }, 573 | MemoryRegion { 574 | id: 1, 575 | name: "IROM", 576 | start: 0x42000000, 577 | length: 0x42400000 - 0x42000000, 578 | }, 579 | MemoryRegion { 580 | id: 2, 581 | name: "DRAM1", 582 | start: 0x3FCA_0000, 583 | length: 0x3FCD_FFFF - 0x3FCA_0000, 584 | }, 585 | MemoryRegion { 586 | id: 3, 587 | name: "IRAM0", 588 | start: 0x4037_C000, 589 | length: 0x4037_FFFF - 0x4037_C000, 590 | }, 591 | MemoryRegion { 592 | id: 4, 593 | name: "IRAM1", 594 | start: 0x4038_0000, 595 | length: 0x403B_FFFF - 0x4038_0000, 596 | }, 597 | ], 598 | }, 599 | Memory { 600 | name: "ESP32-C3", 601 | regions: &[ 602 | MemoryRegion { 603 | id: 0, 604 | name: "DROM", 605 | start: 0x3C000000, 606 | length: 0x400000, 607 | }, 608 | MemoryRegion { 609 | id: 1, 610 | name: "IROM", 611 | start: 0x42000000, 612 | length: 0x400000, 613 | }, 614 | MemoryRegion { 615 | id: 2, 616 | name: "DRAM1", 617 | start: 0x3FC8_0000, 618 | length: 0x3FCD_FFFF - 0x3FC8_0000, 619 | }, 620 | MemoryRegion { 621 | id: 3, 622 | name: "IRAM0", 623 | start: 0x4037_C000, 624 | length: 0x4037_FFFF - 0x4037_C000, 625 | }, 626 | MemoryRegion { 627 | id: 4, 628 | name: "IRAM1", 629 | start: 0x4038_0000, 630 | length: 0x403D_FFFF - 0x4038_0000, 631 | }, 632 | MemoryRegion { 633 | id: 4, 634 | name: "RTCFAST", 635 | start: 0x5000_0000, 636 | length: 0x5000_1FFF - 0x5000_0000, 637 | }, 638 | ], 639 | }, 640 | Memory { 641 | name: "ESP32-C6", 642 | regions: &[ 643 | MemoryRegion { 644 | id: 0, 645 | name: "RAM", 646 | start: 0x40800000, 647 | length: 0x40880000 - 0x40800000, 648 | }, 649 | MemoryRegion { 650 | id: 1, 651 | name: "ROM", 652 | start: 0x42000000, 653 | length: 0x10000 << 8, 654 | }, 655 | MemoryRegion { 656 | id: 2, 657 | name: "LPRAM", 658 | start: 0x5000_0000, 659 | length: 0x5000_3FFF - 0x5000_0000, 660 | }, 661 | ], 662 | }, 663 | Memory { 664 | name: "ESP32-H2", 665 | regions: &[ 666 | MemoryRegion { 667 | id: 0, 668 | name: "DRAM", 669 | start: 0x40800000, 670 | length: 0x40850000 - 0x40800000, 671 | }, 672 | MemoryRegion { 673 | id: 1, 674 | name: "ROM", 675 | start: 0x42000000, 676 | length: 0x10000 << 8, 677 | }, 678 | MemoryRegion { 679 | id: 2, 680 | name: "LPRAM", 681 | start: 0x5000_0000, 682 | length: 0x5000_0FFF - 0x5000_0000, 683 | }, 684 | ], 685 | }, 686 | ]; 687 | --------------------------------------------------------------------------------