recreate rootfs on ver change, link gralloc
[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 X > /dev/null; then
77     # need to restore SGX, X and friends
78     rmmod bufferclass_ti omaplfb pvrsrvkm
79     /etc/init.d/pvr-init start
80     rmmod wl1251_sdio # hmh
81     /etc/init.d/NetworkManager start
82     /etc/init.d/slim-init start
83   fi
84
85   if ! ps a | grep -q 'pnd_run.*run_gingerbread.sh'; then
86     # something killed pnd_run, have to clean up for it
87     cat > /tmp/clean_android.sh <<EOF
88       #!/bin/bash
89       trap '' HUP
90       sleep 3
91       umount $mpoint_main
92       umount $mpoint_main # needed twice??
93       losetup -a | awk -F ':' '{ print \$1 }' | xargs losetup -d 2> /dev/null
94       rm $0
95 EOF
96     cd /tmp/
97     chmod +x /tmp/clean_android.sh
98     /tmp/clean_android.sh &
99     sleep 1
100   fi
101   exit $exitcode
102 }
103
104
105 # logger, binder and ashmem
106 delay=0
107 if ! test -e /dev/log_events; then
108   modprobe logger
109   delay=0.5
110 fi
111 if ! test -e /dev/binder; then
112   modprobe binder
113   delay=0.5
114 fi
115 if ! test -e /dev/ashmem; then
116   modprobe ashmem
117   delay=0.5
118 fi
119 sleep $delay
120 if test ! -e /dev/log_events -o ! -e /dev/binder -o ! -e /dev/ashmem; then
121   err "could not load required Android modules,\n\
122 perhaps you are running unsupported\nfirmware/kernel."
123   exit 1
124 fi
125
126 if test "x$last_pnd_version" != "x$pnd_version"; then
127   echo "version changed from $last_pnd_version to $pnd_version"
128   rm -f rootfs.ext2
129   echo "$pnd_version" > $mpoint_main/last_pnd_version
130 fi
131
132 if ! test -e rootfs.ext2; then
133   if ! cp -v pandora/default_rootfs.ext2 rootfs.ext2; then
134     err "file copy failed, not enough space?"
135     exit 1
136   fi
137 fi
138
139 if ! test -e data.ext4; then
140   size=`zenity --entry --text="\
141     Android needs a partition to store it's data and installed programs.\n\
142     This will be stored in preallocated file of size that you have to select now.\n\
143     Android documentation recommends at least 150MB, going below 50MB will cause\n\
144     problems, as well as over 2GB if you are running from FAT partitioned card.\n\n\
145     Please select size of Android data partition (in megabytes):\n\
146     (creation may take several minutes after you press OK)" \
147       --entry-text=150`
148   if test -z "$size" || ! dd if=/dev/zero of=data.ext4 bs=1M count=$size; then
149     err "failed to create file, not enough space? bad input?"
150     exit 1
151   fi
152   if ! mkfs.ext4 -O ^has_journal -m 0 -F data.ext4; then
153     err "failed to create filesystem"
154     exit 1
155   fi
156 fi
157
158 if ! fsck.ext4 -y data.ext4 || ! fsck.ext2 -y rootfs.ext2; then
159   if [ "$?" -ge "4" ]; then
160     err "file corruption detected, try clearing appdata."
161     exit 1
162   fi
163 fi
164
165 mkdir -p $root
166 mount -o loop,rw,noatime rootfs.ext2 $root
167 mount --bind $mpoint_main/system/ $root/system/
168 mount -o loop,rw,noatime data.ext4 $root/data
169
170 mkdir -p $root/vendor/
171
172 # handle SGX
173 mkdir -p $root/vendor/pvr
174 echo "0 0 android" > $root/vendor/pvr/egl.cfg
175
176 sgx_kernel_loaded=false
177 rm -f $root/vendor/pvr/gralloc.omap3.so
178
179 # load the right SGX driver
180 if ! grep -q '1.5.15.2766' /proc/pvr/version 2> /dev/null; then
181   echo have to change SGX kernel driver
182   /etc/init.d/pvr-init stop || true
183   if test -d $mpoint_main/pandora/pvr/$kernel_ver; then
184     # found with this android release
185     pvrbase=$mpoint_main/pandora/pvr/$kernel_ver
186   elif test -d /lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766; then
187     # found in firmware
188     pvrbase=/lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766
189   fi
190
191   if [ "x$pvrbase" != "x" ]; then
192     if insmod $pvrbase/pvrsrvkm.ko && insmod $pvrbase/omaplfb.ko; then
193       sgx_kernel_loaded=true
194       # optional
195       insmod $pvrbase/bufferclass_ti.ko || true
196     fi
197   fi
198 else
199   sgx_kernel_loaded=true
200 fi
201
202 sgx_user_ready=false
203 #if false; then
204 if $sgx_kernel_loaded; then
205   es=`cat /etc/powervr-esrev`
206   if [ "x$es" = "x" ]; then
207     err "unable to determine SGX version"
208   else
209     es="es$es"
210     # for some braindead reason 103 is named 121 too
211     sgx_ver=121
212     if [ "$es" = "es5" ]; then
213       sgx_ver=125
214     else
215       ln -fs /system/lib/$es/libGLESv2_POWERVR_SGX530_121.so $root/vendor/pvr/
216       ln -fs /system/lib/$es/libGLESv1_CM_POWERVR_SGX530_121.so $root/vendor/pvr/
217     fi
218     ln -fs /system/bin/$es/pvrsrvinit $root/vendor/pvr/
219     ln -fs /system/lib/hw/gralloc.omap3.so.1 $root/vendor/pvr/gralloc.omap3.so
220     ln -fs /system/lib/$es/libPVRScopeServices.so $root/vendor/pvr/
221     ln -fs /system/lib/$es/libglslcompiler.so $root/vendor/pvr/
222     ln -fs /system/lib/$es/libsrv_um.so $root/vendor/pvr/
223     ln -fs /system/lib/$es/libIMGegl.so $root/vendor/pvr/
224
225     echo "0 1 POWERVR_SGX530_$sgx_ver" >> $root/vendor/pvr/egl.cfg
226     sgx_user_ready=true
227   fi
228 fi
229
230 if ! $sgx_user_ready; then
231   err "SGX driver load failed, no 3D support"
232 fi
233
234 # stop X and interfering things, get wifi ready
235 set +e
236 if pidof xfce4-session > /dev/null; then
237   user=`cat /tmp/currentuser`
238   # most often doesn't work :(
239   #if ! test -z "$user"; then
240   #  su -c 'xfce4-session-logout --logout' $user
241   #fi
242 fi
243 /etc/init.d/NetworkManager stop
244 modprobe mac80211
245 /etc/init.d/wl1251-init start
246 /etc/init.d/slim-init stop
247 sleep 1 # for wlan0, hmh..
248 chvt 2 & # may hang..
249 sleep 1
250 killall chvt 2> /dev/null || true
251 ifconfig wlan0 down
252 set -e
253
254 cp -v /etc/pointercal $root/vendor/
255 cp -v /lib/modules/$kernel_ver/kernel/drivers/net/wireless/wl1251/wl1251_sdio.ko $root/vendor/
256 mkdir -p $root/vendor/firmware
257 cp -v /lib/firmware/brf6300.bin $root/vendor/firmware/
258
259 # some cleanup
260 rm -rf $root/acct/uid/*
261
262 chroot $root /init &
263
264 # wait for a message
265 while true; do
266   sleep 1
267
268   if nc -V 2> /dev/null | grep -q GNU; then
269     # GNU nc always fails
270     msg=`nc -l -p 36936 localhost || true`
271   else
272     msg=`nc -l localhost 36936`
273   fi
274   if [ "x$msg" = "xquit" ]; then
275     break
276   fi
277   echo "unknown message: $msg"
278 done
279
280 # real init can't be killed this way
281 killall init
282
283 # done, run exit handler indirectly
284 exitcode=0