|
| 1 | +--- |
| 2 | +title: Flashing SD Card Images |
| 3 | +author: troglobit |
| 4 | +date: 2025-10-27 08:05:00 +0100 |
| 5 | +categories: [howto] |
| 6 | +tags: [beginner] |
| 7 | +--- |
| 8 | + |
| 9 | +This guide covers how to flash an Infix SD card image to a microSD card or |
| 10 | +eMMC module. |
| 11 | + |
| 12 | +### Prerequisites |
| 13 | + |
| 14 | +You will need: |
| 15 | + |
| 16 | +- An SD card reader (USB or built-in) |
| 17 | +- A microSD card or eMMC module (minimum 2 GB recommended) |
| 18 | +- An Infix SD card image from the [latest-boot][1] builds |
| 19 | + |
| 20 | +### Linux |
| 21 | + |
| 22 | +#### Using dd |
| 23 | + |
| 24 | +The traditional `dd` command works on any Linux system without additional |
| 25 | +software: |
| 26 | + |
| 27 | +```console |
| 28 | +$ sudo dd if=infix-aarch64-bpi-r3.img of=/dev/sdX bs=1M status=progress oflag=direct conv=fsync |
| 29 | +``` |
| 30 | + |
| 31 | +Replace `/dev/sdX` with your actual SD card device. You can find the correct |
| 32 | +device using `lsblk` to list all block devices. |
| 33 | + |
| 34 | +> Make sure to unmount any partitions on the SD card before flashing. |
| 35 | +> The device should be `/dev/sdX` (the whole disk), not `/dev/sdX1` |
| 36 | +> (a partition). |
| 37 | +{: .prompt-warning } |
| 38 | + |
| 39 | +#### Using Balena Etcher |
| 40 | + |
| 41 | +[Balena Etcher][2] provides a graphical interface and works on Linux, |
| 42 | +Windows, and macOS. It includes built-in verification. |
| 43 | + |
| 44 | +1. Download and install Etcher from the [official website][2] |
| 45 | +2. Launch Etcher |
| 46 | +3. Click "Flash from file" and select your image file |
| 47 | +4. Click "Select target" and choose your SD card |
| 48 | +5. Click "Flash!" and wait for the process to complete |
| 49 | + |
| 50 | +Etcher will automatically unmount the SD card and verify the written data. |
| 51 | + |
| 52 | +#### Using bmaptool |
| 53 | + |
| 54 | +The `bmaptool` utility is the fastest option for flashing images, as it only |
| 55 | +writes data to blocks that actually contain data, skipping empty regions. |
| 56 | + |
| 57 | +Install bmaptool on Debian-based systems: |
| 58 | + |
| 59 | +```console |
| 60 | +$ sudo apt install bmap-tools |
| 61 | +``` |
| 62 | + |
| 63 | +Since Infix does not yet publish `.bmap` files, you need to generate one first: |
| 64 | + |
| 65 | +```console |
| 66 | +$ bmaptool create infix-aarch64-bpi-r3.img > infix-aarch64-bpi-r3.bmap |
| 67 | +``` |
| 68 | + |
| 69 | +Flash the image: |
| 70 | + |
| 71 | +```console |
| 72 | +$ sudo bmaptool copy infix-aarch64-bpi-r3.img /dev/sdX |
| 73 | +``` |
| 74 | + |
| 75 | +The tool will automatically find and use the `.bmap` file if it exists in the |
| 76 | +same directory as the image. |
| 77 | + |
| 78 | +### Windows |
| 79 | + |
| 80 | +[Balena Etcher][2] is recommended for Windows: |
| 81 | + |
| 82 | +1. Download and install Etcher from the [official website][2] |
| 83 | +2. Insert your SD card |
| 84 | +3. Launch Etcher |
| 85 | +4. Click "Flash from file" and select your image file |
| 86 | +5. Click "Select target" and choose your SD card |
| 87 | +6. Click "Flash!" and wait for the process to complete |
| 88 | + |
| 89 | +An alternative is [Win32 Disk Imager][3], which provides similar |
| 90 | +functionality. |
| 91 | + |
| 92 | +### Verifying the Flash |
| 93 | + |
| 94 | +After flashing, safely eject the SD card from your computer and insert it |
| 95 | +into your target device. The system should boot and be accessible via serial |
| 96 | +console or SSH to the hostname advertised over mDNS. |
| 97 | + |
| 98 | +The default credentials and network configuration are described in the |
| 99 | +[getting started guide][4]. |
| 100 | + |
| 101 | +### Troubleshooting |
| 102 | + |
| 103 | +If the device does not boot: |
| 104 | + |
| 105 | +- Verify you wrote to the correct device (not a partition) |
| 106 | +- Check that the SD card is properly seated in the slot |
| 107 | +- Try a different SD card (some cards are incompatible with certain devices) |
| 108 | +- Verify the image is for the correct board |
| 109 | +- Check the serial console output for error messages |
| 110 | + |
| 111 | +For additional help, consult the [documentation][5] or ask on the |
| 112 | +[community Discord][6]. |
| 113 | + |
| 114 | +### Shell Script Example |
| 115 | + |
| 116 | +For regular flashing tasks on Linux, a shell script with safety checks can |
| 117 | +be helpful: |
| 118 | + |
| 119 | +```bash |
| 120 | +#!/bin/sh |
| 121 | +# flash.sh - Write image file to SD card with safety checks |
| 122 | + |
| 123 | +yorn= |
| 124 | +file= |
| 125 | +dev= |
| 126 | + |
| 127 | +fatal() |
| 128 | +{ |
| 129 | + printf "Error: %s\n" "$*" >&2 |
| 130 | + exit 1 |
| 131 | +} |
| 132 | + |
| 133 | +note() |
| 134 | +{ |
| 135 | + printf "%s\n" "$*" |
| 136 | +} |
| 137 | + |
| 138 | +yorn() |
| 139 | +{ |
| 140 | + [ -n "$yorn" ] && return 0 |
| 141 | + printf "%s, are you sure (y/N)? " "$1" |
| 142 | + read -r answer |
| 143 | + [ "$answer" = "y" ] || [ "$answer" = "Y" ] |
| 144 | +} |
| 145 | + |
| 146 | +# Parse arguments |
| 147 | +while getopts "y" opt; do |
| 148 | + case "$opt" in |
| 149 | + y) yorn=y ;; |
| 150 | + *) echo "Usage: flash [-y] DEV FILE" >&2; exit 1 ;; |
| 151 | + esac |
| 152 | +done |
| 153 | +shift $((OPTIND-1)) |
| 154 | + |
| 155 | +# Get device and file |
| 156 | +if [ $# -eq 2 ]; then |
| 157 | + dev=$1 |
| 158 | + file=$2 |
| 159 | +elif [ $# -eq 1 ]; then |
| 160 | + file=$1 |
| 161 | + # Try to guess SD card device |
| 162 | + guess_dev=$(lsblk -ndo NAME,RM,MOUNTPOINT | awk '$2=="1" && $3=="" { print $1 }') |
| 163 | + count=$(printf "%s\n" "$guess_dev" | wc -l) |
| 164 | + if [ "$count" -eq 1 ]; then |
| 165 | + dev="/dev/$guess_dev" |
| 166 | + note "Guessed SD card device: $dev" |
| 167 | + else |
| 168 | + fatal "Unable to safely guess SD card device." |
| 169 | + fi |
| 170 | +else |
| 171 | + echo "Usage: flash [-y] DEV FILE" >&2 |
| 172 | + exit 1 |
| 173 | +fi |
| 174 | + |
| 175 | +[ -b "$dev" ] || fatal "$dev is not a block device." |
| 176 | +[ -f "$file" ] || fatal "$file does not exist." |
| 177 | + |
| 178 | +# Safety check for system drives |
| 179 | +case "$dev" in |
| 180 | + /dev/sda* | /dev/nvme0n1* | /dev/vda*) |
| 181 | + printf "WARNING: %s looks like a system drive!\n" "$dev" >&2 |
| 182 | + yorn "Flash to $dev" || exit 1 |
| 183 | + ;; |
| 184 | +esac |
| 185 | + |
| 186 | +# Check if mounted |
| 187 | +if mountpoint -q "$dev" 2>/dev/null; then |
| 188 | + fatal "$dev is mounted. Unmount before proceeding." |
| 189 | +fi |
| 190 | + |
| 191 | +yorn "Write $file to $dev" || exit 0 |
| 192 | + |
| 193 | +note "Writing $file to $dev..." |
| 194 | +if ! dd if="$file" of="$dev" bs=1M status=progress oflag=direct conv=fsync; then |
| 195 | + fatal "dd failed to write image." |
| 196 | +fi |
| 197 | + |
| 198 | +note "Done." |
| 199 | +``` |
| 200 | + |
| 201 | +Save this as `flash.sh`, make it executable with `chmod +x flash.sh`, and use: |
| 202 | + |
| 203 | +```console |
| 204 | +$ ./flash.sh /dev/sdX infix-aarch64-bpi-r3.img |
| 205 | +``` |
| 206 | + |
| 207 | +The script includes automatic device detection if you omit the device |
| 208 | +argument, and safety checks to prevent accidentally overwriting system |
| 209 | +drives. |
| 210 | + |
| 211 | +[1]: https://github.com/kernelkit/infix/releases/tag/latest-boot |
| 212 | +[2]: https://etcher.balena.io/ |
| 213 | +[3]: https://win32diskimager.org/ |
| 214 | +[4]: /posts/getting-started/ |
| 215 | +[5]: https://github.com/kernelkit/infix/tree/main/doc |
| 216 | +[6]: https://discord.gg/6bHJWQNVxN |
0 commit comments