Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,163 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)

project(esp-miner)

# Post-build step: automatically create merged binary (esp-miner-merged.bin)
add_custom_target(
merge_bin_target
COMMAND ${CMAKE_COMMAND} -E echo "Creating merged binary: esp-miner-merged.bin"
COMMAND ${PYTHON} -m esptool --chip esp32s3 merge_bin
--flash_mode dio --flash_size 16MB --flash_freq 80m
0x0 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
-o esp-miner-merged.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "Creating merged binary: esp-miner-merged.bin"
)

# Config file to merge. Set with: idf.py -DMERGE_CONFIG_CVS=config-401.cvs
# Default: config-401.cvs (standard Bitaxe config)
set(MERGE_CONFIG_CVS "config-401.cvs" CACHE STRING "Config CSV file to include in merged binary (e.g. config-401.cvs)")

# Generate config.bin from the selected .cvs file using ESP-IDF's nvs_partition_gen
set(CONFIG_BIN_OUTPUT "${PROJECT_DIR}/config.bin")
add_custom_command(
OUTPUT ${CONFIG_BIN_OUTPUT}
COMMAND ${PYTHON} "$ENV{IDF_PATH}/components/nvs_flash/tools/nvs_partition_gen.py"
generate ${MERGE_CONFIG_CVS} ${CONFIG_BIN_OUTPUT} --size 0x1000
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS ${PROJECT_DIR}/${MERGE_CONFIG_CVS}
COMMENT "Generating config.bin from ${MERGE_CONFIG_CVS}"
)

# Merged binary with config.bin included (for custom boards)
add_custom_target(
merge_bin_target_with_config
COMMAND ${CMAKE_COMMAND} -E echo "Creating merged binary with config from: ${MERGE_CONFIG_CVS}"
COMMAND ${PYTHON} -m esptool --chip esp32s3 merge_bin
--flash_mode dio --flash_size 16MB --flash_freq 80m
0x0 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x9000 ${CONFIG_BIN_OUTPUT}
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
-o esp-miner-merged-with-config.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app ${CONFIG_BIN_OUTPUT}
COMMENT "Creating merged binary with config from ${MERGE_CONFIG_CVS}"
)

# Update-only binary (firmware + OTA in hex format, for OTA updates)
add_custom_target(
merge_bin_target_update
COMMAND ${CMAKE_COMMAND} -E echo "Creating update binary: esp-miner-update.bin"
COMMAND ${PYTHON} -m esptool --chip esp32s3 merge_bin
--flash_mode dio --flash_size 16MB --flash_freq 80m --format hex
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
-o esp-miner-update.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "Creating update binary: esp-miner-update.bin"
)

# Flash targets with selective erase ranges
# NOTE: These write individual components instead of a merged binary so esptool
# only erases the specific partition areas being updated, not the entire chip.

# Full chip erase + flash (factory reset, first installation)
# Erases everything: bootloader, partitions, config, firmware, OTA
add_custom_target(
flash_factory
COMMAND ${PYTHON} -m esptool --chip esp32s3 erase_flash
COMMAND ${PYTHON} -m esptool --chip esp32s3 write_flash
0x0 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "Factory flash: full erase + write all partitions"
)

# Update flash: writes bootloader + firmware + OTA, keeps NVS config intact
# Each write_flash only erases its own partition range.
add_custom_target(
flash_update_keep_config
COMMAND ${PYTHON} -m esptool --chip esp32s3 write_flash
0x0 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "Update flash: writes firmware only, preserves NVS config at 0x9000"
)

# Flash with config: includes config.bin, keeps other partitions (OTA, www)
add_custom_target(
flash_with_config
COMMAND ${PYTHON} -m esptool --chip esp32s3 write_flash
0x0 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x9000 ${CONFIG_BIN_OUTPUT}
0x10000 build/esp-miner.bin
0xf10000 build/ota_data_initial.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app ${CONFIG_BIN_OUTPUT}
COMMENT "Flash with config: writes all including config from ${MERGE_CONFIG_CVS}, preserves OTA/www"
)

# Erase only NVS config partition (0x9000 - 0x10000, 24KB) then write config
add_custom_target(
flash_config_only
COMMAND ${PYTHON} -m esptool --chip esp32s3 erase_region 0x9000 0x7000
COMMAND ${PYTHON} -m esptool --chip esp32s3 write_flash 0x9000 ${CONFIG_BIN_OUTPUT}
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS ${CONFIG_BIN_OUTPUT}
COMMENT "Config only: erase + write NVS config from ${MERGE_CONFIG_CVS}"
)

# Erase factory app only (0x10000 - 0x500000) then write firmware
add_custom_target(
flash_app_only
COMMAND ${PYTHON} -m esptool --chip esp32s3 erase_region 0x10000 0x400000
COMMAND ${PYTHON} -m esptool --chip esp32s3 write_flash 0x10000 build/esp-miner.bin
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "App only: erase + write firmware, keeps bootloader, partition, config intact"
)

# Generate merged binaries for all config-*.bin files (like merge_bin_all.sh -c)
file(GLOB CONFIG_BINS "${PROJECT_DIR}/config-*.bin")
if(CONFIG_BINS)
add_custom_target(
merge_bin_target_all_configs
COMMAND ${CMAKE_COMMAND} -E echo "Creating merged binaries for all configs..."
COMMAND ${PYTHON} -c "
import glob, subprocess, sys
configs = glob.glob('config-*.bin')
for cfg in sorted(configs):
out = cfg.replace('.bin', '-merged.bin')
cmd = [
sys.executable, '-m', 'esptool', '--chip', 'esp32s3', 'merge_bin',
'--flash_mode', 'dio', '--flash_size', '16MB', '--flash_freq', '80m',
'0x0', 'build/bootloader/bootloader.bin',
'0x8000', 'build/partition_table/partition-table.bin',
'0x9000', cfg,
'0x10000', 'build/esp-miner.bin',
'0xf10000', 'build/ota_data_initial.bin',
'-o', out
]
print(f'Creating {out}')
subprocess.run(cmd, check=True)
print('All merged binaries created.')
"
WORKING_DIRECTORY ${PROJECT_DIR}
DEPENDS app
COMMENT "Creating merged binaries for all config-*.bin files"
)
endif()

103 changes: 101 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@ Available API endpoints:
* `/api/system/scoreboard` Get top 20 highest difficulty shares
* `/api/system/wifi/scan` Scan for available Wi-Fi networks
* `/api/system/logs` Download system logs
* `/api/system/autotune` Get Autotune settings information

**POST**

* `/api/system/restart` Restart the system
* `/api/system/identify` Identify the device
* `/api/system/OTA` Update system firmware
* `/api/system/OTAWWW` Update AxeOS
* `/api/system/autotune` Update Autotune settings

**PATCH**

Expand Down Expand Up @@ -314,10 +316,107 @@ git submodule update --init --recursive

At the root of the repository, run:
```
idf.py build && ./merge_bin.sh ./esp-miner-merged.bin
idf.py build
```

This automatically builds the Axe-OS frontend, embeds it into the firmware, and produces `build/esp-miner.bin`.

To create a merged flashable binary, use one of these methods:

**CMake targets (recommended):**

```
# Default merged binary (bootloader + partition + firmware + OTA)
# Use this when you plan to flash config separately with bitaxetool
idf.py merge_bin_target
```

```
# Merged binary including a config file baked in
# Generates config.bin from the specified .cvs file automatically.
# Choose your hardware config with -DMERGE_CONFIG_CVS:
idf.py -DMERGE_CONFIG_CVS=config-401.cvs merge_bin_target_with_config
idf.py -DMERGE_CONFIG_CVS=config-402.cvs merge_bin_target_with_config
idf.py -DMERGE_CONFIG_CVS=config-custom.cvs merge_bin_target_with_config
# Default is config-401.cvs if not specified.
```

```
# Update-only binary (firmware + OTA in hex format)
# For OTA updates via /api/system/OTA endpoint — does not include bootloader or partitions
idf.py merge_bin_target_update
```

```
# Generate merged binaries for all config-*.bin files in project root
# Produces one merged binary per config file (e.g. config-401-merged.bin)
idf.py merge_bin_target_all_configs
```

Output files:
- `esp-miner-merged.bin` — no config baked in
- `esp-miner-merged-with-config.bin` — includes config.bin (generated from selected .cvs) at 0x9000
- `esp-miner-update.bin` — firmware + OTA only, hex format (for OTA updates)
- `config-XXX-merged.bin` — one per `config-XXX.bin` found (factory-style images)

**Flash the merged binaries:**

⚠️ **Warning:** Flashing a merged binary at 0x0 with esptool will erase everything up to the end of the binary (~0xf12000), wiping your NVS config and OTA partitions.

```
# Flash merged binary directly (erases everything up to 0xf12000)
esptool.py --chip esp32s3 write_flash 0x0 esp-miner-merged.bin

# Or use bitaxetool with a config file (overwrites the baked-in config)
bitaxetool --config ./config-401.cvs --firmware ./esp-miner-merged.bin
```

**Flash targets (recommended — preserves config where possible):**

These targets write individual components so each partition only erases its own area.

```
# Factory flash: full erase + write all partitions (first installation)
idf.py flash_factory
```

```
# Update flash: writes bootloader + firmware + OTA, preserves NVS config at 0x9000
idf.py flash_update_keep_config
```

```
# Flash with config: includes config from selected .cvs, preserves OTA/www partitions
idf.py -DMERGE_CONFIG_CVS=config-401.cvs flash_with_config
```

```
# Config only: erase + write NVS config from selected .cvs
idf.py -DMERGE_CONFIG_CVS=config-401.cvs flash_config_only
```

```
# App only: erase + write firmware, keeps bootloader, partition, config intact
idf.py flash_app_only
```

**Erase range summary:**

| Target | Erases | Preserves |
|--------|--------|-----------|
| `flash_factory` | Everything | Nothing |
| `flash_update_keep_config` | Bootloader, firmware, OTA | NVS config |
| `flash_with_config` | Bootloader, firmware, OTA | OTA/www partitions |
| `flash_config_only` | NVS config (0x9000-0x10000) | Everything else |
| `flash_app_only` | Firmware (0x10000-0x500000) | Bootloader, config, OTA |

**Shell script (legacy):**
```
./merge_bin.sh ./esp-miner-merged.bin
./merge_bin.sh -c ./esp-miner-merged.bin # with config.bin
```

Note: the merge_bin.sh script is a custom script that merges the bootloader, partition table, and the application binary into a single file.
Note: the merge_bin tools combine the bootloader, partition table, application binary, and OTA data into a single file that can be flashed to the device at 0x0.

Note: if using VSCode, you may have to configure the settings.json file to match your esp hardware version. For example, if your bitaxe has something other than an esp32-s3, you will need to change the version in the `.vscode/settings.json` file.

Expand Down
Loading