3.9 KiB
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\rightarrowBoots Slot 1 (Stock CrealityOS: kernelp5, rootfsp7).ota:kernel2\rightarrowBoots Slot 2 (Custom / OpenKE: kernelp6, rootfsp8).
How Stock OTA Updater Flashes to Slot 2
When you run a USB update from the stock Creality touchscreen:
- Stock firmware queries which slot is currently running (
local_get_kernel_dev_path). - Since the printer is running on Slot 1 (
ota:kernel), the updater targets the inactive slot:- Flashes
xImagetokernel2(mmcblk0p6). - Flashes
rootfs.squashfstorootfs2(mmcblk0p8). - Flashes
zero.bintortos2(mmcblk0p4).
- Flashes
- Calls
local_set_next_boot_device, which writesota:kernel2intommcblk0p1. - Reboots into OpenKE.
Note
Stock firmware in Slot 1 (
mmcblk0p5andmmcblk0p7) 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)
echo -n "ota:kernel" > /dev/mmcblk0p1
sync
reboot
From Stock CrealityOS (if toggling forward again)
. /etc/ota_bin/ota_utils.sh
. /etc/ota_bin/ota_local_method.sh
local_set_next_boot_device
reboot