| 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 |