Files
DarKE/docs/A_B_PARTITION_MODEL.md
T

87 lines
3.9 KiB
Markdown

# Hardware Partition Layout & Dual-Slot A/B Boot Model
This document details the eMMC physical partition layout, the hardware A/B slot mechanics, and the persistent storage architecture used by Creality X2000 devices (Ender-3 V3 KE and Nebula Pad).
---
## 1. Physical Partition Table
The onboard eMMC is partitioned with a standard GPT partition table:
| Partition | Label | Fixed Capacity | Mount / Role | Active Slot 1 (Stock) | Active Slot 2 (OpenKE) |
| :--- | :--- | :--- | :--- | :--- | :--- |
| `/dev/mmcblk0p1` | `ota` | **1 MiB** | Boot marker storage | Stores `ota:kernel` or `ota:kernel2` | Shared |
| `/dev/mmcblk0p2` | `sn_mac` | **1 MiB** | Factory serial & MAC addresses | Read-only identity | Shared |
| `/dev/mmcblk0p3` | `rtos` | **4 MiB** | Aux RTOS firmware (Slot 1) | Active | Inactive |
| `/dev/mmcblk0p4` | `rtos2` | **4 MiB** | Aux RTOS firmware (Slot 2) | Inactive | Active |
| `/dev/mmcblk0p5` | `kernel` | **8 MiB** | Linux uImage (Slot 1) | Active | Inactive |
| `/dev/mmcblk0p6` | `kernel2` | **8 MiB** | Linux uImage (Slot 2) | Inactive | Active |
| `/dev/mmcblk0p7` | `rootfs` | **500 MiB** | SquashFS rootfs (Slot 1) | Active | Inactive |
| `/dev/mmcblk0p8` | `rootfs2` | **500 MiB** | SquashFS rootfs (Slot 2) | Inactive | Active |
| `/dev/mmcblk0p9` | `rootfs_data` | **300 MiB** | Ext4 writable overlay | `/overlay` | `/overlay` |
| `/dev/mmcblk0p10` | `userdata` | **~6.1 GiB** | Ext4 persistent storage | Mounted at `/usr/data` | Mounted at `/usr/data` |
---
## 2. Boot Selection via the OTA Marker
The bootloader (U-Boot) reads the 1 MiB `ota` partition (`/dev/mmcblk0p1`) on power-up to decide which kernel and rootfs to mount. The partition contains a simple ASCII string:
* `ota:kernel` $\rightarrow$ Boots **Slot 1** (Stock CrealityOS: kernel `p5`, rootfs `p7`).
* `ota:kernel2` $\rightarrow$ Boots **Slot 2** (Custom / OpenKE: kernel `p6`, rootfs `p8`).
### How Stock OTA Updater Flashes to Slot 2
When you run a USB update from the stock Creality touchscreen:
1. Stock firmware queries which slot is currently running (`local_get_kernel_dev_path`).
2. Since the printer is running on Slot 1 (`ota:kernel`), the updater targets the **inactive** slot:
- Flashes `xImage` to `kernel2` (`mmcblk0p6`).
- Flashes `rootfs.squashfs` to `rootfs2` (`mmcblk0p8`).
- Flashes `zero.bin` to `rtos2` (`mmcblk0p4`).
3. Calls `local_set_next_boot_device`, which writes `ota:kernel2` into `mmcblk0p1`.
4. Reboots into OpenKE.
> [!NOTE]
> Stock firmware in Slot 1 (`mmcblk0p5` and `mmcblk0p7`) is **never overwritten** by this process.
---
## 3. Persistent Data Isolation (`/usr/data`)
`/dev/mmcblk0p10` is the single shared ~6.1 GiB persistent partition mounted at `/usr/data`. Both Slot 1 and Slot 2 share this partition, but they use strict directory separation:
```
/usr/data/
├── creality/ # Stock CrealityOS files (gcode, logs, userdata, factory data)
│ ├── userdata/
│ └── printer_data/
└── openke/ # OpenKE isolated runtime
├── apps/ # Mutable checkouts (klipper, moonraker, mainsail)
├── envs/ # Python virtual environments
├── system/ # Boot logs, activation state, machine configs
└── printer_data/ # Klipper config (printer.cfg), macros, Moonraker DB
```
Because OpenKE namespaces all its data under `/usr/data/openke/`, flashing OpenKE does not erase or corrupt stock print history, WiFi credentials, or factory calibration files.
---
## 4. Reverting to Stock Firmware
If you ever wish to return to stock CrealityOS, you do not need to reflash. You simply toggle the boot marker back to Slot 1:
### From OpenKE Shell (SSH)
```bash
echo -n "ota:kernel" > /dev/mmcblk0p1
sync
reboot
```
### From Stock CrealityOS (if toggling forward again)
```bash
. /etc/ota_bin/ota_utils.sh
. /etc/ota_bin/ota_local_method.sh
local_set_next_boot_device
reboot
```