How AtomCam Firmware Update Handles Flash Memory Writing: A Deep Dive into MTD Operations

The AtomCam firmware update process relies on the init script overlay_rootfs/etc/init.d/S16fwupdate to safely write flash memory by reading upgrade flags from /dev/mtd7, erasing target partitions with flash_eraseall, and programming new images using flashcp to ensure block-aligned, verified NAND operations.

The mnakada/atomcam_tools repository provides open-source tooling for AtomCam devices, including a robust firmware update mechanism designed for embedded Linux MTD (Memory Technology Device) storage. Understanding how this process handles flash memory writing is critical for developers maintaining these cameras or customizing the firmware pipeline.

Overview of the Firmware Update Architecture

The update orchestration starts with the System V init script located at overlay_rootfs/etc/init.d/S16fwupdate. When invoked with the start argument—either during boot or manually—the script manages the entire flash programming workflow by interpreting upgrade metadata, preparing temporary buffers, and executing atomic write operations to NAND partitions.

Reading the Upgrade Configuration from MTD

Before writing, the script determines which components require updating by parsing the FWGRADEUP flag stored in the metadata partition /dev/mtd7. This flag specifies whether to update the kernel, rootfs, application partition, or combinations thereof.

FWGRADEUP=$(awk '/FWGRADEUP=/ { gsub(/^.*=/, ""); print $0; }' /dev/mtd7)

Valid values include kernel+app, kernel+rootfs, kernel, rootfs, or app. The script logs the detected upgrade type to /media/mmc/update.log for debugging purposes.

The Flash Programming Workflow

Step 1: Image Extraction with flash_copy()

The flash_copy() function handles reading the source MTD partition into a temporary file. It dynamically calculates the partition size by parsing /proc/mtd and uses dd to create /tmp/mtd.

flash_copy() {
    size=$(awk '{ if($1 == MTD ":") print ("0x"$2)/1024; }' MTD=${1##*/} /proc/mtd)
    dd if=$1 of=/tmp/mtd bs=1k count=${size}
    if [ $? != 0 ]; then
        return 1
    fi
    ...
}

Step 2: Erasing Target Partitions

Before programming, the script must erase the destination flash blocks to ensure clean NAND cells. It invokes the flash_eraseall utility on the target device (e.g., /dev/mtd1), which is required for reliable NAND flash programming.

flash_eraseall /dev/mtd1

Step 3: Writing the New Image

After erasure, the script uses flashcp to copy the prepared image from /tmp/mtd to the destination partition. This utility ensures the write is verified and block-aligned.

flashcp -v /tmp/mtd $2

Step 4: Cleanup and Verification

Post-write, the script removes the temporary /tmp/mtd file and, for rootfs updates, deletes the old SquashFS image at /media/mmc/atom_root.squashfs. Error checking after each command ([ $? != 0 ] && return) ensures the script exits on failure, preventing partial updates.

MTD Partition Mapping for Different Upgrade Types

The script routes specific source-to-destination copies based on the FWGRADEUP value:

  • kernel+app: Copies kernel (/dev/mtd4 → /dev/mtd1) and application (/dev/mtd5 → /dev/mtd3)
  • kernel+rootfs: Copies kernel (/dev/mtd4 → /dev/mtd1) and rootfs (/dev/mtd5 → /dev/mtd2)
  • kernel: Copies only the kernel partition (/dev/mtd4 → /dev/mtd1)
  • rootfs: Copies only the rootfs partition (/dev/mtd5 → /dev/mtd2)
  • app: Copies only the application partition (/dev/mtd5 → /dev/mtd3)

Supporting Infrastructure

The utilities required (flash_eraseall, flashcp) are enabled in the buildroot configuration at configs/atomcam_defconfig. Additionally, overlay_rootfs/etc/init.d/S61atomcam ensures these tools are properly mounted and available during the update process.

Summary

  • The update process is managed by overlay_rootfs/etc/init.d/S16fwupdate, which reads upgrade directives from /dev/mtd7
  • The flash_copy() function safely extracts partition data to /tmp/mtd before programming
  • All target partitions are erased using flash_eraseall prior to writing to ensure NAND integrity
  • Images are programmed atomically using flashcp, with error checking after each operation
  • The system supports five upgrade types (kernel+app, kernel+rootfs, kernel, rootfs, app) with specific MTD routing between source and destination partitions

Frequently Asked Questions

What happens if the flash write fails during an AtomCam firmware update?

The script checks exit codes after each critical operation ([ $? != 0 ] && return). If flash_eraseall, dd, or flashcp fails, the function returns immediately, halting the update process and preserving the existing firmware on remaining partitions. The exit status propagates to the init system, allowing error detection and logging to /media/mmc/update.log.

Which MTD partitions are used during the AtomCam firmware update process?

The metadata partition /dev/mtd7 stores the FWGRADEUP flag. Source images are read from /dev/mtd4 (kernel) and /dev/mtd5 (rootfs/app), then written to /dev/mtd1 (kernel destination), /dev/mtd2 (rootfs), or /dev/mtd3 (application) depending on the upgrade type specified in the metadata.

Why is flash_eraseall necessary before writing to NAND flash?

NAND flash requires blocks to be erased before programming to reset memory cells to a known state. The flash_eraseall utility clears the target /dev/mtdX device, ensuring the subsequent flashcp operation writes to clean, block-aligned flash areas and preventing data corruption or write failures that could brick the device.

How can I manually trigger a firmware update on AtomCam?

You can invoke the init script directly with sudo /etc/init.d/S16fwupdate start or reboot the device, which executes the script during the boot sequence if the FWGRADEUP flag is present in /dev/mtd7. Ensure the source images are available in the source MTD partitions before triggering the update.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →