run_gingerbread: fix signal handling and exit
[android_pandora.git] / pnd / run_gingerbread.sh
diff --git a/pnd/run_gingerbread.sh b/pnd/run_gingerbread.sh
new file mode 100755 (executable)
index 0000000..521dc97
--- /dev/null
@@ -0,0 +1,273 @@
+#!/bin/bash
+# run/kill Android from Linux, the hackjob script
+# (c) Grazvydas "notaz" Ignotas, 2012
+set -e -x
+
+if [ "`id -u`" != "0" ]; then
+  # gksudo causes logging not to work somehow..
+  # so use it to only ask for password, use sudo to re-run the script
+  gksudo -m "Android needs root privileges to run, please enter your password" id
+  exec sudo -n $0
+fi
+
+root=/mnt/android
+mpoint_main=`pwd`
+kernel_ver=`uname -r`
+exitcode=1
+
+trap onexit INT QUIT TERM EXIT
+trap '' HUP
+
+err()
+{
+  zenity --error --text "$1"
+  echo "$1"
+}
+
+onexit()
+{
+  set +e +x
+
+  list="/sbin/ueventd /system/bin/logcat /system/bin/sh /system/bin/servicemanager
+    /system/bin/vold /system/bin/netd /system/bin/rild /system/bin/installd /sbin/adbd
+    /system/bin/mediaserver /system/bin/keystore /system/bin/debuggerd
+    /system/bin/dbus-daemon"
+  for pr in $list; do
+    pb=`basename $pr`
+    p=`ps -C $pb -o pid=,cmd= | grep $pr | awk '{print $1}'`
+    test -n "$p" && echo kill $p $pr && kill $p
+  done
+  for pr in $list; do
+    pb=`basename $pr`
+    p=`ps -C $pb -o pid=,cmd= | grep $pr | awk '{print $1}'`
+    test -n "$p" && echo kill -9 $p $pr && kill -9 $p
+  done
+  list2=`ps ax | grep -v grep | grep -e ':.. /system/' -e ':.. /data/' -e ' android\.' | awk '{print $1}'`
+  list3=`lsof | grep '/dev/binder' | awk '{print $2}' | uniq`
+  for p in $list2 $list3; do
+    test -n "$p" && echo kill $p && kill $p
+  done
+  
+  sleep 0.5
+  
+  for i in `seq 4`; do
+    sdmounts=`grep -e '\.android_secure' -e 'secure/asec' -e 'mnt/sdcard' /proc/mounts`
+    if [ -n "$sdmounts" ]; then
+      echo "$sdmounts" | awk '{print $2}' | xargs umount
+    fi
+
+    omounts=`grep "$root/" /proc/mounts | awk '{print $2}'`
+    if [ -n "$omounts" ]; then
+      for m in $omounts; do
+        if ! umount $m; then
+          umount -i $m
+        fi
+      done
+    fi
+
+    sleep 0.5
+    if umount $root; then
+      break;
+    fi
+  done
+
+  if ! pidof X > /dev/null; then
+    # need to restore SGX, X and friends
+    rmmod bufferclass_ti omaplfb pvrsrvkm
+    /etc/init.d/pvr-init start
+    rmmod wl1251_sdio # hmh
+    /etc/init.d/NetworkManager start
+    /etc/init.d/slim-init start
+  fi
+
+  if ! ps a | grep -q 'pnd_run.*run_gingerbread.sh'; then
+    # something killed pnd_run, have to clean up for it
+    cat > /tmp/clean_android.sh <<EOF
+      #!/bin/bash
+      trap '' HUP
+      sleep 3
+      umount $mpoint_main
+      umount $mpoint_main # needed twice??
+      losetup -a | awk -F ':' '{ print \$1 }' | xargs losetup -d 2> /dev/null
+      rm $0
+EOF
+    cd /tmp/
+    chmod +x /tmp/clean_android.sh
+    /tmp/clean_android.sh &
+    sleep 1
+  fi
+  exit $exitcode
+}
+
+
+# logger, binder and ashmem
+delay=0
+if ! test -e /dev/log_events; then
+  modprobe logger
+  delay=0.5
+fi
+if ! test -e /dev/binder; then
+  modprobe binder
+  delay=0.5
+fi
+if ! test -e /dev/ashmem; then
+  modprobe ashmem
+  delay=0.5
+fi
+sleep $delay
+if test ! -e /dev/log_events -o ! -e /dev/binder -o ! -e /dev/ashmem; then
+  err "could not load required Android modules,\n\
+perhaps you are running unsupported\nfirmware/kernel."
+  exit 1
+fi
+
+if ! test -e rootfs.ext2; then
+  if ! cp -v pandora/default_rootfs.ext2 rootfs.ext2; then
+    err "file copy failed, not enough space?"
+    exit 1
+  fi
+fi
+
+if ! test -e data.ext4; then
+  size=`zenity --entry --text="\
+    Android needs a partition to store it's data and installed programs.\n\
+    This will be stored in preallocated file of size that you have to select now.\n\
+    Android documentation recommends at least 150MB, going below 50MB will cause\n\
+    problems, as well as over 2GB if you are running from FAT partitioned card.\n\n\
+    Please select size of Android data partition (in megabytes):\n\
+    (creation may take several minutes after you press OK)" \
+      --entry-text=150`
+  if test -z "$size" || ! dd if=/dev/zero of=data.ext4 bs=1M count=$size; then
+    err "failed to create file, not enough space? bad input?"
+    exit 1
+  fi
+  if ! mkfs.ext4 -O ^has_journal -m 0 -F data.ext4; then
+    err "failed to create filesystem"
+    exit 1
+  fi
+fi
+
+if ! fsck.ext4 -y data.ext4 || ! fsck.ext2 -y rootfs.ext2; then
+  if [ "$?" -ge "4" ]; then
+    err "file corruption detected, try clearing appdata."
+    exit 1
+  fi
+fi
+
+mkdir -p $root
+mount -o loop,rw,noatime rootfs.ext2 $root
+mount --bind $mpoint_main/system/ $root/system/
+mount -o loop,rw,noatime data.ext4 $root/data
+
+mkdir -p $root/vendor/
+
+# handle SGX
+mkdir -p $root/vendor/pvr
+echo "0 0 android" > $root/vendor/pvr/egl.cfg
+
+# load the right SGX driver
+sgx_kernel_loaded=false
+if ! grep -q '1.5.15.2766' /proc/pvr/version 2> /dev/null; then
+  echo have to change SGX kernel driver
+  /etc/init.d/pvr-init stop || true
+  if test -d $mpoint_main/pandora/pvr/$kernel_ver; then
+    # found with this android release
+    pvrbase=$mpoint_main/pandora/pvr/$kernel_ver
+  elif test -d /lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766; then
+    # found in firmware
+    pvrbase=/lib/modules/$kernel_ver/kernel/drivers/gpu/pvr/1.5.15.2766
+  fi
+
+  if [ "x$pvrbase" != "x" ]; then
+    if insmod $pvrbase/pvrsrvkm.ko && insmod $pvrbase/omaplfb.ko; then
+      sgx_kernel_loaded=true
+      # optional
+      insmod $pvrbase/bufferclass_ti.ko || true
+    fi
+  fi
+else
+  sgx_kernel_loaded=true
+fi
+
+sgx_user_ready=false
+#if false; then
+if $sgx_kernel_loaded; then
+  es=`cat /etc/powervr-esrev`
+  if [ "x$es" = "x" ]; then
+    err "unable to determine SGX version"
+  else
+    es="es$es"
+    # for some braindead reason 103 is named 121 too
+    sgx_ver=121
+    if [ "$es" = "es5" ]; then
+      sgx_ver=125
+    else
+      ln -fs /system/lib/$es/libGLESv2_POWERVR_SGX530_121.so $root/vendor/pvr/
+      ln -fs /system/lib/$es/libGLESv1_CM_POWERVR_SGX530_121.so $root/vendor/pvr/
+    fi
+    ln -fs /system/bin/$es/pvrsrvinit $root/vendor/pvr/
+    ln -fs /system/lib/$es/libPVRScopeServices.so $root/vendor/pvr/
+    ln -fs /system/lib/$es/libglslcompiler.so $root/vendor/pvr/
+    ln -fs /system/lib/$es/libsrv_um.so $root/vendor/pvr/
+    ln -fs /system/lib/$es/libIMGegl.so $root/vendor/pvr/
+
+    echo "0 1 POWERVR_SGX530_$sgx_ver" >> $root/vendor/pvr/egl.cfg
+    sgx_user_ready=true
+  fi
+fi
+
+if ! $sgx_user_ready; then
+  err "SGX driver load failed, no 3D support"
+fi
+
+# stop X and interfering things, get wifi ready
+set +e
+if pidof xfce4-session > /dev/null; then
+  user=`cat /tmp/currentuser`
+  # most often doesn't work :(
+  #if ! test -z "$user"; then
+  #  su -c 'xfce4-session-logout --logout' $user
+  #fi
+fi
+/etc/init.d/NetworkManager stop
+modprobe mac80211
+/etc/init.d/wl1251-init start
+/etc/init.d/slim-init stop
+sleep 1 # for wlan0, hmh..
+chvt 2 & # may hang..
+sleep 1
+killall chvt 2> /dev/null || true
+ifconfig wlan0 down
+set -e
+
+cp -v /etc/pointercal $root/vendor/
+cp -v /lib/modules/$kernel_ver/kernel/drivers/net/wireless/wl1251/wl1251_sdio.ko $root/vendor/
+mkdir -p $root/vendor/firmware
+cp -v /lib/firmware/brf6300.bin $root/vendor/firmware/
+
+# some cleanup
+rm -rf $root/acct/uid/*
+
+chroot $root /init &
+
+# wait for a message
+while true; do
+  sleep 1
+
+  if nc -V 2> /dev/null | grep -q GNU; then
+    # GNU nc always fails
+    msg=`nc -l -p 36936 localhost || true`
+  else
+    msg=`nc -l localhost 36936`
+  fi
+  if [ "x$msg" = "xquit" ]; then
+    break
+  fi
+  echo "unknown message: $msg"
+done
+
+# real init can't be killed this way
+killall init
+
+# done, run exit handler indirectly
+exitcode=0