Skip to content

Commit 28d4906

Browse files
committed
Merge pull request #2254 from bettio/grow-erlang-boot-partition
ESP32: Increase Erlang boot.avm partition to 512KB Users flashing applications to ESP32 devices with Erlang-only images must update their flashing offset from `0x210000` to `0x250000`. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 378eb53 + 3e8707d commit 28d4906

8 files changed

Lines changed: 42 additions & 32 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- `erlang:float_to_binary/2` and `erlang:float_to_list/2` now accept `{decimals, 0..253}` and `{scientific, 0..249}`
2929
- `erlang:binary_to_float/1` and `erlang:list_to_float/1` now use locale-independent parsing and
3030
strict format validation
31+
- ESP32: the `boot.avm` partition for Erlang-only images has been increased from 256KB to 512KB,
32+
matching the Elixir partition layout. The `main.avm` offset is now `0x250000` for all images
33+
(previously `0x210000` for Erlang-only).
3134

3235
### Fixed
3336
- Fixed `erlang:cancel_timer/1` return type spec and documentation to match OTP

UPDATING.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ handling code.
2222
- ESP32 builds with Elixir support may be configured without making changes to git-tracked files
2323
using `idf.py -DATOMVM_ELIXIR_SUPPORT=on set-target ${CHIP}` instead of copying
2424
partitions-elixir.csv to partitions.csv. This configures the build to use partitions-elixir.csv for
25-
the partition table. The `main.avm` offset in the partition table will determine which flavor of
26-
esp32boot libraries to include for the `idf.py flash` task and the image assembled by
27-
`build/mkimage.sh`.
25+
the partition table. The `ATOMVM_ELIXIR_SUPPORT` option will determine which flavor of esp32boot
26+
libraries to include for the `idf.py flash` task and the image assembled by `build/mkimage.sh`.
2827
- ESP32 release builds may be configured with `idf.py -DATOMVM_RELEASE=on set-target ${CHIP}`
2928
rather than copy sdkconfig.release-defaults.in to sdkconfig.defaults.in (which still requires a
3029
`reconfigure` or `set-target` to be run to pick up the changes), this may also be combined with the
3130
`ATOMVM_ELIXIR_SUPPORT` option. For example, an Elixir-supported release build is configured using:
3231
`idf.py -DATOMVM_ELIXIR_SUPPORT=on -DATOMVM_RELEASE=on set-target ${CHIP}`
3332
- `json_encoder` module has been removed, use new (and standard) `json` module. New module uses
3433
standard Erlang/OTP API, that takes maps instead of proplists.
34+
- ESP32: the `boot.avm` partition has been increased from 256KB to 512KB for Erlang-only images.
35+
The `main.avm` offset is now `0x250000` for all images (previously `0x210000` for Erlang-only).
36+
Update flashing offsets in your tooling, build scripts, and `mix.exs` or `rebar.config` if you
37+
were using the `0x210000` offset.
3538

3639
## v0.6.4 -> v0.6.5
3740

doc/src/atomvm-tooling.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ $ rebar3 atomvm esp32_flash --port /dev/ttyUSB0 --baud 921600
119119
...
120120
===> esptool.py --chip auto --port /dev/ttyUSB0 --baud 921600 --before default_reset
121121
--after hard_reset write_flash -u --flash_mode keep --flash_freq keep --flash_size detect
122-
0x210000 atomvm_examples/erlang/hello_world/_build/default/lib/hello_world.avm
122+
0x250000 atomvm_examples/erlang/hello_world/_build/default/lib/hello_world.avm
123123
```
124124

125125
```{tip}
@@ -147,14 +147,14 @@ You can now use a serial console program such as [minicom](https://en.wikipedia.
147147
###########################################################
148148

149149
I (852) AtomVM: Starting AtomVM revision 0.6.0-alpha.1
150-
I (862) sys: Loaded BEAM partition boot.avm at address 0x1d0000 (size=262144 bytes)
150+
I (862) sys: Loaded BEAM partition boot.avm at address 0x1d0000 (size=524288 bytes)
151151
I (882) network_driver: Initialized network interface
152152
I (882) network_driver: Created default event loop
153153
I (902) AtomVM: Found startup beam esp32init.beam
154154
I (922) AtomVM: Starting esp32init.beam...
155155
---
156156
AtomVM init.
157-
I (932) sys: Loaded BEAM partition main.avm at address 0x210000 (size=1048576
157+
I (932) sys: Loaded BEAM partition main.avm at address 0x250000 (size=1048576
158158
bytes)
159159
Starting application...
160160
Hello World

doc/src/build-instructions.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,9 @@ The flash layout is roughly as follows (not to scale):
505505
| (factory) | |
506506
| | |
507507
+-----------------+ |
508-
| boot.avm | 256-512KB v
509-
+-----------------+ ------------- 0x210000 for Erlang only images or
510-
| | ^ 0x250000 for images with Elixir modules
508+
| boot.avm | 512KB v
509+
+-----------------+ ------------- 0x250000
510+
| | ^
511511
| | |
512512
| main.avm | 1MB+ | Erlang/Elixir
513513
| | | Application
@@ -524,11 +524,13 @@ The following table summarizes the partitions created on the ESP32 when deployin
524524
| NVS | 0x9000 | 24kB | Space for non-volatile storage. |
525525
| PHY_INIT | 0xF000 | 4kB | Initialization data for physical layer radio signal data. |
526526
| AtomVM virtual machine | 0x10000 | 1.75mB | The AtomVM virtual machine (compiled from C code). |
527-
| boot.avm | 0x1D0000 | 256k | The AtomVM BEAM library, compiled from Erlang and Elixir files in the AtomVM source tree. |
528-
| main.avm | `0x210000` \| `0x250000` | 1mB | The user application. This is where users flash their compiled Erlang/Elixir code |
527+
| boot.avm | 0x1D0000 | 512k | The AtomVM BEAM library, compiled from Erlang and Elixir files in the AtomVM source tree. |
528+
| main.avm | 0x250000 | 1mB | The user application. This is where users flash their compiled Erlang/Elixir code |
529529

530-
```{warning}
531-
There is an important difference in the partition layout between the minimal images and those build with Elixir support. To accommodate the extra Elixir modules the boot.avm partition on these images is larger, and the application offset is moved accordingly. When working with Elixir supported images it is important to always use the offset `0x250000` whether using `mix` or the `atomvm_rebar3_plugin` (possibly to test an Erlang app), otherwise part of the boot.avm partition (specifically the area where many Elixir modules are located) will be overwritten with the application, but the VM will still be trying to load from the later `0x250000` offset. This should be kept in mind reading the rest of build instructions, and [AtomVM Tooling](./atomvm-tooling.md) sections of the docs that cover the use of rebar3, for these sections an Erlang only image is assumed.
530+
```{note}
531+
Since v0.7.0-alpha.1, both Erlang-only and Elixir-supported images use the same partition layout
532+
and the same `main.avm` offset of `0x250000`. Previous versions used `0x210000` for Erlang-only
533+
images.
532534
```
533535

534536
### The `boot.avm` and `main.avm` partitions
@@ -537,7 +539,7 @@ The `boot.avm` and `main.avm` partitions are intended to store Erlang/Elixir lib
537539

538540
The `boot.avm` partition is intended for core Erlang/Elixir libraries that are built as part of the AtomVM build. The release image of AtomVM (see below) includes both the AtomVM virtual machine and the `boot.avm` partition, which includes the BEAM files from the `estdlib` and `eavmlib` libraries.
539541

540-
In contrast, the `main.avm` partition is intended for user applications. Currently, the `main.avm` partition starts at address `0x210000` for thin images or `0x250000` for images with Elixir modules, and it is to that location to which application developers should flash their application AVM files.
542+
In contrast, the `main.avm` partition is intended for user applications. Currently, the `main.avm` partition starts at address `0x250000`, and it is to that location to which application developers should flash their application AVM files.
541543

542544
The AtomVM search path for BEAM modules starts in the `main.avm` partition and falls back to `boot.avm`. Users should not have a need to override any functionality in the `boot.avm` partition, but if necessary, a BEAM module of the same name in the `main.avm` partition will be loaded instead of the version in the `boot.avm` partition.
543545

@@ -580,7 +582,7 @@ Wrote AtomVM Virtual Machine at offset 0x10000 (65536)
580582
Wrote AtomVM Core BEAM Library at offset 0x1D0000 (1114112)
581583
```
582584

583-
Users can then use the `esptool.py` directly to flash the entire image to the ESP32 device, and then flash their applications to the `main.app` partition at address `0x210000`, (or `0x250000` for Elixir images)
585+
Users can then use the `esptool.py` directly to flash the entire image to the ESP32 device, and then flash their applications to the `main.app` partition at address `0x250000`.
584586

585587
But first, it is a good idea to erase the flash, e.g.,
586588

doc/src/getting-started-guide.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ The ES32 AtomVM virtual machine is an IDF application that runs on the ESP32 pla
5151

5252
The AtomVM virtual machine is implemented in C, and the AtomVM binary image contains the binary object code compiled from C source files, as well as the ESP boot loader and partition map, which tells the ESP32 how the flash module is laid out.
5353

54-
AtomVM developers will typically write their applications in Erlang or Elixir. These source files are compiled into BEAM bytecode, which is then assembled into AtomVM "packbeam" (`.avm`) files. This packbeam file is flashed onto the ESP32 device, starting at the data partition address `0x210000`. When AtomVM starts, it will look in this partition for the first occurrence of a BEAM module that exports a `start/0` function. Once that module is located, execution of the BEAM bytecode will commence at that point.
54+
AtomVM developers will typically write their applications in Erlang or Elixir. These source files are compiled into BEAM bytecode, which is then assembled into AtomVM "packbeam" (`.avm`) files. This packbeam file is flashed onto the ESP32 device, starting at the data partition address `0x250000`. When AtomVM starts, it will look in this partition for the first occurrence of a BEAM module that exports a `start/0` function. Once that module is located, execution of the BEAM bytecode will commence at that point.
5555

5656
The following diagram provides a simplified overview of the layout of the AtomVM virtual machine and Erlang/Elixir applications on the ESP32 flash module.
5757

@@ -66,8 +66,8 @@ The following diagram provides a simplified overview of the layout of the AtomVM
6666
| Virtual | |
6767
| Machine | |
6868
| | v
69-
+---------------+ ----------- 0x210000 for thin images or
70-
| | ^ 0x250000 for images with Elixir modules
69+
+---------------+ ----------- 0x250000
70+
| | ^
7171
| | |
7272
| data | | Erlang/Elixir
7373
| partition | | Application
@@ -187,7 +187,7 @@ Instructions for building AtomVM from source are covered in the AtomVM [Build In
187187

188188
### Deploying an AtomVM application for ESP32
189189

190-
An AtomVM application is a collection of BEAM files, which have been compiled using the Erlang or Elixir compiler. These BEAM files are assembled into an AtomVM "packbeam" (`.avm`) file, which in turn is flashed to the `main` data partition on the ESP32 flash module, starting at address `0x210000` if you are using a thin image, or `0x250000` for images with Elixir support.
190+
An AtomVM application is a collection of BEAM files, which have been compiled using the Erlang or Elixir compiler. These BEAM files are assembled into an AtomVM "packbeam" (`.avm`) file, which in turn is flashed to the `main` data partition on the ESP32 flash module, starting at address `0x250000`.
191191

192192
When the AtomVM virtual machine starts, it will search for the first module that contains an exported `start/0` function in this partition, and it will begin execution of the BEAM bytecode at that function.
193193

src/platforms/esp32/GetBootAVM.cmake

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
2020

2121
partition_table_get_partition_info(app_offset "--partition-name main.avm" "offset")
2222
set(AVM_APP_OFFSET "${app_offset}")
23-
# 0x210000 = standard Erlang only partition layout (partitions.csv)
24-
if ("${app_offset}" STREQUAL "0x210000")
25-
set(BOOT_LIBS "esp32boot.avm")
26-
set(ATOMVM_FLAVOR "")
27-
# 0x250000 = Elixir-supported partition layout (partitions-elixir.csv)
28-
elseif ("${app_offset}" STREQUAL "0x250000")
29-
set(BOOT_LIBS "elixir_esp32boot.avm")
30-
set(ATOMVM_FLAVOR "-elixir")
23+
# Both partitions.csv and partitions-elixir.csv use 0x250000 for main.avm.
24+
# Use ATOMVM_ELIXIR_SUPPORT to select the boot library flavor.
25+
if ("${app_offset}" STREQUAL "0x250000")
26+
if (ATOMVM_ELIXIR_SUPPORT)
27+
set(BOOT_LIBS "elixir_esp32boot.avm")
28+
set(ATOMVM_FLAVOR "-elixir")
29+
else()
30+
set(BOOT_LIBS "esp32boot.avm")
31+
set(ATOMVM_FLAVOR "")
32+
endif()
3133
else()
3234
set(BOOT_LIBS "NONE")
3335
set(ATOMVM_FLAVOR "")

src/platforms/esp32/partitions.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
nvs, data, nvs, 0x9000, 0x6000,
99
phy_init, data, phy, 0xf000, 0x1000,
1010
factory, app, factory, 0x10000, 0x1C0000,
11-
boot.avm, data, phy, 0x1D0000, 0x40000,
12-
main.avm, data, phy, 0x210000, 0x100000
11+
boot.avm, data, phy, 0x1D0000, 0x80000,
12+
main.avm, data, phy, 0x250000, 0x100000

tools/test/smoke-test/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ To run an example program, `cd` into the appropriate example directory, and buil
186186
===> Verifying dependencies...
187187
===> Analyzing applications...
188188
===> Compiling hello_world
189-
===> esptool.py --chip auto --port /dev/tty.usbserial-0164A0E0 --baud 921600 --before default_reset --after hard_reset write_flash -u --flash_mode keep --flash_freq keep --flash_size detect 0x210000 .../atomvm_examples/erlang/hello_world/_build/default/lib/hello_world.avm
189+
===> esptool.py --chip auto --port /dev/tty.usbserial-0164A0E0 --baud 921600 --before default_reset --after hard_reset write_flash -u --flash_mode keep --flash_freq keep --flash_size detect 0x250000 .../atomvm_examples/erlang/hello_world/_build/default/lib/hello_world.avm
190190

191191
esptool.py v3.3.4-dev
192192
Serial port /dev/tty.usbserial-0164A0E0
@@ -236,14 +236,14 @@ For example:
236236
###########################################################
237237

238238
I (780) AtomVM: Starting AtomVM revision 0.6.0-alpha.1
239-
I (790) sys: Loaded BEAM partition boot.avm at address 0x1d0000 (size=262144 bytes)
239+
I (790) sys: Loaded BEAM partition boot.avm at address 0x1d0000 (size=524288 bytes)
240240
I (810) network_driver: Initialized network interface
241241
I (810) network_driver: Created default event loop
242242
I (830) AtomVM: Found startup beam esp32init.beam
243243
I (830) AtomVM: Starting esp32init.beam...
244244
---
245245
AtomVM init.
246-
I (840) sys: Loaded BEAM partition main.avm at address 0x210000 (size=1048576 bytes)
246+
I (840) sys: Loaded BEAM partition main.avm at address 0x250000 (size=1048576 bytes)
247247
Starting application...
248248
Hello World
249249
AtomVM finished with return value: ok

0 commit comments

Comments
 (0)