页面标题
GitHub Gitee

制作自己的 Docker 容器,并部署 Hi3519DV500 SDK

事先声明:这可能是过年前最后一篇文章了,同时也可能是近期《海思觉迷录》最后一篇使用 Hi3519DV500 的文章了
海思觉迷录的下一篇文章应该就是 Hi3863 的了

当我们在开发的时候,玩着玩着把自己的环境给搞的找不着北了(或者干脆玩崩了)也不算什么罕见的事情骂谁罕见
但是吧,如果我们每次遇上这种情况的时候都要重装虚拟机/重装系统/重装SDK,这其实也是一个挺耗时的过程。
所以,Docker 来了。

Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache 2.0 协议开源。
Docker 可以让开发者打包应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。

这里我们就以 Hi3519DV500 SDK 为例:

1. 准备工作

首先自然是准备放进容器里的“原材料”了:

MyProjectDir/
├── Dockerfile  # 一个文本文件,包含了一系列用于构建 Docker 镜像的指令
├── reg_info.bin  # 从 u-boot 表格的 VBA 宏里生成的文件
├── gcc-xxxx-aarch64-v01c01-linux-glibc.tgz   # 海思的交叉编译工具链
├── Hi3519DV500_SDK_Vx.x.x.x.tgz   # 海思的 SDK 包
├── cmake-3.16.5.tar.gz   # Cmake 源码包,要想在低版本 Ubuntu 上跑高版本 Cmake 就得要这玩意
└── Python-3.8.0.tgz   # Python 源码包,其实我感觉不是很需要这玩意,但是既然海思的手册推荐从源码安装,那咱们也这么做吧

这里也捎带着简单提一下常见几条 Dockerfile 指令:

# 使用 Ubuntu 18.04 作为基础镜像
FROM ubuntu:18.04

# 执行命令
RUN apt-get update

# 复制本地文件到镜像
COPY cmake-3.16.5.tar.gz /tmp/

# 设置环境变量
ENV ARCH=arm64
ENV CROSS_COMPILE=aarch64-v01c01-linux-gnu-

# 设置工作目录
WORKDIR /workspace

不过话说回来,既然是制作自己的 Docker 镜像,那本地得有 Docker 环境:

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# 验证是否安装成功
sudo docker run hello-world

# 将用户添加入 Docker 组
sudo usermod -aG docker $USER

如果找不到好用的镜像源的话,还是老老实实挂代理吧......

2. 正式开始

然后就可以开始制作了,首先是编写自己的 Dockerfile,这里除了海思的原生 SDK 之外还添加了 Cmake:

# 使用 Ubuntu 18.04 作为基础镜像
FROM ubuntu:18.04

# 1. 设置为非交互式环境,避免安装过程中等待用户输入
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai

# 2. 第一步:配置 dash(自动选择 'no',不使用 dash 作为默认 shell)
RUN echo "dash dash/sh boolean false" | debconf-set-selections && \
    dpkg-reconfigure --frontend=noninteractive dash

# 使用华为云镜像源替换 Ubuntu 官方源(加快国内下载速度)
RUN sed -i "s@http://.*archive.ubuntu.com@http://mirrors.huaweicloud.com@g" /etc/apt/sources.list && \
    sed -i "s@http://.*security.ubuntu.com@http://mirrors.huaweicloud.com@g" /etc/apt/sources.list

# 3. 更新源并安装所有必要的软件包(合并了多个 apt-get install 步骤以提高效率)
RUN apt-get update && apt-get install -y \
    make \
    libc6-i386 \
    lib32z1 \
    lib32stdc++6 \
    libncurses5-dev \
    ncurses-term \
    libncursesw5-dev \
    g++ \
    u-boot-tools \
    texinfo \
    gawk \
    libssl-dev \
    openssl \
    bc \
    p7zip-full \
    gperf \
    bison \
    flex \
    diffutils \
    git \
    unzip \
    libffi-dev \
    libtool \
    libfreetype6 \
    fakeroot \
    autopoint \
    po4a \
    zlib1g-dev \
    liblzo2-dev \
    uuid-dev \
    pkg-config \
    automake \
    texlive \
    wget \
    curl \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    autoconf \
    automake \
    libtool \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 4. 创建并清空 /etc/ld.so.preload 文件(解决32位库可能的问题)
RUN touch /etc/ld.so.preload && echo "" > /etc/ld.so.preload

# 5. 安装 CMake 3.16.5
COPY cmake-3.16.5.tar.gz /tmp/
RUN cd /tmp && \
    tar -xzf cmake-3.16.5.tar.gz && \
    cd cmake-3.16.5 && \
    ./bootstrap --prefix=/usr/local && \
    make -j$(nproc) && \
    make install && \
    cd /

# 6. 安装 Python 3.8 及 pip
COPY Python-3.8.0.tgz /tmp/
RUN cd /tmp && \
    tar -zxvf Python-3.8.0.tgz && \
    cd Python-3.8.0 && \
    ./configure --enable-optimizations --with-ensurepip=install && \
    make -j$(nproc) && \
    make install && \
    cd /

# 7. 设置 Python 3.8 为默认 python3,创建软链接
RUN ln -sf /usr/local/bin/python3.8 /usr/bin/python3  && \
    ln -sf /usr/local/bin/python3.8 /usr/bin/python

# 8. 安装指定版本的 Python 包
RUN python3.8 -m pip install --no-cache-dir --upgrade pip && \
    python3.8 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
    python3.8 -m pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn && \
    python3.8 -m pip install --no-cache-dir \
    wheel==0.36.2 \
    pycryptodome==3.9.8 \
    pyelftools==0.27 \
    cryptography==41.0.3

# 9. 安装交叉编译工具链
# 注意:需要将 gcc-xxxx-aarch64-v01c01-linux-musl.tgz 放在 Dockerfile 同级目录
COPY gcc-20231123-aarch64-v01c01-linux-gnu.tgz /tmp/
RUN cd /tmp && \
    tar xf gcc-20231123-aarch64-v01c01-linux-gnu.tgz && \
    cd gcc-20231123-aarch64-v01c01-linux-gnu && \
    ./install_gcc_toolchain.sh && \
    cd /

# 10. 解压并安装 SDK
# 注意:需要将 Hi3519DV500_SDK_V*.tgz 放在 Dockerfile 同级目录
COPY Hi3519DV500_SDK_V2.0.1.1.tgz /opt/
RUN cd /opt && \
    tar -zxf Hi3519DV500_SDK_V2.0.1.1.tgz && \
    cd Hi3519DV500_SDK_V2.0.1.1 && \
    ./sdk.unpack && \
    rm /opt/Hi3519DV500_SDK_V2.0.1.1.tgz

# 11. 设置环境变量
ENV ARCH=arm64
ENV CROSS_COMPILE=aarch64-v01c01-linux-gnu-
# 将 CMake 路径和交叉编译工具链路径都添加到 PATH
ENV PATH="/usr/local/bin:/opt/linux/x86-arm/aarch64-v01c01-linux-gnu-gcc/bin:${PATH}"
ENV HI_SDK_PATH="/opt/Hi3519DV500_SDK_V2.0.1.1"

# 12. 将 PATH 配置添加到 ~/.bashrc,以便交互式 shell 使用
RUN echo 'export PATH="/usr/local/bin:/opt/linux/x86-arm/aarch64-v01c01-linux-gnu-gcc/bin:$PATH"' >> ~/.bashrc && \
    echo "export HI_SDK_PATH=/opt/Hi3519DV500_SDK_V2.0.1.1" >> ~/.bashrc && \
    echo "export CROSS_COMPILE=aarch64-v01c01-linux-gnu-" >> ~/.bashrc && \
    echo "export ARCH=arm64" >> ~/.bashrc

RUN source ~/.bashrc

# 13. 编译 U-Boot
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/u-boot && \
    tar xf u-boot-2022.07.tar.bz2 && \
    cd u-boot-2022.07 && \
    patch -p1 < ../u-boot-2022.07.patch && \
    make ARCH=arm CROSS_COMPILE=aarch64-v01c01-linux-gnu- hi3519dv500_emmc_defconfig && \
    # 注意:menuconfig 需要交互,在自动构建中跳过或使用预设配置
    # 如果需要自动配置,可以使用以下命令预设配置:
    # sed -i 's/CONFIG_XXX=y/CONFIG_XXX=n/' .config
    # 这里暂时跳过 menuconfig,直接编译
    make ARCH=arm CROSS_COMPILE=aarch64-v01c01-linux-gnu- -j $(nproc)

# 14. 编译 gzip 工具并复制到 U-Boot 目录
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/u-boot && \
    make -C ../gzip/ && \
    cp ../gzip/bin/gzip u-boot-2022.07/arch/arm/cpu/armv8/hi3519dv500/hw_compressed/ -rf && \
    chmod +x u-boot-2022.07/arch/arm/cpu/armv8/hi3519dv500/hw_compressed/gzip

# 15. 生成 U-Boot 中间镜像
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/u-boot/u-boot-2022.07 && \
    make ARCH=arm CROSS_COMPILE=aarch64-v01c01-linux-gnu- u-boot-z.bin

# 16. 编译 Linux 内核
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/linux && \
    tar xf linux-5.10.tar.gz && \
    mv linux-5.10 linux-5.10.y && \
    cd linux-5.10.y && \
    patch -p1 < ../linux-5.10.patch && \
    make ARCH=arm64 CROSS_COMPILE=aarch64-v01c01-linux-gnu- hi3519dv500_emmc_defconfig && \
    # 同样跳过 menuconfig,使用默认配置
    make ARCH=arm64 CROSS_COMPILE=aarch64-v01c01-linux-gnu- uImage -j $(nproc)

# 17. 编译 ARM Trusted Firmware (ATF)
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/arm-trusted-firmware && \
    make OSDRV_CROSS=aarch64-v01c01-linux-gnu all

# 18. 复制本地 reg_info.bin 文件到镜像中
# 注意:需要将本地的 reg_info.bin 文件放在 Dockerfile 同一目录
COPY reg_info.bin /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp/tools/pc/boot_tools/

# 19. 编译 GSL 组件
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp/components/gsl && \
    make clean && \
    make

# 20. 准备并生成 boot 镜像
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp && \
    # 复制 gsl.bin
    cp ./components/gsl/pub/gsl.bin ./tools/pc/image_tool/input/ && \
    # 复制 u-boot 二进制文件(注意路径和文件名可能需要调整)
    cp ../../../../open_source/u-boot/u-boot-2022.07/u-boot-hi3519dv500.bin ./tools/pc/image_tool/input/u-boot-original.bin 2>/dev/null && \
    # 复制 reg_info.bin
    cp ./tools/pc/boot_tools/reg_info.bin ./tools/pc/image_tool/input/ && \
    # 生成 boot 镜像
    cd ./tools/pc/image_tool && \
    python3.8 oem/oem_quick_build.py

# 编译整个 bsp 目录
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp && \
    make -j$(nproc) BOOT_MEDIA=emmc LIB_TYPE=glibc CHIP=hi3519dv500 all

RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/e2fsprogs && \
    tar -xvf e2fsprogs-1.46.4.tar.xz && \
    cd ./e2fsprogs-1.46.4 && \
    patch -p1 < ../e2fsprogs-1.46.4.patch && \
    cd ../ && make OSDRV_CROSS=aarch64-v01c01-linux-gnu -j$(nproc)

RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/e2fsprogs && \
    cp ./out/pc/sbin/mkfs.ext4 /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp/pub/bin/pc/

# 21. 创建根文件系统镜像
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source && \
    # 创建空的 ext4 镜像文件
    dd if=/dev/zero of=bsp/pub/hi3519dv500_emmc_image_glibc/rootfs_hi3519dv500_1024M.ext4 bs=512 count=2097152 && \
    # 格式化 ext4 文件系统
    ./bsp/pub/bin/pc/mkfs.ext4 bsp/pub/hi3519dv500_emmc_image_glibc/rootfs_hi3519dv500_1024M.ext4

# 22. 填充根文件系统
RUN cd /opt/Hi3519DV500_SDK_V2.0.1.1/open_source/e2fsprogs/out/pc/contrib && \
    ./populate-extfs.sh ../../../../../smp/a55_linux/source/bsp/pub/rootfs_glibc_arm64 \
    ../../../../../smp/a55_linux/source/bsp/pub/hi3519dv500_emmc_image_glibc/rootfs_hi3519dv500_1024M.ext4

# 23. 创建非 root 用户用于开发(可选但推荐)
RUN useradd -m -s /bin/bash developer && \
    chown -R developer:developer /opt/Hi3519DV500_SDK_V2.0.1.1

# 24. 设置工作目录并切换到非 root 用户
WORKDIR /workspace
USER developer

# 25. 默认启动命令
CMD ["/bin/bash"]

可以先拉取基础镜像,再执行 Dockerfile 文件进行构建:

docker pull ubuntu:18.04
docker build -t hi3519dv500-dev:latest .

这样即为构建成功:
image

然后,导出容器镜像文件即可:docker save -o hi3519dv500-dev.tar hi3519dv500-dev:latest

执行 docker load -i xxx.tar 可以导入外部容器镜像文件
执行 docker images 可验证导入是否成功

3. 测试

接下来进行测试:

docker run --rm -it -v $(pwd):/workspace hi3519dv500-dev:latest
cd /opt/Hi3519DV500_SDK_V2.0.1.1/smp/a55_linux/source/bsp  # 进入 Docker 容器
make -j$(nproc) BOOT_MEDIA=emmc LIB_TYPE=glibc CHIP=hi3519dv500 all  # 编译整个系统镜像

若没有报错,则成功
image

下一篇文章不出意外的话应该是瑞芯微的 CMOS Sensor 驱动移植了

posted @ 2026-02-04 10:26  Wintoki  阅读(22)  评论(0)    收藏  举报