免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

海思Hi3516DV500/HI3519DV500 SDK在Ubuntu 20.04上编译环境搭建指南

海思Hi3516DV500/HI3519DV500 SDK在Ubuntu 20.04上编译环境搭建指南 说实话刚拿到海思Hi3516DV500/HI3519DV500的SDK包时我也以为跟以前搞其他平台一样解压、敲个make、等几分钟就完事。结果在Ubuntu 20.04上硬是卡了两天各种缺库、工具链无法执行、menuconfig界面起不来一度怀疑自己拿的是不是个半成品SDK。后来把整个环境从头到尾捋了一遍才发现问题几乎都出在宿主机的年代感和SDK自带的古董工具链之间的错位上。这篇文章就是把我折腾过的东西全部整理出来。不管你是刚拿到DV500系列SDK的新手还是从Ubuntu 18.04甚至14.04升上来的老手只要跟着下面的步骤走一遍基本能把编译环境一次性打通。我会把依赖包清单、工具链安装、osdrv编译流程、常见报错排查全部写清楚连我踩过的坑也一并交代。1. 为什么SDK编译环境这么多坑根源在年代差1.1 Ubuntu 20.04和SDK默认环境之间隔了整整一代海思SDK里的交叉编译工具链很多还是基于Ubuntu 12.04/14.04时代的环境打包的。那时候系统gcc是4.8左右、Python还停留在2.7、默认b shell是bash、ncurses库是5系列。而Ubuntu 20.04的默认环境变成了gcc 9.4、Python 3.8、/bin/sh指向dash、ncurses库是6系列。这种代差直接带来的后果就是SDK里很多脚本和二进制工具期望的运行时库在20.04上根本找不到或者找到了但版本对不上一执行就报错。最典型的例子就是老的32位工具链跑不起来因为64位系统没装32位运行库。Hi3516DV500和HI3519DV500这批芯片SDK虽然比老的Hi3518系列新不少但很多基础组件仍然是从老代码库演进过来的。common目录下还留着大量用python2写的脚本busybox的配置文件还在用老式语法内核和uboot的配置阶段仍会拉起menuconfig。这些组件对宿主机的依赖很敏感不是你随便拿个新版gcc就能编译过去的。1.2 为什么不能用系统自带的gcc直接编译有些刚接触交叉编译的朋友会问SDK里不是有工具链吗我直接用系统gcc编不也一样不一样。SDK里的内核、uboot、rootfs、mpp库全部是用工具链目录下指定的那套交叉编译器来编译的系统gcc编出来的内核镜像在目标板上根本起不来。而且mpp库里很多模块是针对特定工具链做过程序级优化的混用编译器可能导致ABI不兼容到了板子上跑起来就会段错误或者接口调用异常。所以第一步要明确整个SDK的编译必须使用SDK自带的交叉编译工具链宿主机的系统gcc唯一的作用是编译一些辅助工具比如mkfs、dtc、mkimage这类宿主机工具。1.3 20.04依然是最妥协的选择我试过Ubuntu 18.04也试过22.04。18.04的问题在于Python 3.6偏老部分新版SDK脚本对它有兼容问题22.04的问题更麻烦openssl升级到3.x之后内核模块签名、uboot加密这些环节经常报“OpenSSL 3.0 incompatible”之类的错误。Ubuntu 20.04的glibc版本、openssl 1.1.1、Python 3.8刚好卡在老的SDK脚本还能跑新的编译工具也认的平衡点上。这也是我推荐把编译环境固定在20.04的原因。2. 拿到SDK压缩包先别急着编译目录结构和Makefile参数要读懂2.1 典型SDK目录一览海思DV500系列的SDK压缩包解压后通常会得到Hi3516DV500_SDK_Vx.x.x.x这样的顶层目录。里面几个核心目录最好先有个印象目录作用备注osdrv编译uboot、内核、rootfs、工具链的总入口启动流程里核心部分全在这mpp媒体处理平台包含sample、库、驱动ko应用开发主要跟它打交道smp多核/多进程框架的例子部分SDK版本以mpp/smp形式存在docs芯片文档、开发指南、编译指导很多关键信息藏在这里tools烧录工具、调试工具、工具链安装包交叉编译工具链一般在这drv外设驱动源码有些版本叫driverthird-party第三方开源组件如curl、openssl等第一次拿到SDK我建议先把docs目录下的《SDK编译环境说明》和《osdrv编译指导》这两份文档打开看一遍。别嫌浪费时间的里面会明确写清楚当前版本支持哪几个Ubuntu版本、工具链安装路径、Makefile参数怎么传。不同批次的SDKMakefile参数名真的不一样——有的用OSDRV_CROSS有的用CROSS_COMPILE还有的用CROSS不查文档硬猜很容易卡住。2.2 工具链到底藏在哪个目录DV500系列的工具链和以前老平台不一样有的版本把工具链放在osdrv/toolchain/下有的放在tools/linux/toolchain/里。解压后先找一下find . -name *himix*.install -o -name *himix*.tgz -o -name *himix*.tar.gz 2/dev/null常见的工具链名称有arm-himix200-linux32位ARM、aarch64-himix410-linux64位ARM。Hi3516DV500一般是Cortex-A7核心用arm-himix200-linux居多Hi3519DV500是Cortex-A53偏向aarch64-himix410-linux。具体以你手头SDK自带的为准不要跨芯片混用工具链。2.3 编译参数在README里都写了每个SDK版本的osdrv目录下基本都有README或者docs/下的编译说明。里面会给出标准的make命令模板。以我碰到的版本为例常见的格式长这样cd osdrv make CHIPhi3516dv500 OSDRV_CROSSarm-himix200-linux all如果你是Hi3519DV500把CHIP参数换成hi3519dv500OSDRV_CROSS换成对应的64位工具链前缀。除了CHIP和工具链有些版本还有BOOT_MEDIAboot介质类型、FLASH_TYPE、DDR_TYPE等参数这些必须跟你的实际板子硬件对应上不然编译出来的镜像在板上驱动不起来。我见过不少人在这一步卡住把CHIP写错或者工具链前缀跟SDK不匹配编译到一半就报一堆莫名其妙的内核错误。先花五分钟看文档比盲目开干省一小时。3. 依赖包安装清单直接照着贴命令再逐个验证3.1 apt批量安装的依赖包及用途下面是我在一台纯净Ubuntu 20.04上验证过的安装命令。建议先更新软件源再一次性装齐sudo apt-get update sudo apt-get install -y \ gcc g gcc-multilib g-multilib \ make cmake \ flex bison bc \ libssl-dev \ zlib1g-dev \ libncursesw5-dev \ u-boot-tools \r device-tree-compiler \ pkg-config \ lib32z1 lib32stdc6 lib32ncurses6 \ libc6-dev-i386 \ dosfstools \ lzop \ python2 python-is-python2逐个说下为什么需要它们软件包用途不装会怎样gcc/g/make宿主机基础编译系统自带一般没问题但没有会直接找不到编译器gcc-multilib/g-multilib提供32位交叉编译支持SDK里某些宿主机工具是32位编译链接缺了会报错flex/bison内核、uboot配置阶段的词法/语法解析器编译内核必装少了在配置阶段直接挂bc内核编译时做数值运算报bc command not foundlibssl-devopenssl头文件内核、uboot配置签名和加密模块时缺头文件zlib1g-dev压缩库开发包mtd-utils等工具编译依赖libncursesw5-devmenuconfig界面库不装这个make menuconfig起不来u-boot-tools提供mkimage等工具生成uImage时报mkimage not founddevice-tree-compiler设备树编译工具dtc编译dtb时需要不装会报dtc错误lib32z1/lib32stdc6/lib32ncurses632位运行时库32位交叉工具链无法执行libc6-dev-i38632位C标准库开发文件兼容32位程序编译和运行dosfstoolsmkfs.vfat等工具制作rootfs镜像时需要lzoplzo压缩工具部分内核压缩镜像时需要python2/python-is-python2兼容SDK里的python2脚本老脚本执行时报No module named xxx3.2 Ubuntu 20.04特有的坑libncurses5被移除了如果你在20.04上执行apt install libncurses5-dev会提示找不到候选包。因为20.04默认只提供ncurses 6.x5.x系列被移出了官方源。而很多海思工具链的menuconfig二进制是动态链接到libncurses.so.5的光有6还不行。我的做法是从Ubuntu 18.04的软件源里把deb包下载下来手动装cd /tmp wget http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.1-1ubuntu1_amd64.deb sudo dpkg -i libncurses5_6.1-1ubuntu1_amd64.deb如果这个文件名在你的网络环境下失效了就去http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/目录下找对应版本的libncurses5包。装上之后再执行dpkg -l | grep ncurses你会看到5和6两个系列共存互相不冲突。注意libncurses5是运行时库libncurses5-dev是开发头文件。如果你只是跑SDK里现成的menuconfig二进制装运行时库就够了如果要从源码重编译ncurses相关组件才需要dev版。3.3 装完怎么验证一条命令看全依赖包装齐之后我习惯用一条命令确认关键工具都在which gcc g make flex bison bc mkimage dtc python2 python3 gcc --version | head -n 1 gcc -m32 --version | head -n 1重点看gcc -m32能不能跑通。如果提示找不到32-bit相关的头文件或库说明gcc-multilib或libc6-dev-i386没装好回到上一步补齐。4. 交叉编译工具链装上不算数环境变量打通才算4.1 工具链安装脚本的正确打开方式以arm-himix200-linux为例找到工具链安装包后先解压再执行install脚本cd tools/linux/toolchain tar -zxvf arm-himix200-linux.tar.gz sudo ./arm-himix200-linux.install注意这里的sudo很关键。install脚本会把工具链目录装到/opt/hisi-linux/x86-arm/下这个路径普通用户没有写权限不加sudo会半路失败。如果是aarch64-himix410-linux安装路径通常是/opt/hisi-linux/x86-aarch64/步骤完全一样。4.2 环境变量不生效等于白装安装脚本会在/etc/profile或者/opt/...下生成环境变量配置。装完之后一定要重新登录或者手动执行source /etc/profile然后验证which arm-himix200-linux-gcc arm-himix200-linux-gcc -v能正确输出版本信息才算激活。如果提示No such file or directory先不要怀疑工具链坏了——大概率是32位运行库没装齐。执行file /opt/hisi-linux/x86-arm/arm-himix200-linux/bin/arm-himix200-linux-gcc看输出里有没有ELF 32-bit字样如果是32位ELF就回到第3章把lib32那一串补齐。我见过有人卡在这步一整天其实原因就是lib32stdc6没装工具链二进制一执行就报错。这个错误提示特别有迷惑性它不直接告诉你缺哪个库而是一句笼统的cannot execute binary file: Exec format error。4.3 WSL2用户需要注意的额外点如果你跟我一样开发机是Windows用WSL2里的Ubuntu 20.04来编译那么编译环境配置和原生Ubuntu没有任何区别上面所有命令照用。但有一个区别WSL2默认的/bin/sh是dash而且很多systemd服务是关闭的。编译本身不受影响但后续如果你要在WSL2里直接挂载USB设备烧录需要额外转发USB设备比较麻烦。我的建议是WSL2只负责编译烧录和调试放到原生Ubuntu或者Windows端工具来做各干各的更省心。5. osdrv全量编译一条命令背后的参数逻辑5.1 编译前先清理别被旧产物干扰SDK里osdrv编译过的中间文件非常占地方而且不同参数编译出来的产物会混在一起。强烈建议每次都先清理一次cd osdrv make cleanerootfscleanerootfs会清掉之前生成的rootfs、内核镜像、uboot镜像等。如果你是第一次编译这步跳过也行但养成习惯没有坏处。5.2 实际编译命令和参数解析以Hi3516DV500为例我用过的最简命令是make CHIPhi3516dv500 OSDRV_CROSSarm-himix200-linux allCHIP决定了编译哪个芯片的配置这个参数不能省OSDRV_CROSS指定交叉编译器前缀它对应的是工具链中的arm-himix200-linux-gcc。如果你的SDK版本用CROSS_COMPILE写法就变成make CHIPhi3516dv500 CROSS_COMPILEarm-himix200-linux- all注意区分这两者的差异。CROSS_COMPILE后面通常要带个短横线。编译时我建议加参数限制并发数避免把内存吃满make CHIPhi3516dv500 OSDRV_CROSSarm-himix200-linux -j8 all 21 | tee build.log21 | tee build.log的作用是让所有输出同时显示在屏幕和写入日志文件。编译环境出问题时日志文件是排查的第一手资料避免你重新跑一遍才能看到报错。5.3 编译成功后的产物去哪看编译结束后产物统一放在osdrv/pub/里。典型的结构长这样osdrv/pub/ ├── bin/ ├── rootfs_.../ ├── uImage_.../ ├── u-boot-.../ └── ...你可以先ls看一下各文件大小是否正常。内核压缩包一般在几MB到十几MB之间rootfs根据配置不同可能在几十MB到几百MB。如果某个文件大小是0或者明显偏小说明编译过程中可能有模块被跳过了回头检查日志。5.4 编译失败不一定非要从头再来SDK编译是分阶段的先uboot、再内核、最后rootfs。如果在rootfs阶段挂了uboot和内核其实已经编好了。这时只需要修掉问题再次执行相同的make命令它会自动做增量编译不会全部重来。所以别一报错就清掉全部产物先看日志定位到第几步再说。6. mpp与sample编译链路验证环境是否真的完整6.1 mpp库编译是检验工具链的最佳试金石osdrv编译通过只能说明启动镜像流程没问题。真正检验整个交叉编译环境是否完全可靠的是mpp部分的编译因为mpp库涉及大量芯片多媒体特性的编译对编译器头文件路径、宏定义、链接顺序都很敏感。进入mpp目录后先看有没有README或者Makefile。比较常见的做法是直接cd mpp make或者部分SDK版本提供了make_all脚本cd mpp/smp ./make_allmpp编译依赖之前设置好的工具链环境变量如果没source/etc/profilemake会直接报找不到编译器。6.2 sample编译验证最终可执行文件mpp编译通过后接着编sample。sample里是各种demo程序比如vio、venc、vpss这些。它们编译产物都是可以直接放到板子上跑的可执行文件所以这一步等于对整个编译链路做了一次端到端验证cd mpp/sample makesample编译经常出现的情况是库路径找不到原因是Makefile.param里依赖mpp库的相对路径如果你不是从干净状态开始某个库没编出来就会在链接阶段报错。这时候检查mpp的lib目录是否生成了对应.so或.a文件缺了就先把mpp补编完整。我在实际编译中发现很多开发板厂商给的SDK里sample默认是不全量编译的需要你手动修改Makefile里的某个模块开关。不要以为报错就是环境问题先看看是不是开关没开。6.3 环境变量和编译顺序踩过的人才知道sdk编译的顺序必须是工具链环境变量 → osdrv → mpp → sample。这个顺序不能乱。因为sample会引用mpp生成的库mpp的某些组件又引用了osdrv生成的内核头文件。如果你在编译mpp时遇到linux/xxx.h not found基本可以判断是osdrv的内核头文件还没装到mpp的include路径下。回到osdrv重新执行一遍完整编译或者手动把内核头文件拷到mpp目录下对应位置。7. 常见报错对照与排查顺序7.1 报错对照表我在整理这套环境的过程中把最常见的报错汇总成一张表。建议你收藏起来遇到问题先拿出来对一遍报错现象根因解决方案cannot execute binary file: Exec format error32位工具链缺32位运行库安装lib32z1 lib32stdc6 lib32ncurses6 libc6-dev-i386make[1]: gcc: Command not found宿主机gcc不在PATHapt install gcc或检查环境变量*** Unable to find the ncurses libraries缺ncurses开发库安装libncursesw5-dev旧工具链需手动装libncurses5mkimage command not found缺u-boot-toolsapt install u-boot-toolsbc: command not found缺bcapt install bc/bin/sh: 1: Syntax error: ( unexpected/bin/sh指向dashsudo dpkg-reconfigure dash选择No切换为bashundefined reference to \EVP_...openssl版本不匹配确认安装libssl-dev必要时将openssl切换到1.1.1Python.h: No such file or directory缺python开发头文件apt install python2-devCannot find device tree compiler缺dtcapt install device-tree-compilerNo space left on device磁盘满了预留至少20GB检查df -hvirtual memory exhaustedmake并发开太大调低-j参数或增加swap7.2 我的排查顺序如果你在编译中报错建议按这个顺序排第一步先看日志开头的第一个error不要看最后那几行。make出错时后面的错误往往是一连串连锁反应真正的根因在第一个。第二步确认是不是32位库问题。凡是工具链二进制执行报错第一时间执行file命令看ELF格式再确认32位库装没装。第三步排查/bin/sh指向。很多SDK脚本假设sh是bashUbuntu 20.04默认dash这会导致一堆语法错误。切换完记得重新退出终端再进让环境彻底生效。第四步检查磁盘空间。SDK解压加编译我实测下来峰值占用超过15GB如果你只留了10GB编到内核阶段必挂。7.3 切换bash的注意事项sudo dpkg-reconfigure dash弹出来的界面里有一个Use dash as the default system shell的选项选No即可。切换后验证ls -l /bin/sh输出显示/bin/sh - bash才算成功。这个坑非常隐蔽。编译内核时偶尔会触发某些shell脚本里的数组语法在dash下直接报错而且报错位置不是出错处是在调用脚本的那一行。你排查半天觉得逻辑没问题其实只是shell解释器不对。8. 写在最后的实际操作体会整套环境配置下来我最想说的一点是别迷信教程里的命令SDK版本不同工具链名称、Makefile参数、目录结构都会有差异。关键是理解每个步骤究竟在干什么——依赖包解决的是宿主机兼容问题工具链环境变量解决的是交叉编译器的可执行问题osdrv编译解决的是启动镜像的完整性问题mpp和sample编译则是验证整个环境是否真的可用的试金石。我自己现在每次换机器都先把第3章的依赖清单跑一遍然后直接试编译sample能编出可执行文件就算环境通过。这个方法省掉了大量反复试错的时间。还有一个小建议装好环境后把/opt/hisi-linux这个目录整个备份一下下次换电脑直接拷贝过去再重新source环境变量就能用不用再经历一遍工具链安装的折磨。祝你在Hi3516DV500/HI3519DV500上顺利跑通第一块板。
返回列表