本帖最后由 deny12138 于 2019-5-19 21:37 编辑
更新
这篇帖子针对的是绿板小爱系统分区无法修改的情况,对小爱进行刷机的方式修改系统分区,和将C语言程序打包进系统。有人说使用opkg包管理工具,或者着说使用编译好的ipk包里的程序。但这是不行的,因为ipk包里的程序基本都是使用ld-musl-arm.so.3 这个翻译器(名字不一定一样,但基本都带musl),而小爱同学系统里却只有这个 ld-linux-armhf.so.3 ;树莓派中用的跟小爱一样,并且GCC版本也都是6.3.0。所以树莓派上的二进制程序都能拷到小爱上运行,(依赖的库文件也得拷过去)。
开篇
“开篇一**,内容全靠编“,皮了这一下感觉很开心。
好了,说回正题。其实呢,我也不是很想用这个标题,本来想着写”让你的绿板小爱拔掉‘小吊瓶’“来着,但是搜了一下,发现已经有人写了,嗯~,还是换一个主题吧,然后就换了这个标题。
正文
其实在上一次对小爱的系统和固件的分析当中,还是发现了很多内容的,也提到过建立一个代码库,收集好用的脚本方便刷机,于是就有了https://github.com/denymz/mi_aispeaker 。
这里简单说一下食用方法:
首先获取到系统的根目录分区root.squashfs文件,有三种方法
- 获取到固件包(.bin文件)上传到小爱同学中使用 miso -r -x <上传的固件包> 就能得到固件中的所有文件加上-f <文件名> 就能指定只解压某个文件
- dd 命令 dd if=/dev/mtdblock4 of=/tmp/root.squashfs (系统1),dd if=/dev/mtdblock5 of=/tmp/root.squashfs(系统2)
- binwalk -e 命令,不推荐,远没有以上两个好,所以不介绍了。
接下来就要用到Linux的系统了,Ubuntu和centos都是可以的,都可以使用包管理工具安装squashfs-tools。
将文件上传至linux系统中,使用unsquashfs解包得到squashfs-root的文件夹,然后执行以下命令
git clone [url=https://github.com/denymz/mi_aispeaker.git]https://github.com/denymz/mi_aispeaker.git[/url]
cd mi_aispeaker && cp -r * ../ && cd ..
接下来就可以修改squashfs-root目录下的内容了;修改完成后使用 package.sh 脚本打包,不指定参数默认打包成root.squashfs文件,打包完成后可以通过scp命令上传至小爱同学的文件系统中;
第一次刷机建议将flash_rootfs.sh脚本也上传,并使用该脚本来刷机。脚本用法 flash_rootfs.sh <0:将会把文件刷入到正在运行的系统 | 1:将会把文件输入到没在运行的另一系统> <将要刷入的root.squashfs文件>
目前进行了以下改动,/data/etc/rc.local 文件相当于 /etc/rc.local,里面的内容将会开机执行,增加ssl自签名证书,可以使用crontab -e命令修改定时计划,原/etc/crontabs/root文件不会生效,编译移植xinetd到小爱同学;
对于xinetd不了解的可以百度,他的大概作用是让你能够托管linux程序,比如写了一个脚本,并将该脚本通过xinetd托管在8088端口,这时向小爱同学的8088端口发起tcp连接就能触发该脚本运行,因为http也是使用的tcp协议,所以也就能通过一般浏览器访问进行触发,在脚本中可以使用read命令来读取通过tcp连接传输过来的数据。
好了,扯了这么多跟标题无关的内容,下面就来说一说如何让小爱同学运行自己编写C语言程序,一个C语言程序如果想要正常运行,需要以下几个条件
- 系统中有该程序依赖的库文件;
- 程序使用的指令集该系统需要具备;
- 程序使用的翻译器与系统中的相同;
最简单省事的方法就是使用树莓派,或者斐讯N1(armbian系统)编译程序然后复制到小爱同学上面运行(懒得搭交叉编译环境,xinetd就是我在树莓派上编译然后拷过去的),所以只要你想,任何C语言程序只要支持在树莓派上运行,就都是可以移植到小爱上面运行的。
虽然这是很美好,但是最大的问题是打包后的root.squashfs文件不得超过32兆(33,554,432 bytes),哪怕只是超过1byte,都会导致刷入失败;然后该系统就不能正常启动。原因是/dev/mtdblock4和/dev/mtdblock5大小只有33,554,432 bytes。
不过也还是有解决办法的,将程序需要的库文件通过软链接的方式事先在/lib文件夹下建立到该文件实际位置的软连接,比如我需要的一个库文件放在 /data/lib目录下,那么就在/lib目录建立一个指向 /data/lib/<库文件名>的软连接就行了。因为程序可以随便放在哪个位置来运行,可是库文件的话只会去那么几个地方找。哦,对了,还有一个小技巧,在编译完成后使用strip命令去除程序的调试符号,能够进一步减小程序体积。
结尾
好了,瞎扯了很多,也感谢你能坚持看到这里,最后呢宣传一下我的博客吧,https://blog.dmzy.vip ,有什么问题也可以在博客下留言,这样的话,我就可以在第一时间知道,并及时回复你啦。
|