前面的一篇博文中,提到了要使用自己编译出来的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。这个是下一篇博文的内容。
- 前言
- Freescale IMX6 Android (1): 使用HDMI作为Android显示输出的配置
- Freescale IMX6 Android (2): Android NFS启动问题汇总
- Freescale IMX6 Android (3): 手动制作Android启动用SD卡 省去MFGTOOLS烧写
- Freescale IMX6 Android (5): APP通过JNI控制LED
- Freescale IMX6 Android (4): 基于TQIMX6 给Toolbox添加LED控制程序
- Freescale IMX6 Android (6): 向ServerManager中添加Service
- Freescale IMX6 Android (7): Android启动动画死循环 Home界面不出来与pid XXX exit 可能的原因汇总