前面的一篇博文中,提到了要使用自己編譯出來的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到機器后,無法安裝:

提示的是空間不夠,但是實際上,使用的是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 可能的原因匯總