本文与 0xFFFF论坛:记录下折腾香橙派过程中踩过的坑 同步
开始使用
几个月之前入手了一块Orange PI One Plus开发板,实际用途是想拿来做个机顶盒(玩的)
本文虽然主要讨论的是One Plus,但很多软件操作同样适用于Orange PI 3
简单说一下硬件资源,这块开发板CPU是全志H6,带4K硬件解码,开发板本身带HDMI,红外,麦克风以及一个千兆网口,详细资料看这里。 其实如果把这块开发板的硬件与树莓派3甚至4比,它的优势是很明显的,毕竟4K硬件解码也是到了4才有,但是软件开发支持不怎么友好。
准备
下面来讲讲上手的过程。首先你最好有已经装好了一个Ubuntu,版本16或者18都可以,主要用途是拿来编译。另外你还需要一条串口调试线,用来连接开发板上的硬件调试口,好处是在没有连接屏幕和键盘等外围设备的情况下你也能够调试开发板,上某宝买来大概是这个样子
至于后面的如何接线、驱动和配置调试详细内容看手册,Linux系统和Windows下都可以用Putty调试,注意Putty在Ubuntu需要在终端sudo下才能打开。
另外由于One Plus没有eMMC,所以烧录和启动的话要用一张sd卡,也要提前准备好卡和读卡器
烧写系统
现成镜像有Android TV 9,Debian,Ubuntu Server,好像最近Armbian测试通过了也放了上去。这一步按照手册来也没有太多坑。Android镜像似乎一定要用Windows下的工具烧录,另外除了两个Server版和Armbian外其他的都有图形界面。还有最近出的Armbian下载官网体验似乎一直不好,下载链接打开要么超时要么像这样
正确打开方式:找国内镜像站,比如清华的镜像或者中科大的镜像,图为清华镜像下载
在我们校内好像还有教育网加持,速度应该非常可观。其实不论是开发板的Armbian还是主机Ubuntu都应该更换国内镜像,在接下来的安装过程避免浪费时间,避免掉大坑里。下载完之后在Windows上可用工具中给的Win32DiskManager写入。先接好串口线,再把卡插入板上打开电源,你应该看到主机这一端有输出信息
现在应该就可以用串口终端玩耍Linux了
编译
官方给出了一个自动化脚本,包括搭建交叉编译环境和Kernel与Uboot编译,手册里讲了如何一键编译Linux
据说它的4.9还是测试版拿过来改的,所以我不太敢用4.9,这里我只编译了3.10。这个内核是可以给Android用的,具体例子看CSDN: H6机顶盒Android编译1-linux内核编译,H6机顶盒Android编译2-Android编译,使用的源码在这里
按照手册和自动化脚本做,这个过程没有遇到什么坑,当然接下来应该可以编译发行版。
但是和Android一样,编译这种系统是个费时费力,而且什么也没有学到,所以我选了定制一个小型的系统
定制
所谓定制,就是在原有系统的基础上删减和增加自己的模块。本来编译前需要修改配置文件,但是上面给出的源码里面就已经预先配置好了,编译脚本只需要指定平台和交叉编译工具即可。实际上Linux Kernel编译系统本身就带了一个图形化的菜单可供配置。在刚才编译前下载的文件夹OrangePIH6中进入kernel文件夹,执行
make ARCH=arm64 menuconfig
ARCH指定了编译目标平台为arm64,后面应该出现一个这样的界面
在这个菜单里空格可选中/不选,回车进入菜单项,斜杠可以搜索。以下是我修改的选项:
- Boot Options的参数指定文件系统为ext4,不然后面可能出现挂载错误
- 由于这个内核不是给Android用的,所以应该可以把Android的驱动全部删掉。但是好像有几个是硬件解码驱动要用的,删掉会编译失败,所以还是要选(当然如果不用解码驱动的话也可以全部删掉)
- 视频解码驱动的话默认应该是有的,后面有勾了一个V4L的API,之后再试一下能不能用
然后其他设置不动,保存配置,编译的时候没有指定的话默认是用.config
开上面脚本那个脚本编译一遍,完成后会提示你已经输出到output文件夹里了。交叉工具链在编译一步的脚本应该已经自动装好了,如果报错,请先检查以下你的make
build-essential
gcc-aarch64-linux-gnu
等工具有没有装齐。然而现在仅仅是完成了内核编译,这些文件还带不起一个系统。
这时还需要制作一个根目录文件系统。对于OrangePI这样的小型开发板,一个轻量级的busybox是最适合不过了。上网找了一下,确实有人做过类似的操作:Orangepi PC2 使用busybox制作文件系统。按照教程,下载来跟刚才类似,开始配置编译
make menuconfig CROSS_COMPILE=aarch64-linux-gnu-
不过我与他不同的地方是我用了动态编译,因为之前用静态编译时到了后面就会增加不少麻烦。动态编译唯一的坏处是编译完成之后要把编译出来的文件所需要的二进制库复制进 /lib ,不过实际上最终要复制的库也只有两个,ld和libc
本来到了编译busybox这一步可以配置的东西很多,但基本上都是因人而异,玩法不一样预先要编译的也就不一样 :)
这里唯一的坑在于一定要把uhcpc和ifconfig选上,不然就会面临接上了网线却没办法自动拿到ip的问题
然后 make && make install
就完事了,输出文件默认在busybox目录下的_install文件夹里
不得不说它编译的十分纯粹,只有干干净净的二进制文件,剩下的折腾过程就在于怎么写配置文件和写入。按照上面那篇教程,
要建好 dev proc sys tmp mnt var/log var/lock var/lib var/run etc/init.d几个文件夹,写rcS,profile和inittab。个人建议加上passwd,写上这样一行
root::0:0:root:/root:/bin/sh
记得加好权限,并且建一个/root文件夹,这样可以避免后面出现许多怪异的问题
然后把busybox/example/uhdcp/simple.script复制进刚刚生成的/usr/share/udhcpc下,并且改名为default.script,以便udhcpc后面自动获取ip
至于动态链接库的问题,用aarch64-linux-gnu-readelf -d
可以读出二进制文件需要什么库,可以cd到busybox根目录下的bin文件夹里用aarch64-linux-gnu-readelf -d ./* | grep NEEDED
看看各个文件用了什么库,如果重复多,可以aarch64-linux-gnu-readelf -d ./* | grep NEEDED | sort | uniq
自动去重,最后只有
如果你是用apt安装的工具链的话,其链接库文件应该在你的主机/usr/aarch64-linux-gnu/lib下, 把这些库文件及其链接复制到/lib下即可
每次这样操作确实十分繁琐,你可以写一个脚本完成,也可以像我现在这样建一个空目录,当作根目录按上面操作一次,再把这个目录与_install文件夹生成文件合并一次
生成镜像
其实技术上没有什么难度,把官方给的/script/build_image.sh改一下即可:
把脚本里的rootfs路径ROOTFS改成busybox的,配置好常量如镜像名
分区设定的参数里可以把boot_size和disk_size改小,boot_size大概30M左右就够了,disk_size是boot_size+你的roofs大小,busybox的根目录大概只有3~5M
mkfs.ext4那行要加参数
-O ^64bit,^metadata_csum
,不然开机之后会报挂载失败的错由于这个脚本是要sudo运行的,所以后面要把images文件夹chown -R 改归当前用户
来一波sudo ./build_image.sh即可得到我们想要的镜像文件
再用balenaEtcher烧写进sd卡,启动!
4秒开机感觉相当不错~~ 虽然没有扩容,但是文件系统大小也是够用的。不过代价就是busybox上面没有我们熟悉的一切服务,连个网要手动udhcpc(当然写进rcS也不是不行)
接下来我想在上面加个ssh客户端和上传文件服务器,整个完整的开发环境,明天再来
SSH客户端与文件服务器
本来这两个东西可以直接装个OpenSSH解决,不过OpenSSH又要zlib和OpenSSL的库,然后OpenSSL又要牵扯一大堆的库。这些库要一一编译一次,其中不少是没有对交叉编译做适配的,所以比较烦。最后找到了一个简单的SSH客户端DropBear,编译可以不用除了libc外的任何库
在下载来的源码目录执行以下命令即可完成交叉编译
1 | ./configure --host=aarch64-linux-gnu --prefix=/ --disable-zlib CC=aarch64-linux-gnu-gcc LD=aarch64-linux-gnu-ld |
其中输出文件夹output要预先建好,把输出文件夹下的文件复制到busybox的根目录下即可
有一点比较坑的是虽然它本身编译时只链接了libc,但是实际上还有libnss_file.so要复制过去,不然就会因为读不到用户信息而报错,具体看这里:解决dropbear在busybox中使用无法使用本地用户登录问题
接下来就是在开发板上配置
1 | mkdir /etc/dropbear |
当然现在可以配置私钥登陆,把生成的私钥文件复制到/root/.ssh/下并改名为authorized_keys,不过搭好文件服务器后就可以用更简单的办法上传。现在先用passwd
改一下密码,然后连上局域网之后就可以直接登陆了
文件服务器一开始是想用ftpd之类的。后来是搭好了,准备开始弄开发环境才发现有问题。之前一直在找一个能远程部署并且远程调试,能媲美本地开发的工具,也找到一个QTCreator。当时在学校下载,官网很慢,老办法用镜像站
有没有感觉校园网突然香起来了哈哈哈
然后按照这个配置教程配好之后发现好像还少了一个sftp,网友提示要编译一次OpenSSH,那我的DropBear有什么用???不过最后还是卡在编译OpenSSL上,没有办法。不过QTCreator每次验证我的选项之后都会说少sftp和rsync
难道两个都要?后来上网查了一下rsync是什么,发现也是用来传输文件的,试着编译一遍,发现很快搞定,也不需要什么库
1 | ./configure --prefix=$PWD/output --host=aarch64-linux-gnu --with-rsh=dropbear --with-included-popt --with-included-zlib |
丢到/bin里面,在用QTCreator试一下,OK!
这就是我刚才说支持一键部署SSH密钥的地方,美滋滋~~
在Kits里面配置交叉编译器一下应该就可以线上调试了
建立个cmake的项目试试启动调试
本来之前编译了个gdbserver放上去,结果还不行?一开始我以为:10000
这个参数是乱给的,后来发现其实它的意思是在本地10000端口打开gdbserver,但是前面的ip省略了。但是前面加个*号就可以,然后我在QTCreator里还找不到调整gdb参数设置的地方?
结果就是这个问题现在无解,更加棘手的是QTCreator好像还没把我编译好的文件上传上去,按照官方的说法要自己配置上传,所以白折腾一场???
硬件编解码驱动与其他
之前远程调试的问题其实在armbian或者ubuntu下就完全没有问题,毕竟开发用这两个系统才合适
另外关于硬件解码的驱动还是有办法解决的,在官方提供的Android驱动下有民间整合的硬件解码驱动,所以只要用一般的视频播放接口即可实现,可惜不是底层的驱动。不过官方也放出了各种芯片平台通用的linux驱动,并且比较让人高兴的是终于带上了文档。
编译驱动的过程可能会出错,按这篇教程来全志 CedarX 库linux安装(不得不吐槽一下这个居然不能编译成arm64,浪费了H6这样的架构)。不过静态编译会让编解码库找不到插件路径报错(不影响使用),改一下GetLocalPathFromProcessMaps或者AddVEncPlugin/AddVDPlugin即可
还有一个看上去比较靠谱的源码,连播放器demo都带上了。但是目前在我本机上编译失败,原因似乎是本机少了arm上的alsa库,而且大概因为这些库在busybox上移植也比较麻烦(毕竟别人的目标平台还是ubuntu)。
在Github上找找还是有不少好东西的,比如说别人针对开发板制作的ubuntu精简版。剩下的代码不是没有文档的就是处于实验性质的,姑且当作参考
- https://github.com/ugers/android_external_cedarx
- https://github.com/allwinner-dev-team/android_external_cedarx
- https://github.com/FREEWING-JP/OrangePi_CedarX
- https://github.com/Allwinner-Homlet/H6-CedarC
- https://github.com/linux-sunxi/cedarx-libs
- https://github.com/liqil/cedarx-libs
- https://github.com/linux-sunxi/libcedrus
- https://github.com/bootlin/libva-v4l2-request
- https://github.com/linux-sunxi/libvdpau-sunxi
- https://github.com/allwinner-zh/media-codec
- https://github.com/allwinner-zh/media-codec-lib
- https://github.com/avafinger/v4l2-request-test
- https://github.com/bootlin/v4l2-request-test
- https://github.com/fsebentley/CedarX-12.06.2015
- https://github.com/leviathanch/sunxi-cedarx-blobs
- https://github.com/noblock/sunxi-cedar-mainline
busybox下面还有一个问题就是即使CPU占有为0%,芯片的温度依然高居不下。目前的解决方案是修改cpu的调度器
1 | echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor |
其中可用的调度器可以通过cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
查到,有一下几种
performance: 最大性能 powersave: 最高节能 ondemand: 快升快降 interactive: 快升慢降 conservative: 慢升快降
buxybox默认用的performance的策略就是始终让CPU处于最高频率1.8Ghz,所以温度才会一直拉满。