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