initial version
[android_pandora.git] / pnd / run.sh
1 #!/bin/bash
2 # run/kill Android from Linux
3 # (c) Grazvydas "notaz" Ignotas, 2012
4 set -e -x
5
6 if [ "`id -u`" != "0" ]; then
7   gksudo -m "Android needs root privileges to run, please enter your password" $0
8   exit 0
9 fi
10
11 root=/mnt/android
12 mpoint_main=`pwd`
13 kernel_ver=`uname -r`
14
15 trap onexit 1 2 3 15 EXIT
16
17 err()
18 {
19   zenity --error --text "$1"
20   echo "$1"
21 }
22
23 onexit()
24 {
25   set +e +x
26
27   list="/sbin/ueventd /system/bin/logcat /system/bin/sh /system/bin/servicemanager
28     /system/bin/vold /system/bin/netd /system/bin/rild /system/bin/installd /sbin/adbd
29     /system/bin/mediaserver /system/bin/keystore /system/bin/debuggerd
30     /system/bin/dbus-daemon"
31   for pr in $list; do
32     pb=`basename $pr`
33     p=`ps -C $pb -o pid=,cmd= | grep $pr | awk '{print $1}'`
34     test -n "$p" && echo kill $p $pr && kill $p
35   done
36   for pr in $list; do
37     pb=`basename $pr`
38     p=`ps -C $pb -o pid=,cmd= | grep $pr | awk '{print $1}'`
39     test -n "$p" && echo kill -9 $p $pr && kill -9 $p
40   done
41   list2=`ps ax | grep -v grep | grep -e ':.. /system/' -e ':.. /data/' -e ' android\.' | awk '{print $1}'`
42   list3=`lsof | grep '/dev/binder' | awk '{print $2}' | uniq`
43   for p in $list2 $list3; do
44     test -n "$p" && echo kill $p && kill $p
45   done
46   
47   sleep 0.5
48   
49   for i in `seq 5`; do
50     sdmounts=`grep -e '\.android_secure' -e 'secure/asec' -e 'mnt/sdcard' /proc/mounts`
51     if [ -n "$sdmounts" ]; then
52       echo "$sdmounts" | awk '{print $2}' | xargs umount
53     fi
54
55     umount $root/mnt/asec
56     umount $root/debug
57     umount $root/dev/pts
58     umount $root/dev
59     umount $root/proc
60     umount $root/sys
61     umount $root/data
62     umount $root/system || umount -i $root/system
63   
64     sleep 1
65     if umount $root; then
66       break;
67     fi
68   done
69
70   if ! pidof X > /dev/null; then
71     # need to restore SGX, X and friends
72     rmmod bufferclass_ti omaplfb pvrsrvkm
73     /etc/init.d/pvr-init start
74     rmmod wl1251_sdio # hmh
75     /etc/init.d/NetworkManager start
76     /etc/init.d/slim-init start
77   fi
78 }
79
80
81 # logger, binder and ashmem
82 delay=0
83 if ! test -e /dev/log_events; then
84   modprobe logger
85   delay=0.5
86 fi
87 if ! test -e /dev/binder; then
88   modprobe binder
89   delay=0.5
90 fi
91 if ! test -e /dev/ashmem; then
92   modprobe ashmem
93   delay=0.5
94 fi
95 sleep $delay
96 if test ! -e /dev/log_events -o ! -e /dev/binder -o ! -e /dev/ashmem; then
97   err "could not load required Android modules,\n\
98 perhaps you are running unsupported\nfirmware/kernel."
99   exit 1
100 fi
101
102 if ! test -e rootfs.ext2; then
103   if ! cp -v pandora/default_rootfs.ext2 rootfs.ext2; then
104     err "file copy failed, not enough space?"
105     exit 1
106   fi
107 fi
108
109 if ! test -e data.ext4; then
110   size=`zenity --entry --text="\
111     Android needs a partition to store it's data and installed programs.\n\
112     This will be stored in preallocated file of size that you have to select now.\n\
113     Android documentation recommends at least 150MB, going below 50MB will cause\n\
114     problems, as well as over 2GB if you are running from FAT partitioned card.\n\n\
115     Please select size of Android data partition (in megabytes):\n\
116     (creation may take several minutes after you press OK)" \
117       --entry-text=150`
118   if test -z "$size" || ! dd if=/dev/zero of=data.ext4 bs=1M count=$size; then
119     err "failed to create file, not enough space? bad input?"
120     exit 1
121   fi
122   if ! mkfs.ext4 -O ^has_journal -m 0 -F data.ext4; then
123     err "failed to create filesystem"
124     exit 1
125   fi
126 fi
127
128 if ! fsck.ext4 -y data.ext4 || ! fsck.ext2 -y rootfs.ext2; then
129   if [ "$?" -ge "4" ]; then
130     err "file corruption detected, try clearing appdata."
131     exit 1
132   fi
133 fi
134
135 mkdir -p $root
136 mount -o loop,rw,noatime rootfs.ext2 $root
137 mount --bind $mpoint_main/system/ $root/system/
138 mount -o loop,rw,noatime data.ext4 $root/data
139
140 mkdir -p $root/vendor
141
142 # handle SGX
143 mkdir -p $root/vendor/pvr
144 echo "0 0 android" > $root/vendor/pvr/egl.cfg
145
146 # load the right SGX driver
147 sgx_kernel_loaded=false
148 if ! grep -q '1.5.15.2766' /proc/pvr/version 2> /dev/null; then
149   echo have to change SGX kernel driver
150   /etc/init.d/pvr-init stop || true
151   if test -d $mpoint_main/pandora/pvr/$kernel_ver; then
152     # found with this android release
153     pvrbase=$mpoint_main/pandora/pvr/$kernel_ver
154   elif test -d /lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766; then
155     # found in firmware
156     pvrbase=/lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766
157   fi
158
159   if [ "x$pvrbase" != "x" ]; then
160     if insmod $pvrbase/pvrsrvkm.ko && insmod $pvrbase/omaplfb.ko; then
161       sgx_kernel_loaded=true
162       # optional
163       insmod $pvrbase/bufferclass_ti.ko || true
164     fi
165   fi
166 else
167   sgx_kernel_loaded=true
168 fi
169
170 sgx_user_ready=false
171 #if false; then
172 if $sgx_kernel_loaded; then
173   es=`cat /etc/powervr-esrev`
174   if [ "x$es" = "x" ]; then
175     err "unable to determine SGX version"
176   else
177     es="es$es"
178     # for some braindead reason 103 is named 121 too
179     sgx_ver=121
180     if [ "$es" = "es5" ]; then
181       sgx_ver=125
182     else
183       ln -fs /system/lib/$es/libGLESv2_POWERVR_SGX530_121.so $root/vendor/pvr/
184       ln -fs /system/lib/$es/libGLESv1_CM_POWERVR_SGX530_121.so $root/vendor/pvr/
185     fi
186     ln -fs /system/bin/$es/pvrsrvinit $root/vendor/pvr/
187     ln -fs /system/lib/$es/libPVRScopeServices.so $root/vendor/pvr/
188     ln -fs /system/lib/$es/libglslcompiler.so $root/vendor/pvr/
189     ln -fs /system/lib/$es/libsrv_um.so $root/vendor/pvr/
190     ln -fs /system/lib/$es/libIMGegl.so $root/vendor/pvr/
191
192     echo "0 1 POWERVR_SGX530_$sgx_ver" >> $root/vendor/pvr/egl.cfg
193     sgx_user_ready=true
194   fi
195 fi
196
197 if ! $sgx_user_ready; then
198   err "SGX driver load failed, no 3D support"
199 fi
200
201 # stop X and interfering things, get wifi ready
202 set +e
203 if pidof xfce4-session > /dev/null; then
204   user=`cat /tmp/currentuser`
205   # most often doesn't work :(
206   #if ! test -z "$user"; then
207   #  su -c 'xfce4-session-logout --logout' $user
208   #fi
209 fi
210 /etc/init.d/NetworkManager stop
211 modprobe mac80211
212 /etc/init.d/wl1251-init start
213 /etc/init.d/slim-init stop
214 sleep 1 # for wlan0, hmh..
215 chvt 2 & # may hang..
216 sleep 1
217 killall chvt 2> /dev/null || true
218 ifconfig wlan0 down
219 set -e
220
221 cp /etc/pointercal $root/vendor/
222 cp /lib/modules/$kernel_ver/kernel/drivers/net/wireless/wl1251/wl1251_sdio.ko $root/vendor/
223 mkdir -p $root/vendor/firmware
224 cp /lib/firmware/brf6300.bin $root/vendor/firmware/
225
226 # some cleanup
227 rm -rf $root/acct/uid/*
228
229 chroot $root /init &
230
231 # wait for a message
232 while true; do
233   sleep 1
234
235   if nc -V 2> /dev/null | grep -q GNU; then
236     # GNU nc always fails
237     msg=`nc -l -p 36936 localhost || true`
238   else
239     msg=`nc -l localhost 36936`
240   fi
241   if [ "x$msg" = "xquit" ]; then
242     break
243   fi
244   echo "unknown message: $msg"
245 done
246
247 # real init can't be killed this way
248 killall init