search
arrow_back 返回
Docker

Docker

Docker

我现在的Ubuntu是20.04版本的,我要开发编译飞凌嵌入式的SDK(22.04),如果不想重新装一个22.04版本的Ubuntu,那就装一个Docker

可以看野火电子官方Docker安装配置教程

但是野火的教程是专门为了“制作纯净的 Ubuntu 根文件系统”设计的,默认使用 Docker 的 root 权限,在编译 U-Boot 和内核(Linux 源码) 时,如果用 root 权限编译,生成的所有文件(.o, .bin, .img)在你的宿主机上也会变成 root 拥有。以后你不用 sudo 就连删都删不掉,非常麻烦

因此我们这里自己创建一个专门用来开发OK3576的容器,这个容器是为了“编译整套底层源码(U-Boot、Kernel)”设计的,在 Dockerfile 中通过 USER_ID 和 GROUP_ID 创建了一个和你宿主机一模一样的普通用户

OK3576在线文档

安装Docker

使用存储库安装

在新主机上首次安装 Docker Engine 之前,需要设置 Docker 存储库。之后就可以从存储库安装和更新 Docker。

设置存储库

更新apt包索引并安装相关软件包以允许apt通过HTTPS使用docker存储库

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

添加 Docker 的官方 GPG 密钥

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

设置存储库

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

安装 Docker engine

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

验证安装完成

sudo docker -v

image

创建 Dockerfile

在现有的 Ubuntu 20.04 电脑上,新建一个空白目录,然后在里面创建一个名为 Dockerfile 的文件(没有任何后缀名),并将以下内容复制进去

# 使用官方 Ubuntu 22.04 作为基础镜像
FROM ubuntu:22.04

# 避免在安装软件包时弹出时区或键盘设置对话框
ENV DEBIAN_FRONTEND=noninteractive

# 1. 更新源并安装飞凌 OK3576 官方要求的所有依赖库
RUN apt-get update && apt-get install -y \
    build-essential libncurses5-dev ncurses-dev lzop net-tools \
    openssh-server vim git fakeroot libsqlite3-dev \
    ssh make gcc libssl-dev liblz4-tool expect expect-dev g++ \
    patchelf chrpath gawk texinfo diffstat binfmt-support \
    qemu-user-static live-build bison flex cmake gcc-multilib \
    g++-multilib unzip device-tree-compiler \
    libgucharmap-2-90-dev bzip2 expat gpgv2 cpp-aarch64-linux-gnu \
    libgmp-dev libmpc-dev bc python-is-python3 python2 \
    sudo locales tzdata cpio \
    && rm -rf /var/lib/apt/lists/*

# 2. 设置本地化字符集(防止后续 Python 脚本报 UTF-8 编码错误)
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

# 3. 接收宿主机用户的 UID 和 GID
ARG USER_ID=1000
ARG GROUP_ID=1000

# 4. 创建一个与宿主机同 UID 的普通用户,赋予 sudo 免密权限
RUN groupadd -g ${GROUP_ID} buildgroup && \
    useradd -u ${USER_ID} -g ${GROUP_ID} -m -s /bin/bash builduser && \
    echo "builduser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/builduser

# 5. 切换到普通用户并设置工作目录
USER builduser
WORKDIR /workdir

image

构建 Docker 镜像

在刚才保存 Dockerfile 的目录下,打开终端,执行以下命令来构建镜像。 (这里使用了 (idu)(id -u) 和 (id -g) 自动获取你当前用户的 ID,传入容器中),命令最后有一个 . (点),代表使用当前目录的 Dockerfile

docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t rk3576-builder:22.04 .

如果显示权限问题,Docker 的后台服务(Daemon)默认是以 root 权限运行的。作为一个普通的系统用户,没有权限去和 Docker 的通信套接字(/var/run/docker.sock)直接对话 image

解决方法 把当前用户加入到 docker 用户组中,这是 Docker 官方推荐的“安装后配置”步骤

将当前用户加入 docker 组

sudo usermod -aG docker $USER

刷新用户组权限

newgrp docker

敲击下面这个命令,如果不加 sudo 也没有报错,就说明可以了

docker ps

image

重新构建Docker镜像 image

SDK准备

把OK3576用户资料中的源码文件和交叉编译工具链拷贝到Ubuntu中 image

可以通过FileZilla传 image image

在SDK目录解压

cat ok3576-linux-source.tar.bz2.0* > OK3576_ubuntu_source.tar.bz2

image

等待运行完成

tar -vxf OK3576_ubuntu_source.tar.bz2

image 解压完成,然后就可以把这几个文件删了ok3576-linux-source.tar.bz2* image

启动并进入编译容器

需要把SDK的目录“映射”(挂载)到容器里

docker run -it --rm -v /home/okay/文档/Linux/Forlinx_SDK/ok3576-linux-source:/workdir rk3576-builder:22.04 /bin/bash

看到下面这个信息说明已经在一个纯净的 Ubuntu 22.04 环境中了 image

编译SDK

该源码编译需要开发环境运行内存 18G 及以上,第一次要进行整体编译,后面可以根据实际情况单独编译

全编译

在SDK源码目录下执行下面命令,编译完成后,系统镜像会在output/update/Image/ 文件夹中生成update.img

./build.sh chip //设置环境变量 ,这里选择ok3576
./build.sh //进行全编译

第一次编译时会报错 image

提示我们需要下载rsync,我们直接在容器里执行

sudo apt-get update
sudo apt-get install rsync

安装完后再次运行编译命令就可以了,选择对应的板卡和系统 image

然后执行全编译命令,等待编译完成即可 image

编译到后面会报错,是因为当前正在尝试编译构建 Debian 12 (Bookworm) 版本的根文件系统(Rootfs)。但是,咱们目前使用的 Ubuntu 22.04 官方软件源里自带的 live-build 工具版本太老了,还不认识 Bookworm 这个新系统。 image

在当前的 Docker 容器终端里,手动从源码安装最新版的 live-build 为了防止污染你的源码目录,先退到 /tmp 目录去下载和安装,装完再回到代码目录。

# 1. 卸载掉系统里版本太老的 live-build
sudo apt-get remove -y live-build

# 2. 切换到临时目录
cd /tmp

# 3. 从 Debian 官方仓库拉取支持 Bookworm 的新版源码
# (注意:这里的 %20 是原厂脚本输出的,直接复制执行即可)
git clone https://salsa.debian.org/live-team/live-build.git --depth 1 -b debian/1%20230131

# 4. 进入源码目录并删掉可能引起编译错误的说明文档目录
cd live-build
rm -rf manpages/po/

# 5. 编译并安装新版 live-build
sudo make install -j8

# 6. 安装完成后,回到你的代码工作目录
cd /workdir

# 7.安装curl
sudo apt-get install -y curl

运行完上面的命令后重新执行编译命令编译代码 又报错了,这是因为“单纯编译内核(Kernel)不需要特权,但构建根文件系统(Rootfs)时,必须赋予最高级别的 —privileged 特权 普通的 Docker 容器出于安全限制,是绝对禁止在容器内执行 mount 挂载命令的,所以系统无情地拒绝了你,报了 permission denied image

解决 由于我们之前启动容器加了 —rm 参数,退出后容器会销毁,之前手动装的 rsync、curl 和新版 live-build 需要重新配置一下 先在终端输入exit退出Docker,回到Ubuntu20.04 加上超级特权重新启动容器

docker run -it --rm --privileged -v /home/okay/文档/Linux/Forlinx_SDK/ok3576-linux-source:/workdir rk3576-builder:22.04 /bin/bash

一键恢复之前装过的依赖 进入容器后直接把下面这整段代码一次性复制粘贴进去并回车,会自动把之前缺的工具全补齐

sudo apt-get update && \
sudo apt-get install -y rsync curl && \
sudo apt-get remove -y live-build && \
cd /tmp && \
git clone https://salsa.debian.org/live-team/live-build.git --depth 1 -b debian/1%20230131 && \
cd live-build && \
rm -rf manpages/po/ && \
sudo make install -j8 && \
cd /workdir

完成后再次编译

image

到目前为止,所有的分区镜像文件都已经构建完了,就差打包成update.img了

到最后构建的时候还会报错,原因是我们的Docker还缺少了一个环境依赖包

sudo apt-get update
sudo apt-get install -y bsdmainutils bsdextrautils

再次打包

./build.sh updateimg

打包成功 image

然后直接exit退出Docker,Ubuntu的SDK目录下就是编译出来的文件了 image

单独编译

下面是单独编译内核镜像

./build.sh chip  //设置环境变量 ,这里选择ok3576
./build.sh kernel      //编译内核

完美Docker

前面配置的Docker在编译过程中还会缺少很多环境依赖包和工具,下面是完美的Docker配置

Dockerfile

# 使用官方 Ubuntu 22.04 作为基础镜像
FROM ubuntu:22.04

# 避免在安装软件包时弹出交互对话框
ENV DEBIAN_FRONTEND=noninteractive

# 第一步:安装飞凌官方指定的依赖 + 我们踩坑发现的隐藏依赖
RUN apt-get update && apt-get install -y \
    build-essential libncurses5-dev ncurses-dev lzop net-tools \
    openssh-server vim git fakeroot libsqlite3-dev \
    ssh make gcc libssl-dev liblz4-tool expect expect-dev g++ \
    patchelf chrpath gawk texinfo diffstat binfmt-support \
    qemu-user-static live-build bison flex cmake gcc-multilib \
    g++-multilib unzip device-tree-compiler \
    libgucharmap-2-90-dev bzip2 expat gpgv2 cpp-aarch64-linux-gnu \
    libgmp-dev libmpc-dev bc python-is-python3 python2 \
    sudo locales tzdata cpio ca-certificates \
    rsync \
    curl \
    bsdmainutils bsdextrautils \
    && rm -rf /var/lib/apt/lists/*
    # 👆 上面新增了 rsync (防 check-sdk 报错), curl (防网络检查报错), 
    # bsdmainutils 和 bsdextrautils (提供 hexdump,防 rkImageMaker 报错)

# 第二步:提前在镜像里修复 live-build 版本过低不支持 Bookworm 的问题
RUN apt-get update && apt-get remove -y live-build && \
    cd /tmp && \
    git clone https://salsa.debian.org/live-team/live-build.git --depth 1 -b debian/1%20230131 && \
    cd live-build && \
    rm -rf manpages/po/ && \
    make install -j8 && \
    cd / && rm -rf /tmp/live-build && \
    rm -rf /var/lib/apt/lists/*

# 第三步:设置本地化字符集(防止 Python 脚本乱码)
RUN locale-gen en_US.UTF-8
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

# 第四步:接收宿主机用户的 UID 和 GID,避免编译产物变成 root 权限
ARG USER_ID=1000
ARG GROUP_ID=1000

RUN groupadd -g ${GROUP_ID} buildgroup && \
    useradd -u ${USER_ID} -g ${GROUP_ID} -m -s /bin/bash builduser && \
    echo "builduser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/builduser

# 切换到普通用户
USER builduser
WORKDIR /workdir

构建镜像

docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t rk3576-builder:ultimate .

启动Docker

docker run -it --rm --privileged -v /home/okay/文档/Linux/Forlinx_SDK/ok3576-linux-source:/workdir rk3576-builder:ultimate /bin/bash

这个Docker是通用的,不是只能编译Forlinx的SDK,其他的都可以,只不过其他的可能需要安装其他额外的依赖,直接在Docker里面安装就行了,只不过每次退出再进来要重新安装,不想那么麻烦的话可以固定在Dockerfile里

评论

Cover
晴天 周杰伦
OKayFlow 正在共享键鼠中... 将鼠标向左大跨度甩回,或在主电脑上按 Scroll Lock 键强制退出
OKayFlow
工具箱

工具箱