# How to Build Firmware

## Overview

K230 RTOS SDK is a multi-repository integrated development kit managed by repo. It includes core components such as U-Boot, OpenSBI, RT-Smart, and MPP. This document provides a complete guide to setting up the development environment, downloading the source code, and building the firmware.

## Development Environment Requirements

> It is recommended to use a virtual machine or Docker and to back up your work regularly to prevent data loss.

### System Requirements

- **Operating System**: Ubuntu 20.04 LTS (x86_64)
  *Other Linux distributions have not been fully tested and may have compatibility issues.*

### Hardware Requirements

- Memory: ≥ 2 GB recommended
- Disk space: ≥ 10 GB free space recommended

## Setting Up the Development Environment

### Configure APT Sources (Optional, Recommended for Users in China)

```bash
sudo cp /etc/apt/sources.list /etc/apt/sources_bak.list
sudo sed -i "s/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
sudo sed -i "s/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
sudo apt update
```

### Install System Dependencies

```bash
# Add support for i386 architecture
sudo dpkg --add-architecture i386
sudo apt update

# Install the compiler toolchain and dependencies
sudo apt install -y --no-install-recommends \
    sudo vim wget curl git git-lfs openssh-client net-tools sed tzdata expect \
    make cmake binutils build-essential gcc g++ bash patch perl tar cpio unzip \
    file bc bison flex autoconf automake python3 python3-pip python3-dev \
    lib32z1 libncurses5-dev fakeroot pigz tree doxygen gawk pkg-config \
    libssl-dev libc6-dev-i386 libncurses5:i386 libconfuse-dev python-is-python3 scons libyaml-dev mtools

# Clean package cache
sudo apt clean
```

### Configure the Python Environment

```bash
# Configure a PIP mirror source (recommended)
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# Install Python dependencies
pip3 install -U pyyaml pycryptodome gmssl jsonschema jinja2
```

### Install the repo Tool

```bash
mkdir -p ~/.bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
chmod a+rx ~/.bin/repo
echo 'export PATH="$HOME/.bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```

## Downloading the Source Code and Building

## 10-Minute Quick Start (Recommended)

If this is your first time working with the K230 RTOS SDK, follow this shortest path to complete a successful build:

```bash
# 1) Download source code. Gitee requires a registered account and configured SSH key.
mkdir -p ~/rtos_k230 && cd ~/rtos_k230
repo init -u git@gitee.com:canmv-k230/manifest.git --repo-url=git@gitee.com:canmv-k230/git-repo.git
repo sync -j $(nproc)

# 2) Download toolchain (first time only)
make dl_toolchain

# 3) Select the board configuration (example: 01Studio)
make k230_rtos_01studio_defconfig

# 4) Build
time make log

# 5) View the output image
ls -lh output/k230_rtos_01studio_defconfig/images/
```

If your board is not an 01Studio, run `make list-def` first, then select the corresponding `k230_rtos_*_defconfig`.

### Initialize git Configuration

```bash
# Configure your username and email based on your git account
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
```

### Download the SDK Source Code

```bash
# Create a working directory
mkdir -p ~/rtos_k230 && cd ~/rtos_k230

# Download from Gitee (recommended for users in China; requires SSH key configured)
repo init -u git@gitee.com:canmv-k230/manifest.git --repo-url=git@gitee.com:canmv-k230/git-repo.git

# Download from GitHub (for international users)
# repo init -u https://github.com/canmv-k230/manifest --repo-url=https://github.com/canmv-k230/git-repo.git

# Synchronize the repository
repo sync -j $(nproc)
```

### Initialize the Toolchain

```bash
# Download the toolchain the first time (only needs to be run once)
make dl_toolchain
```

### Select the Target Board Configuration

```bash
# List all supported board configurations
make list-def

# Example: 01Studio development board
make k230_rtos_01studio_defconfig

# Example: LCKFB development board
make k230_rtos_lckfb_defconfig
```

### Building an RTOS Image When Only a CanMV defconfig Is Available

Some boards may only have a `k230_canmv_*_defconfig` and no corresponding `k230_rtos_*_defconfig`. In that case you can still build an RTOS image based on the CanMV defconfig:

```bash
# 1) Select an available CanMV defconfig
make k230_canmv_xxx_defconfig

# 2) Open menuconfig to adjust feature switches
make menuconfig
```

In `menuconfig`, adjust at minimum the following:

1. Disable CanMV components:

```text
CanMV Components Configuration
```

Disable this option (i.e. do not enable `CONFIG_SDK_ENABLE_CANMV`).

1. Enable samples as needed:

```text
RT-Smart UserSpace Examples Configuration > Enable xxxx examples
```

1. If you need to build a custom application, enable its switch:

```text
Applications Configuration > (select your application switch)
```

For example, the built-in sample: `Enable Application HelloWorld`.

After saving the configuration, run the build:

```bash
time make log
```

If you want to preserve the current configuration as a new defconfig, run:

```bash
make savedefconfig
```

Then save the generated configuration under `configs/` for team reuse.

### Execute the Build

```bash
# Start a full build (this takes a while; using `time` is recommended to track duration)
time make log
```

**Build Output**
Generated firmware images are located at:
`./output/<defconfig>/images/`

Common files include:

- `*.img`: used for SD card flashing or certain command-line flashing scenarios
- `*.kdimg`: used with the K230BurningTool USB flasher, or for OTA upgrades

## Directory Structure

```text
rtos_k230/
├── boards/          # Board support packages (BSP): power, pin, boot media, DDR configurations
├── configs/         # defconfig collection (entry-level configurations)
├── output/          # Build output directory (organized by defconfig)
├── src/
│   ├── applications # User applications (custom apps, packaged to /sdcard/app)
│   ├── opensbi/     # OpenSBI (second-stage bootloader)
│   ├── rtsmart/     # RT-Smart kernel, drivers, MPP, samples, etc.
│   ├── uboot/       # U-Boot (boot loader, partition/image loading)
│   └── canmv/       # CanMV components (included in build when CONFIG_SDK_ENABLE_CANMV is enabled)
└── tools/           # Build scripts, Kconfig, toolchain management scripts
```

### Key Directory Details

#### boards/

- **Purpose**: Stores board-level difference configurations (BSP), such as memory specifications, boot media, peripheral multiplexing, and image layout settings.
- **Typical use**: Adding a new board, adjusting board-level hardware parameters (e.g. certain GPIO/power/DDR settings).

#### configs/

- **Purpose**: Stores `*_defconfig` files, which are the configuration entry points for the project.
- **Usage**: After running `make <board>_defconfig`, the configuration is expanded into the root `.config` file. Subsequent `make menuconfig` operations build on top of this.
- **Recommendation**: Fix a single verified defconfig for your team to avoid configuration drift.

#### output/

- **Purpose**: Output directory for each build.
- **Structure**: `output/<defconfig>/...`
- **Common subdirectories**:
  - `output/<defconfig>/images/`: Final flashable images (typically `*.img`, `*.kdimg`)
  - `output/<defconfig>/rtsmart/`: RT-Smart intermediate build artifacts
  - `output/<defconfig>/uboot/`, `opensbi/`, `applications/`: Per-module build artifacts

#### src/rtsmart/

- **Purpose**: The main RTOS directory—the core source of most runtime capabilities and samples.
- **Key top-level subdirectories**:
  - `rtsmart/`: RT-Smart core (kernel, system components, tools)
  - `mpp/`: Multimedia Processing Platform (video/audio/image kernel and user-space APIs)
  - `examples/`: Official sample projects (peripheral, MPP, AI, integrated)
  - `libs/`: Common libraries and HAL (e.g. `rtsmart_hal`, 3rd-party, nncase, OpenCV)

- **Common development scenarios and where to look**:
  - Adjusting RT-Smart system behavior: start with `src/rtsmart/rtsmart/`
  - Adjusting media pipeline or driver interfaces: start with `src/rtsmart/mpp/`
  - Testing hardware or features: pick the appropriate sample from `src/rtsmart/examples/`
  - Adding low-level driver wrappers or shared capabilities: start with `src/rtsmart/libs/`

- **Relationship to image contents**:
  - `src/rtsmart/examples/` compiles to the samples directory in the image (typically `/sdcard/app/examples/`)
  - Changes to `src/rtsmart/mpp/` and `src/rtsmart/libs/` affect the corresponding runtime libraries and sample behavior

#### src/applications/

- **Purpose**: Entry point for user-defined applications (more suitable for project delivery than samples).
- **Common workflow**: Create an application directory → register in `apps.mk`/Kconfig → enable in `menuconfig` → compile and package with `make`.

#### src/canmv/

- **Purpose**: CanMV-related components and resources.
- **Note**: When `CONFIG_SDK_ENABLE_CANMV` is disabled, this directory is not included in the build—suitable for pure RTOS image scenarios.

#### tools/

- **Purpose**: Build system infrastructure, including toolchain download, Kconfig parsing, and helper scripts.
- **Common command entry points**: `make dl_toolchain`, `make menuconfig`, `make list-def`.

### Common Locations for Getting Started

- Find flashable images: `output/<defconfig>/images/`
- Find the current editable configuration: root `.config` (generated from defconfig + menuconfig)
- Find default configuration templates: `configs/`
- Find sample source code: `src/rtsmart/examples/`
- Find custom application source code: `src/applications/`

## Troubleshooting

### Source Code Sync Failure

- **Symptom**: `repo sync` reports an error or hangs
- **Solution**:
  1. Check your network connection. Users in China should prefer the Gitee repository.
  1. Retry with: `repo sync -j4 --fail-fast`

### Toolchain Not Found

- **Symptom**: `make` reports that the toolchain cannot be found
- **Solution**: Ensure you have run `make dl_toolchain` and check that the toolchain files exist under `~/.kendryte/k230_toolchains`.

### Dependency Conflict

- **Symptom**: A library version incompatibility error during the build
- **Solution**:
  1. Check installed versions with `apt list --installed`.
  1. Install a specific version with `sudo apt install <package>=<version>`.

### Image Packaging Failure

- **Symptom**: The final packaging step reports that a partition is too small
- **Solution**: Reduce the number of enabled examples, or modify the board's image configuration file to increase the size of the affected partition.

## Next Steps

- [Flash Firmware to the Development Board](./how_to_flash.md)
- [Run Sample Programs](./how_to_run_samples.md)

After following this guide, you have set up the K230 RTOS SDK development environment and built the firmware. If you have further questions, refer to the official documentation or open an issue in the code repository.
