# uSD Image Builder

Scripts to build uSD images for NDI demo platforms based on Debian can be found in the `fpga_reference_design/os_uSD` directory:

| File              | Description                                            |
| ----------------- | ------------------------------------------------------ |
| `README.md`       | This file                                              |
| `CHANGELOG.md`    | List of notable changes                                |
| `a10-socdk.conf`  | Config file for Arria-10 SoC Development Kit           |
| `agilex7.conf`    | Config file for Agilex-7 SoC Development Kit           |
| `sockit.conf`     | Config file for SoCKit image                           |
| `zcu104.conf`     | Config file for ZCU104                                 |
| `zybo.conf`       | Config file for Zybo-Z7-20 and Arty-Z7-20              |
| `build.sh`        | Main image build script                                |
| `common.sh`       | Functions common to several scripts                    |
| `boot.sh`         | Extracts boot files from a PetaLinux project           |
| `debootstrap.sh`  | Creates a Debian root filesystem from scratch          |
| `second-stage.sh` | The debootstrap second-stage and rootfs customizations |
| `mk.uSD.sh`       | Creates a uSD image from boot files and a rootfs       |
| `part.txt`        | Partion table for the uSD                              |
| `part.a2.txt`     | Partion table for uSD images with Altera A2 partition  |
| `update.*.tgz.sh` | Example to generate optional tgz files                 |

The build scripts use a configuration file which provides details needed to create an image. The main details required are a pointer to the boot files and various architecture specific information (eg: the Debian architecture name and the qemu static binary to use for an emulated chroot environment). Various other settings may be tweaked as well, including the uSD target size, system host name, etc. Refer to the existing `\*.conf` files for details.

### Build Dependencies

* `debootstrap`

  Used to create a root filesystem image. Currently using version 1.0.128nmu2 with Debian 13 (trixie). Many operating systems ship with an older version of debootstrap that is available through their package managers. It is recommended that a more recent version be installed from a preexisting .deb package. See [Section D.3.2. Install debootstrap](https://www.debian.org/releases/stable/amd64/apds03.en.html) of the Debian GNU/Linux Installation Guide for more details.
* `qemu-static`

  Required to run debootstrap second-stage. Currently tested with version 4.2.1. Note that transparent emulation needs to be set up on the host system. See the QEMU documentation for more details on how to configure this.

### Build an image

To build an image from scratch, simply run the build.sh script with the desired configuration specified:

```
./build.sh zcu104.conf
```

### Rebuild an image

It is often not necessary to run all steps from scratch. Once an initial build has created the required bootfs and rootfs directories, each component of the uSD image may be updated independently. The components that makeup the uSD image are:

* `bootfs.<board>/`

  This directory contains the Xilinx boot files and linux kernel modules extracted from the PetaLinux project. This directory is created and updated by running the `boot.sh` script.
* `../linux_kernel/<board>/boot`

  This directory contains the Altera boot files and linux kernel modules. This directory is created and updated by running make in the `../linux_kernel/<board>` directory.
* `root.<deb_arch>.tgz`

  This file is manually generated and if present will be extracted to the root directory of the target file-system by the root user. This is currently used to install pre-compiled NDI example binaries to /usr/local/bin and the required shared libraries to /usr/local/lib.

  This file is processed by the `second-stage.sh` script, so any changes require re-running `debootstrap.sh` or manually applying the changes to the rootfs directory.

  Note this file should include full paths preceded by a leading ./ eg: `./usr/local/lib/file.so`. Below is one example of how to properly create this file:

  ```
  # Start at the root directory
  cd /

  # Create a tar archive with a leading ./ and put it in /tmp
  tar -czvf /tmp/root.armhf.tgz ./usr/local/bin/*
  ```
* `user.<deb_arch>.tgz`

  This file is similar to the `root.<deb_arch>.tgz` file, above, except it is extracted into the default user's home directory by the default user. This file is used to install the HDMI start and stop scripts for the ZCU104, and is unused by the Zybo-Z7-20 example. Place any files that need to be owned by the default user and thus cannot be placed in the root archive (since the default username, uid/gid, and home directory may change) into this archive.

  This file is processed by the `second-stage.sh` script, so any changes require re-running `debootstrap.sh` or manually applying the changes to the rootfs directory.
* `rootfs.<deb_arch>/`

  This directory contains a stock Debian install generated by debootstrap along with some modifications required to make a usable image (eg: create /etc/fstab and enable networking) and tweaks required for this example (eg: build and install the libuio package). This directory is generated by running the `debootstrap.sh` script, while most of the customizations to the rootfs occur in the `second-stage.sh` script.

  Running debootstrap.sh deletes any existing rootfs and recreates it from scratch, which is a lengthy process and does not allow for modifications other than editing the `second-stage.sh` script. Once created, however, the rootfs directory may be edited manually, just be careful with file-system permissions and user ids. It is also possible to chroot to the rootfs and execute native commands, eg:

  ```
  # Setup shell variables for our configuration
  source zcu104.conf

  # Open a native shell in the rootfs
  sudo LANG=C.UTF-8 chroot $ROOTFS /bin/bash
  ```

Once any desired changes have been made to the above components, a new image can be created by running:

```
sudo ./mk.uSD.sh <config>.conf
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ndi.video/all/developing-with-ndi/advanced-sdk/ndi-advanced-sdk-fpga-example-reference-design/ndi-advanced-sdk-fpga-ip/usd-image-builder.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
