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

> Discover how AtomCam firmware update safely writes flash memory using MTD operations. Learn about init scripts, flash_eraseall, and flashcp for verified NAND programming.

- Repository: [Mitsuru Nakada/atomcam_tools](https://github.com/mnakada/atomcam_tools)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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.

```sh
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`.

```sh
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.

```sh
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.

```sh
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.