PackBEAM Format
Relevant source files
The following files were used as context for generating this wiki page:
The PackBEAM format (often referred to as AVM) is a binary-encoded aggregation format used by AtomVM to package multiple files into a single, contiguous blob. It serves as the primary distribution and execution format for AtomVM applications, allowing the runtime to locate entry points and load bytecode or static assets from a read-only code base. This format is designed for efficiency on embedded devices with constrained resources, such as the ESP32 and STM32, where files are typically flashed to specific media locations.
PackBEAM files are used to aggregate BEAM bytecode files and "normal" data files (such as configuration or assets) into a single file. The runtime treats this data as read-only. Tooling such as the packbeam command-line utility, atomvm_rebar3_plugin, and ExAtomVM facilitate the creation, inspection, and manipulation of these archives.
Sources: doc/src/packbeam-format.md:10-25, tools/packbeam/README.md:10-15, doc/src/getting-started-guide.md:72-80
Overall File Structure
A PackBEAM file consists of a fixed header followed by a sequence of zero or more encoded files. Each encoded file is prefixed with its own header. The sequence is explicitly terminated by a special end file header. All binary integer values are 32-bit big-endian (network order), and headers and file contents are aligned on 4-byte boundaries using null padding.
High-Level Layout
The following diagram illustrates the sequential structure of an AVM archive:
The diagram shows the linear arrangement of headers and data blocks within a single .avm file.
Sources: doc/src/packbeam-format.md:27-41, tools/packbeam/packbeam.c:206-220
PackBEAM Header
Every AtomVM packbeam file begins with a mandatory 24-byte header sequence. This sequence contains an ASCII shebang followed by null bytes to ensure alignment.
| Offset | Length | Value (Hex) | Description / ASCII |
|---|---|---|---|
| 0 | 22 | 0x23 21 2F 75 73 72 2F 62 69 6E 2F 65 6E 76 20 41 74 6F 6D 56 4D 0A | #!/usr/bin/env AtomVM\n |
| 22 | 2 | 0x00 00 | Null padding |
Sources: doc/src/packbeam-format.md:43-52, tools/packbeam/packbeam.c:186-200
File Encodings
Each embedded element in the archive consists of a metadata header and the actual file content.
File Header Structure
The file header is variable-length because of the null-terminated module name, but it follows a strict field order.
| Field | Type | Description |
|---|---|---|
size | 32-bit uint | Total size of the encoded file (including content and padding). |
flags | 32-bit uint | Bitmask for file properties (0x02: BEAM file, 0x01: Entrypoint). |
reserved | 32-bit uint | Unused, currently set to 0. |
module_name | String | Null-terminated string. Padded with 0x00 to 4-byte boundary. |
Flags Detail:
0x01: Indicates the file contains astart/0function suitable for application entry.0x02: Indicates the file is a BEAM module.0x03: Masked value for a BEAM file that is also the entrypoint.
Sources: doc/src/packbeam-format.md:58-85, tools/packbeam/packbeam.c:369-381
Content Handling logic
The content within an AVM file is processed differently depending on whether it is a BEAM file or a standard data file.
BEAM Files
BEAM files are stripped of non-essential IFF chunks to save space on flash media. Supported chunks include AtU8, Code, ExpT, LocT, ImpT, LitU, FunT, StrT, and LitT. Notably, literals in the LitT chunk are uncompressed into a LitU format because the AtomVM runtime lacks zlib support for decompression.
Sources: doc/src/packbeam-format.md:92-110, tools/packbeam/packbeam.c:223-289
Normal Files (Static Assets)
Files that are not BEAM modules can be embedded for access via the atomvm:read_priv/2 NIF. These files are typically stored using a path-like module name convention: <app_name>/priv/<path>.
- Example:
mylib/priv/config.json. - These files are prefixed with a 32-bit size field indicating the unpadded content length.
Sources: doc/src/packbeam-format.md:118-140, doc/src/atomvm-tooling.md:195-205
End File Marker
The end of the packbeam sequence is marked by a specific "end" header. This header has a size of 0 and the module name "end".
Example Byte Sequence:
00000000 (Size)
00000000 (Flags)
00000000 (Reserved)
656E6400 ("end\0")
Sources: doc/src/packbeam-format.md:142-149, tools/packbeam/packbeam.c:218
Tooling and Manipulation
The packbeam tool implements the logic for creating, listing, and extracting AVM contents.
Creation Workflow
When creating a runnable AVM, the tool ensures the first BEAM file with a start/0 function is marked with the appropriate flags.
The sequence illustrates the transformation of individual BEAM files into a packed AVM archive.
Sources: tools/packbeam/packbeam.c:165-218, tools/packbeam/README.md:25-45
Key Management Features
| Feature | Command Option | Description |
|---|---|---|
| Pruning | --prune | Removes BEAM files not transitively referenced by the start module. |
| Start Module | --start | Explicitly sets which module serves as the start/0 entrypoint. |
| Listing | list | Displays modules; the entrypoint is marked with an asterisk (*). |
| Extraction | extract | Recovers individual files from an AVM archive. |
Sources: doc/src/atomvm-tooling.md:208-250, tools/packbeam/packbeam.c:303-315
Significance in AtomVM Architecture
The PackBEAM format is critical for AtomVM's boot process. On platforms like ESP32, the runtime scans the data partition (typically starting at 0x210000 or 0x250000) for the AVM header. It then iterates through the embedded file headers to locate the first BEAM module with the entrypoint flag (0x01). This allows AtomVM to execute complex applications consisting of dozens of modules by loading them from a single, contiguous memory-mapped region.
Sources: doc/src/packbeam-format.md:74-80, doc/src/getting-started-guide.md:80-95, doc/src/atomvm-internals.md:120-130