Hi35xxVxxx 开发环境用户指南
前言
本文档介绍Linux开发环境。Linux开发环境的搭建、U-Boot、Linux内核、根文件系统以及内核和根文件系统的烧写,以及创建网络开发环境和如何启动Linux开发应用程序。
本文档主要提供让客户更快地了解Linux开发环境指导。
说明:
本文以musl库工具链arm-v01c02-linux-musleabi-gcc描述为例。 Hi3516CV610/Hi3516CV608/Hi3511CV100 只支持 musl 工具链。 Hi3511CV100只支持SPI NAND和SPI NOR作为启动介质。 Hi3511CV100不支持optee。
与本文档相对应的产品版本如下。
本文档(本指南)主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
开发环境
嵌入式开发环境
由于嵌入式单板的资源有限,不能在单板上运行开发和调试工具,通常需要交叉编译调试的方式进行开发和调试,即“宿主机+目标机(评估板)”的形式。宿主机和目标机一般采用串口连接,也可同时通过网口或者JTAG连接,如图1所示。
宿主机和目标机的处理器一般不相同。宿主机需要建立适合于目标机的交叉编译环境。程序在宿主机上经过“编译-连接-定位”得到可执行文件。通过一定的方法将可执行文件烧写到目标机中,然后在目标机上运行。
目标机上的Bootloader启动后,目标机中的操作信息通过串口或者网口输出到宿主机上显示。在宿主机上的控制台中输入命令,可以控制目标机。

开发环境
SDK 开发环境通常包括Linux服务器、Windows工作台和单板,三者同处于一个网络中,如图1所示。

在Linux服务器上建立交叉编译环境,Windows工作台通过串口和网口与单板连接,开发人员可以在Windows工作台中进行程序开发或者远程登录到Linux服务器进行程序开发。各部分具体软件介绍如表1所示。
说明:
开发环境中使用了Windows工作台,实际上很多工作也可以在Linux服务器上完成,如使用minicom代替超级终端等,用户可自行选择。
表 1 开发环境的各部分软件描述
无特别要求,可为Ubuntu、Redhat、Debian等。内核版本支持2.6.18及以上版本。安装时建议选择完全安装。 |
||
NFS、telnetd、samba、vim、编译环境(GCC版本4.9.3及以上)、arm交叉编译环境(GCC版本12.3.1)等。 |
||
Linux:Linux内核基于Linux标准内核5.10.y版本移植开发,根文件系统基于busybox 1.34.1版本制作而成。 |
||
Linux开发环境搭建可以选择使用docker容器或者非docker容器两种方式,非docker方式需要手动安装所有工具软件,因此建议优先使用docker容器搭建开发环境。
搭建开发环境:docker
docker方式环境搭建请参考文档《使用docker容器搭建开发环境用户指南》,非docker方式请参考“搭建开发环境:非docker”章节。
搭建开发环境:非docker
推荐用户使用64位Linux服务器,本开发包在32位Linux服务器、较老版本的Linux服务器、偏冷门的Linux服务器上可能存在未知的兼容性问题。
推荐的硬件配置如下:
- CPU Intel(R) Xeon(R) CPU E5-2450 @ 2.10GHz 或更好CPU
- DDR: >= 16GB
- Hard disk >= 600GB
- Gigabit Ethernet
-
OS: Ubuntu 22.04 LTS
发布包使用的Linux Server版本
本示例安装如下版本Linux系统(英文版),本开发包默认均以此Linux系统进行编译:
说明:
ubuntu系统安装步骤略。
网络环境搭建
请用户自行配置网络,并按需安装nfs,samba,ssh等网络组件。
软件包安装
操作系统安装好后,且用户已自行配置好网络环境,则可继续如下步骤完成相关软件包的安装。
-
配置默认使用bash
执行 sudo dpkg-reconfigure dash 选择 no
-
更新 ubuntu 系统索引信息
执行 sudo apt update
-
安装软件包
执行:sudo apt-get install 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 python3-pip wget libmpc-dev mtd-utils zlib1g genromfs
-
创建/etc/ld.so.preload 文件,并执行echo "" > /etc/ld.so.preload,以解决64bit linux server上某些第三方库编译失败的问题。
-
SDK开源组件依赖以下几个库,以ubuntu为例,安装方式请参考下面命令:
由于mtd-utils通过pkg-config工具检查各个库是否正常安装,因此请参考如下方式设置pkg-config工具搜索路径:
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/x86_64-linux-gnu/pkgconfig"
-
SDK开源组件e2fsprogs依赖texlive库,安装方式请参考如下命令:
-
SDK开源组件optee 模块依赖 python3.x.x、pip3、wheel、pycryptodome、pyelftools库
下载安装并执行如下指令:
# 如果以下pip3安装组件操作存在下载异常,可能需要配置下载源:先创建: mkdir ~/.pip,然后编辑:vim ~/.pip/pip.conf,若环境没有vim编辑器,请先安装:sudo apt-get install vim sudo pip3 install wheel sudo pip3 install pycryptodome sudo pip3 install pyelftools sudo pip3 install cryptography创建python软链接
备注:pycryptodome 依赖于python3.x.x 环境请先升级至python3.x.x 版本再安装 pycryptodome 库。
说明: (1) 安装软件包前配置下载源或代理的步骤省略。 (2) 若步骤7中安装cryptography失败,可能是pip版本低导致,可以尝试按照告警提示升级pip包:pip3 install --upgrade pip ,然后再安装一次cryptography。 (3) 以上“apt-get install”所安装软件包版本建议与“附录:非docker镜像软件清单”中软件版本保持一致,否则可能存在兼容性问题,具体可通过“sudo apt-get install [软件包名]=[软件包版本]”指定安装版本操作。 (4) openssl 支持国密规格需使用 openssl-3.0.2 及以上版本. 如果版本不匹配,请从 https://www.openssl.org/ 下载并安装 openssl 3.0.2 版本。
-
检查以上软件包是否安装成功
请使用安装检测脚本检测以上工具是否安装成功,检测脚本位置位于SDK版本包scripts目录:scripts/installed_package_check.sh;请注意,该脚本适用于Ubuntu环境。
安装交叉编译工具
须知:
使用从网络等渠道得到的交叉编译工具可能存在与使用的内核并不配套,造成开发过程中出现一些不可预料的问题。
发布包提供编译工具链arm-v01c02-linux-musleabi- 。arm-v01c02-linux-musleabi-为基于32bit操作系统musl的工具链。
安装步骤如下:
-
解压工具链。
执行如下命令进行解压:
-
安装工具链。
运行如下命令,即可完成此工具链的安装。
其它工具链安装方法与上述描述类似。
U-Boot
关于U-Boot的介绍与使用请参见《Hi35xxVxxx U-boot 移植应用开发指南》。
Linux内核
内核源代码
由于开源工具整改,部分开源工具不再提供源码包,内核源码需要自行下载。
配置并编译内核
须知:
如果对内核和芯片平台没有足够了解,请勿修改默认配置。但可增加需要的模块,下面步骤以musl库工具链编译spi flash内核为例,若需编译其他介质内核,请参考boards/dmeb路径下的readme。
配置并编译内核的操作步骤如下:
- 进入third_party/linux目录
-
下载Linux内核源码(可以选择手动下载到third_party/linux 目录):
在 https://mirrors.edge.kernel.org/pub/linux/kernel 下载对应版本 Linux Kernel 源码
-
进入boards/dmeb路径下执行:
根文件系统
根文件系统简介
Linux的目录结构的最顶层是一个被称为“/”的根目录。系统加载Linux内核之后,就会挂载一个设备到根目录上。存在于这个设备中的文件系统被称为根文件系统。所有的系统命令、系统配置以及其他文件系统的挂载点都位于这个根文件系统中。
根文件系统通常存放于内存和Flash中,或是基于网络的文件系统。根文件系统中存放了嵌入式系统使用的所有应用程序、库以及其他需要用到的服务。图1列出了根文件系统的顶层目录。

通用的Linux系统的根文件系统中会包括根文件系统顶层目录结构图中所有的目录,不过在嵌入式系统中,需要精简根文件系统。部分可以被忽略的目录如表1所示。
表 1 嵌入式系统中可忽略的目录说明
/boot目录一般用于存放内核映像,PC机启动时一般会从该位置加载内核,但在嵌入式系统中,为了节省空间,内核映像存在于Flash或网络服务器中,而不是在根文件系统中。因此也可以忽略这个目录。 |
说明:
空目录并不会增大文件系统的体积,如果没有特殊原因,建议保留这些目录。
利用busybox制作根文件系统
利用busybox制作根文件系统需要先获取busybox源代码,然后配置、编译和安装busybox,操作成功后开始制作根文件系统。
获取busybox源代码
成功安装SDK后,busybox源代码补丁就存放在third_party/busybox目录中。要获取busybox源代码也可以从网站https://busybox.net/下载。
配置busybox
进入busybox所在目录,进行配置操作需要输入如下命令:
cd third_party/busybox/busybox-1.34.1
cp ../../../boards/dmeb/tools/build_scripts/busybox/config_arm_a7_softfp_neon .config //指定配置文件
make menuconfig
busybox的配置界面和内核配置相似,其功能选项容易理解,可以根据自己的需求选择配置。
在 Settings ---> Build Options中注意此选项:CONFIG_CROSS_COMPILER_PREFIX选项用于选择SDK推荐的交叉编译器,配置好后保存并退出。欲了解busybox各选项含义请参考busybox配置帮助。
--- Build Options
[ ] Build static binary (no shared libs)
[ ] Build position independent executable
[ ] Force NOMMU build
[ ] Build shared libbusybox
(arm-v01c02-linux-musleabi-) Cross compiler prefix
() Path to sysroot
编译和安装busybox
编译和安装busybox的具体操作如下:
编译并安装成功后,在busybox-1.34.1的_install目录下生成以下文件:
drwxrwxr-x 2 xxx XXX 4096 Feb 13 11:41 bin
lrwxrwxrwx 1 xxx XXX 11 Feb 13 11:41 linuxrc -> bin/busybox
drwxrwxr-x 2 xxx XXX 4096 Feb 13 11:41 sbin
drwxrwxr-x 4 xxx XXX 4096 Feb 13 11:41 usr
其中xxx表示用户;XXX表示组。
制作根文件系统
成功安装SDK后,在boards/dmeb/pub/目录中存放已制作好的根文件系统。
用户如有需要可在busybox的基础上制作根文件系统,操作步骤如下。
-
创建文件夹,拷贝相应工具。
- 创建rootbox目录;
- 将third_party/busybox/busybox-1.34.1/_install/路径下的所有文件拷贝到rootbox;
- 在rootbox中创建目录:etc dev lib tmp var mnt home proc。
-
配置etc、lib、dev目录的必需文件。
- etc目录可参考系统/etc下的文件。其中最主要的文件包括inittab、fstab、init.d/rcS文件等,这些文件最好从busybox的examples目录下拷贝过来,根据需要自行修改。
- dev目录下的设备文件,可以直接从系统中拷贝过来或者使用mknod命令生成需要的设备文件。拷贝文件时请使用cp -r file。
- lib目录是存放应用程序所需要的库文件,请根据应用程序需要拷贝相应的库文件。
完成以上两个步骤,一个完整的根文件系统就生成了。
说明: SDK软件包中已经包括配置好的完整的根文件系统,如果无特别需求,可直接使用。要添加自己开发的应用程序,只需将应用程序和相应的库文件拷贝到根文件系统的对应目录即可。
须知: - 为了便于调试,默认发布的版本中没有设置root密码;
- 为了保证系统安全,请客户在产品中自行设置root密码。
文件系统简介
嵌入式系统中常用文件系统包括有cramfs、jffs2、NFS、initrd、ext4以及squashfs、ubifs。它们的特点如下:
- cramfs和jffs2具有好的空间特性,很适合嵌入式产品应用。
- squashfs压缩率最高。
- jffs2为可读写文件系统。
- NFS文件系统适用于开发初期的调试阶段。
- initrd采用cramfs文件系统,为只读。
-
ext4文件系统用于eMMC卡。
cramfs
cramfs是针对Linux内核2.4及之后的版本所设计的一种新型文件系统,使用简单,加载容易,速度快。
cramfs的优缺点如下:
- 优点:将文件数据以压缩形式存储,在需要运行时进行解压缩,能节省Flash存储空间。
- 缺点:由于它存储的文件是压缩的格式,所以文件系统不能直接在Flash上运行。同时,文件系统运行时需要解压数据并拷贝至内存中,在一定程度上降低读取效率。另外cramfs文件系统是只读的。
如果想要在单板运行的Linux中提供cramfs的能力,必须要在编译内核时把cramfs的选项加入。在make menuconfig后,进入“File systems”,选择“Miscellaneous filesystems”,最后选中其中的“Compressed ROM file system support (cramfs)”(SDK里面提供的内核默认已经选择了该文件系统的支持)。
在boards/dmeb目录下编译完成后,在boards/dmeb/pub目录下将会生成rootfs的压缩包rootfs_musl_arm.tgz。解压后,解压该压缩包得到 rootfs_musl_arm 目录,使用rootfs_musl_arm 下的mkimg.rootfs工具制作cramfs或cramfs-initrd。
# ./mkimg.rootfs [文件系统源文件目录] [文件系统镜像目标文件目录] [文件系统镜像文件名] [文件系统类型]
./mkimg.rootfs . .. test cramfs-initrd
mv ../test.cramfs.initrd ../cramfs.initrd.img
执行上述命令后,在上级目录下将生成一个cramfs.initrd.img镜像文件。该镜像文件即为所需的文件系统镜像文件。
jffs2
jffs2是RedHat的David Woodhouse在jffs基础上改进的文件系统,是用于微型嵌入式设备的原始闪存芯片的实际文件系统。jffs2文件系统是日志结构化的可读写的文件系统。
jffs2的优缺点如下:
- 优点:使用了压缩的文件格式。最重要的特性是可读写操作。
- 缺点:jffs2文件系统挂载时需要扫描整个jffs2文件系统,因此当jffs2文件系统分区增大时,挂载时间也会相应的变长。使用jffs2格式可能带来少量的Flash空间的浪费。这主要是由于日志文件的过度开销和用于回收系统的无用存储单元,浪费的空间大小大致是若干个数据段。jffs2的另一缺点是当文件系统已满或接近满时,jffs2运行速度会迅速降低。这是因为垃圾收集的问题。
加载jffs2文件系统时的步骤如下:
- 扫描整个芯片,对日志节点进行校验,并且将日志节点全部装入内存缓存。
- 对所有日志节点进行整理,抽取有效的节点并整理出文件目录信息。
- 找出文件系统中无效节点并且将它们删除。
-
最后整理内存中的信息,将加载到缓存中的无效节点释放。
由此可以看出虽然这样能有效地提高系统的可靠性,但是在一定程度上降低了系统的速度。尤其对于较大的闪存芯片,加载过程会更慢。
为了使内核支持jffs2文件系统,必须在编译内核时加入jffs2的选项。在make menuconfig后,进入“File systems”,选择“Miscellaneous filesystems”,最后选中其中的“Journalling Flash File System v2 (JFFS2) support”选项(SDK里面提供的内核默认已经选择了该文件系统的支持)。
jffs2的制作方法为:
其中,mkfs.jffs2工具可以从互联网中下载,也可以在SDK包中找到。rootbox为之前已经制作好的根文件系统。参数说明如表1所示。
表 1 JFFS2参数表
Ubifs
ubifs是unsorted block images file system的简称,用于raw flash设备。ubifs通过ubi子系统处理与mtd设备之间动作。ubifs只能工作于ubi volume之上。ubifs涉及到的系统层次由下到上依次是:
- mtd 子系统:提供对flash 的访问接口;
- ubi 子系统:为flash device提供了wear-leveling和 volume management功能,ubi子系统工作在mtd设备之上,提供了ubi volume;ubi子系统是mtd设备的高层次表示,对上层屏蔽了一些直接使用mtd设备需要处理的问题,比如wearing-leveling以及坏块管理;ubifs 本身则工作在ubi子系统之上。
ubifs 具有如下优缺点:
-
优点:
- ubifs对flash 尺寸有着很好的扩展性;
- 回写(write-back):同jffs2的write-through(立即写入)相比可以显著的提高文件系统的读写性能。
- 异常unmount适应度:ubifs是一个日志文件系统可以容忍突然掉电以及unclean重启。
- on-the-fly compression存储在flash介质上的数据是压缩的,同时也可以灵活的针对单个文件来打开关闭压缩。
- ubifs可以从index破坏后恢复:ubifs中的每一片信息都用一个header来描述,因此可以通过扫描整个flash介质来重构文件系统
- 完整性:ubifs通过把checksum写到flash 介质上来保证数据的完整性,文件数据或meta-data不会损坏;缺省的情况,ubifs仅仅检查meta-data的CRC 校验。
-
缺点:
- ubifs文件系统所有数据结构都是使用tree,ubifs对flash尺寸大小在算法上是可扩展的。但是ubi子系统复杂度随着flash size线性增长,因此ubi子系统加ubifs整体上是线性增大的。
- 制作ubifs 步骤可参考boards/dmeb/tools/pc/ubi_sh/mkubiimg.sh 脚本以及readme 文档。
Initrd
initrd相当于存储介质,它支持的文件系统格式有ext2、cramfs等,因此内核除了支持initrd之外,还要支持cramfs文件系统。内核需要做如下配置,initrd才可以正常工作:
- 进入“Device Drivers->Block devices”,选择支持“RAM block device support”。
- 进入“General setup”,选择支持“Initial RAM filesystem and RAM disk (initramfs/initrd) support”。
- 进入“File systems”,选择“Miscellaneous filesystems”,最后选中其中的“Compressed ROM file system support (cramfs)”。
制作initrd的步骤如下:
- 制作cramfs镜像文件,具体制作方法请参见“cramfs”。
- 以步骤1制作的镜像文件作为输入,制作initrd文件,制作命令为“mkimage -A arm -T ramdisk -C none -a 0 -e 0 -n cramfs-initrd -d ./cramfs-image cramfs-initrd”。
Squashfs
squashfs文件系统是一套基于Linux内核使用的压缩只读文件系统,压缩率高。
squashfs具有如下特点:
- 数据(data)、节点(inode)和目录(directories)都被压缩
- 保存了全部的 32 位 UID/GIDs和文件的创建时间
- 最大支持4GB文件系统
- 检测并删除重复文件
使用squashfs文件系统步骤:
-
配置支持squashfs的内核镜像。进入linux-5.10.y目录下,执行以下命令:
cp arch/arm/configs/hi35xxvxxx_defconfig .config make ARCH=arm CROSS_COMPILE=arm-v01c02-linux-musleabi- menuconfig(保存退出即可) 打开支持xz压缩算法选项,或其他需要支持的压缩算法选项: File systems ---> [*] Miscellaneous filesystems ---> <*> SquashFS 4.0 - Squashed file system support [*] Include support for XZ compressed file systems -
参考boards/dmeb路径下的readme中单独编译内核步骤。
-
先在服务器上安装squashfs文件系统工具(命令参考:sudo apt-get install squashfs-tools),然后制作squashfs文件系统镜像。制作方法如下:
其中,rootfs是之前已经制作好的根文件系统,rootfs.squashfs.img是生成的squashfs文件系统映像文件。-b 64K指定squashfs文件系统的块大小为64K(决定于实际spi flash块大小)。-comp 指定文件系统压缩方式为gzip。请根据实际情况修改参数。
ext4
ext4文件系统是一个高效的、优秀的、可靠的和极具特点的文件系统,相对于ext3的改进是更深层次的,是文件系统数据结构方面的优化。
-
编译ext4需要依赖服务器自身已安装的开源软件e2fsprogs。
进入boards/dmeb/pub目录下,系统自带的mkfs.ext4为制作ext4文件系统工具。以制作96M非稀疏 ext4文件系统为例:
dd if=/dev/zero of=rootfs_hi3516cv610_96M.ext4 bs=512 count=196608 fakeroot sh -c "mkfs.ext4 -d rootfs_musl_arm rootfs_hi3516cv610_96M.ext4"
说明: 196608=96 * 1024 * 1024 / 512 使用ext4类型的文件系统需要加载支持ext4选项的内核镜像 rootfs是之前已经制作好的根文件系统目录。
应用程序开发简介
编写代码
用户可根据个人习惯选择代码编写工具。通常在Windows环境下使用Source Insight,在Linux环境下使用Vim+ctags+cscope,功能也相当强大。
运行应用程序
要运行编译好的应用程序,首先需要将其添加到目标机中,必须完成以下工作:
- 将应用程序和需要的库文件(如果有)等添加到目标机的根文件系统相应的目录中。通常将应用程序放到/bin目录里,库文件放到/lib目录里,配置文件则放到/etc目录里。
- 制作包含新应用程序的根文件系统。
说明:
如果执行应用程序,需要读写文件系统操作。请选择ubifs、jffs2文件系统。
如果需要制作cramfs、ubifs或jffs2文件系统,请参见“文件系统简介”,然后烧写根文件系统到Flash指定位置,并设置相应的启动参数。同样,启动Linux后便可运行新的应用程序。
说明:
如果新添加的应用程序需要系统启动后自动运行,请编辑/etc/init.d/rcS文件,添加需要启动的应用程序路径。
附录:非docker版本软件清单
表 1 非docker版本软件清单