您的位置 首页 数字

运用 Docker 构建 PetaLinux 开发环境

0. 背景0.1 PetaLinux 是什么PetaLinux 是 Xilinx 推出的用于在其自家 SoC 上构建嵌入式 Linux 的一套工具集,集成了编译、调试、仿真等众多工具。0.2

0. 布景

0.1 PetaLinux 是什么

PetaLinux 是 Xilinx 推出的用于在其自家 SoC 上构建嵌入式 Linux 的一套东西集,集成了编译、调试、仿真等许多东西。

0.2 原有的树立 PetaLinux 开发环境的办法有什么问题

实验室的项目依据 Xilinx 的 Zynq 系列 SoC 开发,需求运用 PetaLinux 构建嵌入式 Linux 体系,榜首步便是树立开发环境。团队成员平常的主力体系是 Windows,运用虚拟机的办法树立 Linux 开发环境。树立开发环境呈现困难,或为节省时刻的意图时会从其他成员那里仿制树立好环境的虚拟机。这些办法已发生或或许发生的问题能够总结如下:

1. 装置开发环境的依靠稍显杂乱,且依据操作体系不同而异,新手不易搞定。装置进程没有被很好的文档化,团队成员重复劳动显着。

2. 共同操作体系版别困难。开发人员(现有成员、未来加入成员、项目其他团队的成员)或许运用着不同的 Linux 发行版和版别,由于他们或许有不同的喜爱,版别上喜爱尝鲜或保守,在既有体系上现已有随手的开发东西和设置等等。而当咱们期望共同开发环境或自行树立失利时,往往挑选仿制整个虚拟机镜像。

3. 运用仿制整个虚拟机的办法传递开发环境不行灵敏。体现为:

运用了一段时刻后的虚拟机巨细或许动辄四五十个 GB,仿制时刻长,难以经过网络同享。

为保存可回退的环境,或许为虚拟机增加快照,但这会进一步明显增加虚拟机的体积。

传递虚拟机不只传递了需求的开发环境,还传递了许多无用的软件和个人设置,难以统筹不同开发者之间的习气差异。

关于不同项目、用处或许存在多个虚拟机,资源冗余很大。

4. 运用虚拟机功用体现差。主机装备不高时,运用虚拟机(或许会再虚拟机内运转 IDE 等其他开发东西)会常常卡顿,降低了开发功率。

5. 运用为某一开发环境而仿制来的虚拟机,迁就其环境不肯再装置适宜的开发东西(如 IDE 等)。

0.3 依据 Docker 的处理计划

Docker 作为在许多场景下虚拟机的代替计划备受瞩目,其资源耗费小、为单一运用装备环境、易于经过网络同享等特色很好的处理了上面说到的许多问题。经过 Docker 来构建 PetaLinux 开发环境,咱们能够取得以下优势:

经过紧缩的镜像体积只要 1GB 左右,便利网络传输。

很简单再团队中共同开发环境,包括操作体系和各种库。Docker 镜像的只读特性确保了有一个可回退的共同环境。

开发环境中的依靠被 Dockerfile 明晰、清晰的记录下来,具有很好的文档效应,便利团队长时刻同享和保护。

Docker 能够运转在之前的虚拟机的操作体系上,也能够运转在一个“精简”的操作体系上(如 Docker for Windows 的办法),还能够放到服务器上,运转多个容器供团队成员运用。这使得运用 Linux 环境的办法愈加多样、灵敏,且能削减虚拟机功用原因带来的影响

现在抱负很饱满,但实际中还需求经过一番探求和实验,下面就让咱们开端。

1. 构建 Docker 镜像

Docker 的优势就在于咱们能够运用“代码”来表明需求的环境,它既能描绘环境,也能直接辅导生成环境,这份“代码”便是 Dockerfile。下面详细的记叙了这份 Dockerfile 的每一部分,进程中遇到的问题、处理办法、留意事项等。关于 Dockerfile,能够参阅官方的 Dockerfile reference1,以及 Best practices for writing Dockerfiles2。

1.1 设置构建参数

Dockerfile 中答应运用 ARG 指令设置构建时参数,这些参数在 Dockerfile 中具有默许值,在构建时能够经过 –build-arg 参数指定新的值来掩盖默许值。这些参数能够在 Dockerfile 中被引证(引证办法与在 shell 中引证变量相同),但不会呈现在终究的镜像里。留意一条 ARG 指令只能指定一个参数,这一点和 ENV 指令是不同的。这儿我设置了两个参数如下:

ARG install_dir=/opt

ARG installer_url=172.17.0.1:8000

其间 install_dir 用来指定 PetaLinux 的装置途径,installer_url 用来指定 PetaLinux 装置包的网络地址。假如装置包在互联网上,则这儿是一个拜访链接,假如装置包在本地,则这儿被指定为 Docker 的默许网桥,经过它联通本地网络服务器和构建时的暂时容器。关于这一部分,我会在后边胪陈。

1.2 设置环境变量

通常状况下,PetaLinux 运用一个设置脚原本增加自身的各项东西到环境变量中,在运用相关东西前需求经过 source /settings.sh 来履行脚本。但现在我要制造一个专归于 PetaLinux 的环境,完全能够把环境变量设置好来免除这个进程。在 Dockerfile 中运用 ENV 指令来设置环境变量:

ENV PETALINUX_VER=2014.4

PETALINUX=${install_dir}/petalinux-v2014.4-final

ENV PATH=${PETALINUX}/tools/linux-i386/arm-xilinx-gnueabi/bin:

${PETALINUX}/tools/linux-i386/arm-xilinx-linux-gnueabi/bin:

${PETALINUX}/tools/linux-i386/microblaze-xilinx-elf/bin:

${PETALINUX}/tools/linux-i386/microblazeel-xilinx-linux-gnu/bin:

${PETALINUX}/tools/linux-i386/petalinux/bin:

${PETALINUX}/tools/common/petalinux/bin:

${PATH}

这儿有两点需求留意。一是 ENV 尽管支撑并引荐在一条指令下设置多个环境变量,但假如这些环境变量之间存在彼此引证的状况,就在分隔写了。比方这儿设置 PATH 变量时引证了 PETALINUX 变量,它们就不能在同一个 ENV 指令下进行设置了。二是 PATH 这个变量中每个途径之间不能够有空格,不然是查找不到可履行文件的,所以这儿也只能不管缩进来确保没有空格了。网络上好像没有什么处理这个问题的评论,并且在 ENV 指令下咱们无法运用任何其他的东西去处理这个字符串。

咱们其实也能够把 PetaLinux 供给的 settings.sh 脚本增加到 .bashrc 文件中,使得其每次被主动履行。实际上这个脚本中除了装备环境变量,终究还运转了 PetaLinux 自带的一个环境查看东西,用于查看网络、磁盘剩下空间等信息,运用前述设置环境变量的办法就疏忽这个查看东西了。

1.3 装置依靠

在 PetaLinux 的参阅攻略3中给出了它所依靠的东西和库,但是并不全面和精确。一是由于有些包现已被代替,现在无法取得4;二是关于 32 位库支撑5仅仅一笔带过,并未详细列出;三是有的包或许因十分根底而未列出,但是在 Docker 的根底镜像中却没有包括,如 bc。以下是我测验成功的、在当时根底镜像下需求的一切依靠:

RUN dpkg –add-architecture i386

apt-get update apt-get install -y –no-install-recommends

# Required tools and libraries of Petalinux.

# See in: ug1144-petalinux-tools-reference-guide, v2014.4.

tofrodos

iproute

gawk

gcc-4.7

git-core

make

net-tools

rsync

wget

tftpd-hpa

zlib1g-dev

flex

bison

bc

lib32z1

lib32gcc1

libncurses5-dev

libncursesw5-dev

libncursesw5:i386

libncurses5:i386

libbz2-1.0:i386

libc6:i386

libstdc++6:i386

libselinux1

libselinux1:i386

# Using expect to install Petalinux automatically.

expect

rm -rf /var/lib/apt/lists/* /tmp/*

ln -fs gcc-4.7 /usr/bin/gcc

ln -fs gcc-ar-4.7 /usr/bin/gcc-ar

ln -fs gcc-nm-4.7 /usr/bin/gcc-nm

ln -fs gcc-ranlib-4.7 /usr/bin/gcc-ranlib

这儿咱们运用 –no-install-recommends 参数来防止装置不用要的包,并在装置完毕后整理 /var/lib/apt/lists/ 和 /tmp/ 目录,以尽或许的使镜像精简。

由于在 Ubuntu 16.04 上装置 GCC 会默许装置 gcc 5 的版别,而 2014.4 版别的 PetaLinux 应该没有适配 gcc 5,会呈现许多正告。这儿采纳的办法是装置 gcc-4.7,并修正符号链接,使 /usr/bin/gcc 指向这一版别的 GCC。事实上我并不切当知道应该装置哪个版别,在 PetaLinux 2016.4 中指定了运用 gcc 4.8。这儿影响应该不大,由于真实用于构建项意图穿插编译器是 PetaLinux 自带的。

在网上查找时发现,一般材料都没有介绍怎么直接更改一个软衔接的指向。不知道的状况下,就只能先删去再重建这个链接了。终究仍是在 Stack Overflow 上找到了答案,其实咱们能够运用 -f 选项在一条指令中更改软衔接的指向。这个技巧在后边还会用到。

1.4 运用 expect 脚本主动装置 PetaLinux

PetaLinux 的装置包在装置进程中会显现许可证协议,并要求用户输入承认信息。这样的交互办法给咱们的主动化处理造成了一点小困难,但是程序员长辈们肯定是不答应这种不能主动化的状况继续的,expect 这个东西便是专门用来主动处理这种需求交互输入的状况的。expect 常常用来处理 SSH 登陆等需求交互输入密钥的状况,它会监督一个程序的输出,并在捕获到了特定的输出后给出一个预设的输入。这儿咱们运用一个 auto-install.sh 脚原本主动装置 PetaLinux,脚本的内容如下:

#!/usr/bin/env expect

set timeout -1

set install_dir [lindex $argv 0]

spawn ./petalinux-v2014.4-final-installer.run $install_dir

expect Press Enter to display the license agreements

send r

expect *>*

send yr

expect *>*

send yr

expect eof

榜首行声明运用 expect 这个东西来解说此脚本,/usr/bin/env 会遍历 PATH 变量来寻觅后边的可履行文件,这样防止了依靠于 expect 的装置途径。

第二行设置等候超时,由于 PetaLinux 的装置进程比较慢,这儿将其设为 -1,即一向等候。

第三行设置一个变量来接纳此脚本的参数,咱们借此来指定期望将 PetaLinux 装置到哪个目录下。留意 expect 脚本设置参数的办法和 bash 脚本不同,参数 0 代表咱们调用脚本时给出的榜首个参数,而在 bash 脚本中,参数 0 代表脚本自身的姓名。

第五行用 spawn 指令去履行装置程序。PetaLinux 的装置程序的榜首个参数也是装置途径。

接下来咱们用 expext 指令来捕获程序的输出,用 send 指令发送预设的输入。装置程序提示你承认协议的句子是这样的:Do you accept this license? [y/N] >,直接用 expext 匹配这一句会有问题,由于至少 [] 在 expect 的语法中是有特定含义的,需求转义。已无心境研讨 expect 那古怪的语法,所幸它有很棒的含糊匹配功用,咱们只需求匹配终究一个 > 字符就能够了。

1.5 减小镜像体积

PetaLinux 的装置包在 Xilinx 官方网站上能够下载,但需求先注册,没有固定的下载链接。所以要么需求在构建前把它下载到本地,要么在互联网上寻觅一个适宜的保管地址,能够供给安稳的下载链接。

PetaLinux 的装置包比较大(2014.4 版有 1.2GB,而 2016.4 现已到了丧尽天良的 8.3 GB),在装置完结后,装置包再留在镜像中现已没有什么含义了,还会明显的增加镜像的体积。这儿要了解 Docker 的镜像是由一个个的层(layer)组成的,Dockerfile 中的每一条指令都对应于一层,每一层都是在前一层的根底上进行的增量的改动。这意味着,一旦咱们在某一层中引入了一个文件,即便鄙人一层中将其删去,对体积的减小也杯水车薪,咱们仅仅无法在终究的容器中“看见”它们罢了。假如咱们运用 COPY 指令将 PetaLinux 的装置包增加进去,则 COPY 指令会生成一个层,咱们无法再把它发生的体积抹除去。Stack Overflow 上有一个关于这个问题的评论6,首要说到了三种办法:一是在本地构建一个网络服务器,经过网络的办法传到 Docker 容器的内部,我采用了这种办法,后边胪陈;二是不能运用 Dockerfile 的办法构建容器,而是在容器中完结装置和整理作业后手动提交更改到镜像;三是运用第三方东西对生成的镜像进行再紧缩。

这儿运用网络是更好的办法,一方面假如咱们在互联网或许私有服务器上存放了装置包,经过更改 installer_url 变量就能够运用新的地址获取文件;另一方面,在本地能够运用 Python 轻松的创立一个 HTTP 服务器。在 Dockerfile 中,咱们运用 wget 下载装置包、装备其权限、运转主动装置脚本,终究删去装置包。这些进程必须在一个 RUN 指令下完结,这样装置包才不会留在终究的镜像里。

WORKDIR $install_dir

COPY ./auto-install.sh .

RUN wget -q $installer_url/petalinux-v2014.4-final-installer.run

chmod a+x petalinux-v2014.4-final-installer.run

./auto-install.sh $install_dir

rm -rf petalinux-v2014.4-final-installer.run

在外部,我运用了一个脚原本封装发动 HTTP 服务器、构建 Docker 镜像、中止服务器的进程:

#!/usr/bin/env bash

installer_dir=$1

docker_context=`pwd`

echo Start to build petalinux tools docker image …

echo ———————————————–

cd $installer_dir

python3 -m http.server

server_pid=$!

cd $docker_context

installer_ip=`ifconfig docker0 | grep ‘inets’ | awk ‘{print $2}’`

docker build -t petalinux-docker:2014.4

–build-arg installer_url=${installer_ip}:8000

.

kill $server_pid

echo —————

echo Finish. ^_^

echo —————

这个脚本的榜首个参数是装置包在本地的途径。首先让服务器在后台树立,并记录下其对应的 pid,在完结镜像的构建后再将其杀死。Python 创立的服务器会默许监听 8000 端口。在容器内部(Docker 构建的进程即相当于在暂时的容器中履行 Dockerfile 的进程)能够经过 Docker 的默许网桥(docker0)的 IP 地址来拜访本地主机。网桥对应的 IP 地址并不是仅有的,Docker 是依据主机中网卡的装备不同,挑选一个没有被占用的私有网段(假如 3 类私有 IP 网段都被占用了,Docker 发动时会报错),也能够自行更改,所以这儿咱们从 ifconfig 的输出中提取 docker0 对应得 IP 地址。docker build 指令中 -t 参数为镜像指定标签,–build-arg 参数用来掩盖咱们在 Dockerfile 内部设置的参数,终究一个参数 . 指的是构建环境(build context)为当时途径。留意,假如你将装置包放在了这个构建环境的同一个目录下,一定要经过 .dockerignore 文件来疏忽这个装置包文件,由于不然它会被发送到 Docker daemon 上,增加构建时刻且毫无用处,除非你要运用 COPY 指令的办法导入装置包。

1.6 其他

PetaLinux 会查看 shell 环境,并引荐运用 Bash。在 Ubuntu:16.04 的镜像中 /bin/sh 这个软衔接指向的是 /bin/dash,这儿咱们将其更改为 /bin/bash。

RUN ln -fs /bin/bash /bin/sh # bash is PetaLinux recommended shell

运用 WORKDIR 指令新建了一个 /workspace 的途径用于衔接数据卷。终究一个 WORKDIR 指定的途径就会是进入容器后的地点途径,这一点好像官方文档没有明说。

WORKDIR /workspac

1.7 镜像的构建

假如装置包放在本地,则如 1.5 节所述,运用 build-image.sh 脚本构建镜像。假如装置包在互联网或本地服务器上,则直接运用 docker build 指令,并运用 installer_url 参数指定拜访地址。

2. 测验

你能够自行依照上面的办法自行构建镜像,也能够从 Docker Hub 上下载我上传好的镜像:

docker pull xaljer/petalinux:2014.4

运转容器:

docker run -ti -v /path/to/projects:/workspace xaljer/petalinux:2014.4

在容器中创立工程并编译:

petalinux-create -t project -s

-n

cd

petalinux-build # 构建整个工程,会比较慢

3. 现有问题和下一步作业

3.1 现有问题

PetaLinux 2014.4 支撑的原本是 Ubuntu 14.04,但运用此版别的镜像时发现,其软件源好像有些问题,常常装置失利,故没有运用。

PetaLinux 会提示找不到 tftp,这是由于没有对其进行进一步的装备。假如不运用 tftp 能够疏忽这个问题。

在 Docker for Windows 下构建时,或许会呈现过错7,将存储驱动更改为 aufs 后可修正。但是 Windows 下构建的镜像仍有其他问题,无法运用,作者没有对其作更多的测验和探求。

3.2 下一步作业

增加 Vivado SDK 的一些东西。

PetaLinux 东西的姓名都有点长,能够考虑在镜像里对常用的操作增加别号。但在容器外部作或许会更便利一些,由于咱们不用交互式的进入容器,而是运用 docker exec 来履行指令,此刻能够在容器外面为整个指令增加别号。

有了标准化环境,不只能够在自己的电脑上运转,还期望放在私有服务器上,让咱们经过网络拜访。要到达这样的意图,一要能经过 SSH 拜访容器,二要能在服务器的数据卷和本地计算机之间同步数据(源码及编译成果)。关于 SSH,开始想象能够经过外部的一些 Docker 东西来完结,而不是在容器内部树立 SSH 服务器,由于有多个容器时,要对应多个不同端口等问题。关于数据同步,能够在本地的 Windows 体系上经过 Linux 子体系(WSL)树立 NFS 服务器,在容器内部挂载 NFS,或许经过 Docker 的插件完成直接将远端的 NFS 作为数据卷挂载。

4. 总结

假如并不需求 Docker 的一些优势,咱们也能够考虑将 PetaLinux 装进 Windows 的 Linux 子体系(WSL),这样能够有更好的功用和更无缝的操作。

运用虚拟机在 Windows 下树立嵌入式开发环境是以往十分常用的办法,但也是一种比较粗笨的办法。跟着一些新的技能、渠道的呈现,如 Docker 和 WSL,咱们能够测验使用它们树立开发环境,提高开发的功率。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/shuzi/156868.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部