简介
Duo 系列开发板默认的 SDK 是基于 buildroot 构建的,用来生成 Duo 的固件,目前 SDK 有 V1 和 V2 两个版本。
- V1 版本 SDK 只支持 RISCV 核。(建议 Duo 64M 使用该版本)
- V2 版本 SDK 既支持 RISCV 核,也支持 ARM 核。(建议 Duo256M 和 DuoS 使用该版本)
建议 Duo 64M 选用 V1 版本的 SDK,主要是由于其内存较小,V2 版本的 SDK 中相关的 AI 应用目前还无法在 Duo 64M 中正常运行。
Buildroot SDK V1
SDK 主要包含如下几个部分:
- u-boot: 2021.10
- linux kernel: 5.10.4
- buildroot: 2021.05
- opensbi: 89182b2
源码地址: https://github.com/milkv-duo/duo-buildroot-sdk
SDK目录结构:
├── build 编译目录,存放编译脚本以及各board差异化配置
├── build.sh Milk-V Duo 一键编译脚本
├── buildroot-2021.05 buildroot 开源工具
├── freertos freertos 系统
├── fsbl fsbl启动固件,prebuilt 形式存在
├── install 执行一次完整编译后,临时存放各 image 路径
├── isp_tuning 图像效果调试参数存放路径
├── linux_5.10 开源 linux 内核
├── middleware 算能多媒体框架,包含 so 与 ko
├── device 存放 Milk-V Duo 相关配置及脚本文件的目录
├── opensbi 开源 opensbi 库
├── out Milk-V Duo 最终生成的镜像所在目录
├── ramdisk 存放最小文件系统的 prebuilt 目录
└── u-boot-2021.10 开源 uboot 代码
Buildroot SDK V2
SDK 主要包含如下几个部分:
- u-boot: 2021.10
- linux kernel: 5.10.4
- buildroot: 2025.02
- opensbi: 89182b2
源码地址: https://github.com/milkv-duo/duo-buildroot-sdk-v2
稳定分支: main
SDK目录结构:
├── build 编译目录,存放编译脚本以及各board差异化配置
├── build.sh Milk-V Duo 一键编译脚本
├── buildroot buildroot 开源工具
├── cvi_mpi 算能多媒体框架
├── device 存放 Milk-V Duo 相关配置及脚本文件的目录
├── freertos freertos 系统
├── fsbl fsbl启动固件,prebuilt 形式存在
├── install 执行一次完整编译后,临时存放各 image 路径
├── isp_tuning 图像效果调试参数存放路径
├── linux_5.10 开源 linux 内核
├── osdrv 一些外设驱动源码
├── opensbi 开源 opensbi 库
├── out Milk-V Duo 最终生成的镜像所在目录
├── tdl_sdk 算能深度学习算法 SDK
└── u-boot-2021.10 开源 uboot 代码
编译镜像
准备编译环境,使用本地的 Ubuntu 系 统,官方支持的编译环境为 Ubuntu Jammy 22.04.x amd64。
如果您使用的是其他的 Linux 发行版,我们强烈建议您使用 Docker 环境来编译,以降低编译出错的概率。
以下分别介绍两种环境下的编译方法。
另外,V1 版本和 V2 版本 SDK 的编译方法基本一致,下面以 V2 版本 SDK 为例,介绍 SDK 的编译步骤。
一、使用 Ubuntu 22.04 编译
安装编译依赖的工具包
sudo apt install -y pkg-config build-essential ninja-build automake autoconf libtool wget curl git gcc libssl-dev bc slib squashfs-tools android-sdk-libsparse-utils jq python3-distutils scons parallel tree python3-dev python3-pip device-tree-compiler ssh cpio fakeroot libncurses5 flex bison libncurses5-dev genext2fs rsync unzip dosfstools mtools tcl openssh-client cmake expect python-is-python3
对于 duo-buildroot-sdk-v2,还需要安装以下工具包:
sudo pip install jinja2
获取 SDK
git clone https://github.com/milkv-duo/duo-buildroot-sdk-v2.git --depth=1
在编译过程中,Buildroot 会自动下载一些源码包。SDK V1 中已经集成了部分常用源码包,可以直接编译。SDK V2 中,为了避免由于网络原因导致下载失败,可以提前下载 dl.tar 包并解压到 buildroot 目录:
wget https://github.com/milkv-duo/duo-buildroot-sdk-v2/releases/download/dl/dl.tar
tar xvf ./dl.tar -C ./duo-buildroot-sdk-v2/buildroot/
解压后 duo-buildroot-sdk-v2 的 buildroot 中 dl 目录结构如下:
└── buildroot
└── dl
├── acl
├── alsa-lib
├── alsa-utils
├── attr
├── ...
1、一键编译
执行一键编译脚本 build.sh:
cd duo-buildroot-sdk-v2/
./build.sh
会看到编译脚本的使用方法提示:
$ ./build.sh
Usage:
./build.sh - Show this menu
./build.sh lunch - Select a board to build
./build.sh [board] - Build [board] directly, supported boards as follows:
milkv-duo-musl-riscv64-sd
milkv-duo256m-glibc-arm64-sd
milkv-duo256m-musl-riscv64-sd
milkv-duos-glibc-arm64-emmc
milkv-duos-glibc-arm64-sd
milkv-duos-musl-riscv64-emmc
milkv-duos-musl-riscv64-sd
最下边列出的是当前支持的目标 版本列表。
如提示中所示,有两种方法来编译目录版本。
第一种方法是执行 ./build.sh lunch 调出交互菜单,选择要编译的版本序号,回车:
$ ./build.sh lunch
Select a target to build:
1. milkv-duo-musl-riscv64-sd
2. milkv-duo256m-glibc-arm64-sd
3. milkv-duo256m-musl-riscv64-sd
4. milkv-duos-glibc-arm64-emmc
5. milkv-duos-glibc-arm64-sd
6. milkv-duos-musl-riscv64-emmc
7. milkv-duos-musl-riscv64-sd
Which would you like:
- Duo (64M-DDR) 只有 RISC-V 核,默认为基于 musl libc 编译的 SD 卡镜像。
- Duo256M 支持 RISC-V 和 ARM 核(二选一),RISC-V 核固件基于 musl libc 编译,ARM 核固件基于 glibc 编译,只配置了 SD 卡镜像。
- DuoS 支持 RISC-V 和 ARM 核(二选一),RISC-V 核固件基于 musl libc 编译,ARM 核固件基于 glibc 编译,配置了 SD 卡和 eMMC 镜像。
第二种方法是脚本后面带上目标版本的名字,比如要编译 milkv-duos-musl-riscv64-sd 的镜像:
$ ./build.sh milkv-duos-musl-riscv64-sd
编译成功后可以在 out 目录下看到生成的镜像,其中 *.img 后缀的镜像为 SD 卡烧录的镜像,*.zip 后缀的镜像为 eMMC 的烧录镜像。
注: 第一次编译会自动下载所需的工具链,大小为 840M 左右,下载完会自动解压到 SDK 目录下的 host-tools 目录,下次编译时检测到已存在 host-tools 目录,就不会再次下载了
2、分步编译
如果未执行过一键编译脚本,需要先手动下载工具链 host-tools,再拷贝或移动到 SDK 根目录:
git clone https://github.com/milkv-duo/host-tools.git
cp -a host-tools duo-buildroot-sdk-v2/
加载环境:
source build/envsetup_milkv.sh
如果是第一次编译,会提示选择要编译的目标:
Select a target to build:
1. milkv-duo-musl-riscv64-sd
2. milkv-duo256m-glibc-arm64-sd
3. milkv-duo256m-musl-riscv64-sd
4. milkv-duos-glibc-arm64-emmc
5. milkv-duos-glibc-arm64-sd
6. milkv-duos-musl-riscv64-emmc
7. milkv-duos-musl-riscv64-sd
Which would you like:
选择对应的数字后,回车,成功加载环境变量后,会显示一些当前目标的信息,比如:
Target Board: milkv-duos-musl-riscv64-sd
Target Board Storage: sd
Target Board Config: /build/duo-buildroot-sdk-v2/device/target/boardconfig.sh
Target Image Config: /build/duo-buildroot-sdk-v2/device/target/genimage.cfg
Build tdl-sdk: 1
Output dir: /build/duo-buildroot-sdk-v2/install/soc_sg2000_milkv_duos_musl_riscv64_sd
环境加载完成后,会在 device 目录下创建一个名为 target 的链接,链接到编译目标目录,下次再 source 环境时,检测到该 target 链接存在时,就不会再提示选择目标了。如果需要更换编译目标,可以加 lunch 参数重新调出交互菜单进 行选择:
source build/envsetup_milkv.sh lunch
加载环境成功后,再依次输入如下命令完成分步编译:
clean_all
build_all
如果编译的是 SD 卡镜像,还需要再执行如下命令生成 img 镜像:
pack_sd_image
比如需要编译 milkv-duos-musl-riscv64-sd 的镜像,分步编译命令如下:
source build/envsetup_milkv.sh milkv-duos-musl-riscv64-sd
clean_all
build_all
pack_sd_image
生成的固件位置:
install/soc_sg2000_milkv_duos_musl_riscv64_sd/milkv-duos-musl-riscv64-sd.img
注意,SD 卡镜像为 *.img,eMMC镜像为 upgrade.zip。
除了使用 build_all 进行完整编译之外,还可以单独编译某个模块,一般来说都是先执行 clean_xxx 清理中间文件后,再执行 build_xxx 重新编译。支持的模块,可以输入 clean_ 或者 build_ 后,双击 tab 键查看。以下列出一些常用的模块编译方法:
- fsbl:
clean_fsbl,build_fsbl - uboot:
clean_uboot,build_uboot - kernel:
clean_kernel,build_kernel - osdrv:
clean_osdrv,build_osdrv - cvi_mpi:
clean_middleware,build_middleware - tdl-sdk:
clean_tdl_sdk,build_tdl_sdk
二、使用 Docker 编译
需要在运行 Linux 系统的主机上支持 Docker。 Docker 的 使用方法请参考官方文档或其他教程。
我们将 SDK 代码放在 Linux 主机系统上,调用 Milk-V 提供的 Docker 镜像环境来编译。
在 Linux 主机上拉 SDK 代码
git clone https://github.com/milkv-duo/duo-buildroot-sdk-v2.git --depth=1
在编译过程中,Buildroot 会自动下载一些源码包。SDK V1 中已经集成了部分常用源码包,可以直接编译。SDK V2 中,为了避免由于网络原因导致下载失败,可以提前下载 dl.tar 包并解压到 buildroot 目录:
wget https://github.com/milkv-duo/duo-buildroot-sdk-v2/releases/download/dl/dl.tar
tar xvf ./dl.tar -C ./duo-buildroot-sdk-v2/buildroot/
解压后 duo-buildroot-sdk-v2 的 buildroot 中 dl 目录结构如下:
└── buildroot
└── dl
├── acl
├── alsa-lib
├── alsa-utils
├── attr
├── ...
进入 SDK 代码目录
cd duo-buildroot-sdk-v2
拉取 Docker 镜像并运行
docker run --privileged -itd --name duodocker -v $(pwd):/home/work milkvtech/milkv-duo:latest /bin/bash
命令中部分参数说明:
--privileged以特权模式启动容器。duodockerdocker 运行时名字,可以使用自己想用的名字。$(pwd)当前目录,这里是上一步 cd 到的 duo-buildroot-sdk 目录。-v $(pwd):/home/work将当前的代码目录绑定到 Docker 镜像里的 /home/work 目 录。milkvtech/milkv-duo:latestMilk-V 提供的 Docker 镜像,第一次会自动从 hub.docker.com 下载。
Docker 运行成功后,可以用 docker ps -a 命令查看运行状态:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8edea33c2239 milkvtech/milkv-duo:latest "/bin/bash" 2 hours ago Up 2 hours duodocker
如果 Docker 服务器上的镜像有更新,可以使用 docker pull milkvtech/milkv-duo:latest 命令来同步最新的镜像。
1. 使用 Docker 一键编译
docker exec -it duodocker /bin/bash -c "cd /home/work && cat /etc/issue && export FORCE_UNSAFE_CONFIGURE=1 && ./build.sh [board]"
注意命令最后的 ./build.sh [board] 和前面在 Ubuntu 22.04 中一键编译说明中的用法是一样的,直接 ./build.sh 可以查看命令的使用方法,用 ./build.sh lunch 可以调出交互选择菜单,用 ./build.sh [board] 可以直接编译目标版本,[board] 可以替换为:
milkv-duo-musl-riscv64-sd
milkv-duo256m-glibc-arm64-sd
milkv-duo256m-musl-riscv64-sd
milkv-duos-glibc-arm64-emmc
milkv-duos-glibc-arm64-sd
milkv-duos-musl-riscv64-emmc
milkv-duos-musl-riscv64-sd
命令中部分参数说明:
duodocker运行的 Docker 名字, 与上一步中设置的名字要保持一致"*"双引号中是要在 Docker 镜像中运行的 Shell 命令cd /home/work是切换到 /home/work 目录,由于运行时已经将该目录绑定到主机的代码目录,所以在 Docker 中 /home/work 目录就是该 SDK 的源码目录cat /etc/issue显示 Docker 使用的镜像的版本号,目前是 Ubuntu 22.04.3 LTS,调试用export FORCE_UNSAFE_CONFIGURE=1Docker 中默认使用 root 用户编译,需要使用该环境变量./build.sh [board]执行一键编译脚本
比如需要编译 milkv-duos-musl-riscv64-sd 的镜像,编译命令如下:
docker exec -it duodocker /bin/bash -c "cd /home/work && cat /etc/issue && export FORCE_UNSAFE_CONFIGURE=1 && ./build.sh milkv-duos-musl-riscv64-sd"
编译成功后可以在 out 目录下看到生成的SD卡烧录镜像 *.img
2. 使用 Docker 分步编译
如果未执行过一键编译脚本,需要先手动下载工具链 host-tools,再拷贝或移动到 SDK 根目录:
git clone https://github.com/milkv-duo/host-tools.git
cp -a host-tools duo-buildroot-sdk-v2/
分步编译需要登陆到 Docker 中进行操作,用命令 docker ps -a 查看并记录容器的 ID 号,比如 8edea33c2239