🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
前面的一篇博文中,提到了要使用自己编译出来的Android来启动,且使用NFS的方式来启动Android,但是在今天的尝试中却遇到了问题。且最终没有解决,但是找到了替换方案,替换方案见下一篇博文。遇到的问题汇总如下,希望可以帮助遇到同样问题的人。板子用的还是TQIMX6Q(见以前的博文)。 ## Android NFS启动的rootfs制作与启动 要制作Android NFS rootfs,需要对Android的启动有一个基本的了解,推荐参考相关书籍。简单而已,Android的启动过程如下: uboot --> kernel --> Android Init in ramdisk(boot.img) --> Init 解析 init.rc --> Init 解析 init.HARDWARE.rc --> 根据initrc中的不同section,执行对应的操作 这里面执行的操作包括: 1. 创建目录/配置目录文件的权限/创建symbol link 1. mount文件系统,包括pesudo(例如debufs/proc)与实际的文件系统(例如system分区) 1. 安装内核模块等 1. 启动各个service,例如vold,bootanmition,让系统拥有软件硬件服务 其中ramdisk(可能位于boot.img中),属于第一阶段的rootfs,init.rc与init.HARDWARE.rc都在这里面,而且这个是一个page cache而非initrd形式的文件系统。 对此,我们可以如下建立一个Android NFS rootfs: 1. 拷贝root(即未打包前的uramdisk中的内容)目录中的文件到Rootfs更目录下 1. 在Rootfs中创建system目录,并将Andriod编译生成目录下面的system目录中的文件拷贝进去 1. 添加这个rootfs到nfs server的配置文件中,例如/etc/exports 最后就是启动了,这个时候只需要机器中有可以启动的uboot即可,在uboot中使用前一篇博文的启动args启动。 ## 问题1:NFS启动Android之后特别卡 这个问题表现为,在NFS启动之后输入ps查看进程,会卡很久才出结果,同时在串口中交互也明显感受到很卡,这个问题是因为NFS的连接不稳定所致,一般NFS不稳定的时候会出现如下log提示: ~~~ nfs: server 192.168.2.100 not responding ~~~ 恢复连接之后: ~~~ nfs: server 192.168.2.100 OK ~~~ 但是有的时候会出现nfs 连接重试等待,这个时候就会卡住。 这个问题的解决方法: 1. 确认PC Linux下网络配置是否变更,网络是否繁忙 1. 系统负荷是否过大而导致nfs server无法被及时的调度到 ## 问题2:Init启动各种service之后,Service会exit 问题表现为启动之后,会有Service开始退出,然后这个Service又启动,然后此service又退出,如此反复。这个问题在[TQIMX6的论坛中也有人遇到了这个问题](http://www.armbbs.net/forum.php?mod=viewthread&tid=21353&extra=page%3D1),但是没有人回复。 我这里的log是如下: ~~~ init: untracked pid 2395 exited nfs: server 192.168.2.100 OK binder: release 2593:2614 transaction 31 in, still active binder: send failed reply for transaction 31 to 2591:2617 init: untracked pid 2592 exited binder: release 2633:2640 transaction 56 in, still active binder: send failed reply for transaction 56 to 2642:2653 init: untracked pid 2632 exited ~~~ service退出后,导致bindler发消息无法被回复,这个service居然还是app_process(PID=2395): ~~~ root 2386 2 0 0 c0145ef8 00000000 S flush-0:12 root 2389 1 832 460 c004c9f0 401bce1c S /system/bin/sh system 2390 1 904 172 c0523a28 40106324 S /system/bin/servicemanager root 2391 1 4032 752 ffffffff 4015fbfc S /system/bin/vold root 2392 1 2128 996 c0132c80 400de4d0 S /system/bin/netd root 2393 1 940 236 c056c5ec 400fff8c S /system/bin/debuggerd system 2394 1 5000 1556 ffffffff 400b6614 S /system/bin/surfaceflinger root 2395 1 5552 872 c00eb200 40105050 D /system/bin/app_process drm 2396 1 4648 1316 c00eb200 40150f72 D /system/bin/drmserver media 2397 1 5052 1408 c00eb200 4015af72 D /system/bin/mediaserver install 2398 1 900 216 c056c5ec 401faf8c S /system/bin/installd keystore 2400 1 3268 996 c0523a28 40172324 S /system/bin/keystore radio 2401 1 5556 708 ffffffff 4010fbfc S /system/bin/rild root 2426 2 0 0 c009d3e8 00000000 S kworker/0:2 root 2441 2389 1156 236 00000000 40188060 R ps root 2473 2392 764 72 c06a2aa8 400b9b80 D /system/bin/iptables root@android:/ # ~~~ 遇到这个问题的解决步骤如下: 1. 查看tomb文件,定位Service退出的信息,如果没有记录下来,就按下面步骤来 1. 在bindler中添加打印log,看看是什么消息没有回复,确定Service在哪个位置退出的 1. 确定Service大概退出的问题位置之后,添加log输出,使用二分法确定位置 其中在Bindler中添加输出调试log的示例如下: ~~~ printk(KERN_INFO "binder: %d:%d transaction failed %d, size" "%zd-%zd\n", proc->pid, thread->pid, return_error, tr->data_size, tr->offsets_size); ~~~ bindler实现位于kenrel代码中的:drivers/staging/android/binder.c ## 问题3:NFS启动后的Android无法安装程序 本来以为解决了前面两个问题,就开始使用了,于是在Android Studio中写了一个helloworld测试程序,结果,push到机器后,无法安装: ![](https://box.kancloud.cn/2016-05-05_572afc974f113.jpg) 提示的是空间不够,但是实际上,使用的是NFS(几十GB),拥有足够的空间。 想了想,发现我们使用NFS启动与正常冲eMMC启动Android有一个很重要的区别: > system/data分区在nfs环境下面启动不会mount实际的设备(即不会mount某个flash的分区),我们的data/system其实是NFS mount了的rootfs下面的一个普通目录。 鉴于此,我想提示的空间不足其实是因为读取的是这个目录mount设备的空间大小,而我们没有设备mount到这个目录下,当我们要安装一个apk的时候,会到cache与data下面创建文件,此时就会出现错误。因此对于这个问题,我们可以按照如下方法解决: > 将data/system/cache分区mount到实际的设备分区中。 ## 总结 尽管在经过多个问题的解决与折腾之后,我们可以正常的使用NFS启动Android并安装与调试程序,但是实际上与我们最初的目标有些违背了,这样子变得更为麻烦了。因此我决定使用可拔插的SD卡来启动Android。这个是下一篇博文的内容。