编译
官方给出了一个自动化脚本,包括搭建交叉编译环境和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客户端和上传文件服务器,整个完整的开发环境,明天再来