Permalink
Switch branches/tags
Nothing to show
Find file Copy path
105f890 Dec 15, 2013
2 contributors

Users who have contributed to this file

@pfalcon @zeroepoch
executable file 391 lines (332 sloc) 11.7 KB
#!/bin/sh
#
# NSLU2-Linux Optware setup script for Android
# Copyright (c) 2012 Paul Sokolovsky <pfalcon@users.sourceforge.net>
# License: GPLv3, http://www.gnu.org/licenses/gpl.html
#
# http://sf.net/p/optware-android/
#
# Optware ARM binary packages repositories (aka feeds):
# http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/
#
# Optware source code Subversion repository:
# svn co http://svn.nslu2-linux.org/svnroot/optware/trunk/
#
#set -x
# To install optware, we need root anyway. However, the fact that we can
# obtain root access on device doesn't mean we have root access with
# "adb push", i.e. can push to any location from host. So, we need
# a location writable by adb as a temporary transfer area. That's
# ADB_WRITABLE_DIR. /data/local is usually a good choice for most devices,
# but that can be anything, for example, /sdcard (there's no requirement
# for the filesystem with that dir supported Unix permissions, this script
# will get it right).
#
# OPTWARE_DIR is where to install optware, it should be on a partition with
# normal Unix filesystem (permissions, etc.)
OPTWARE_DIR=/data/opt
ADB_WRITABLE_DIR=/data/local
# Particular field to install from, stable by default
FEED=http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/stable
# DO NOT edit anything below this line unless you know what you are doing
start_script=start.sh
tmp_dir=$ADB_WRITABLE_DIR/optware.tmp
cs08q1_url=https://sourcery.mentor.com/sgpp/lite/arm/portal/package2549/public/arm-none-linux-gnueabi/arm-2008q1-126-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
cs08q1_fname=$(basename $cs08q1_url)
libc_path=arm-2008q1/arm-none-linux-gnueabi/libc
libc_libs="lib/ld-2.5.so ld-linux.so.3 \
lib/libc-2.5.so libc.so.6 \
lib/libm-2.5.so libm.so.6 \
lib/librt-2.5.so librt.so.1 \
lib/libpthread-2.5.so libpthread.so.0 \
lib/libresolv-2.5.so libresolv.so.2 \
lib/libdl-2.5.so libdl.so.2 \
lib/libnss_dns-2.5.so libnss_dns.so.2 \
lib/libutil-2.5.so libutil.so.1 \
lib/libgcc_s.so.1 libgcc_s.so \
lib/libnsl-2.5.so libnsl.so.1 \
lib/libcrypt-2.5.so libcrypt.so.1 \
lib/libBrokenLocale-2.5.so libBrokenLocale.so.1 \
lib/libanl-2.5.so libanl.so.1 \
lib/libcidn-2.5.so libcidn.so.1 \
lib/libnss_compat-2.5.so libnss_compat.so.2 \
lib/libnss_files-2.5.so libnss_files.so.2 \
lib/libnss_hesiod-2.5.so libnss_hesiod.so.2 \
lib/libnss_nis-2.5.so libnss_nis.so.2 \
lib/libnss_nisplus-2.5.so libnss_nisplus.so.2 \
lib/libthread_db-1.0.so libthread_db.so.1 \
"
#
# On-target (device) commands
#
t_cp () {
# copy file on a device
adb shell su -c "cat $1 >$2"
}
t_cd_ln () {
local dir=$1
shift
adb shell su -c "cd $dir; ln $*"
}
t_chmod () {
adb shell su -c "chmod $*"
}
t_mkdir_p () {
# This doesn't complain if dir exists, but can't create intermediate dirs
adb shell su -c "ls $1 >/dev/null 2>&1 || mkdir $1"
}
t_rm_f () {
# Doesn't complain if file not there
adb shell su -c "ls $1 >/dev/null 2>&1 && rm $1"
}
t_rm_rf () {
# Doesn't complain if dir not there
adb shell su -c "ls $1 >/dev/null 2>&1 && rm -r $1"
}
t_remount_rw () {
adb shell su -c "mount -o rw,remount $1 $1"
}
t_remount_ro () {
adb shell su -c "mount -o ro,remount $1 $1"
}
extract_libc () {
if [ ! -d $(echo $libc_path | sed -e 's%/.*%%') ]; then
echo Extracting $cs08q1_fname
tar xfj $cs08q1_fname $list
fi
}
install_system_lib () {
local f=$(basename $1)
echo "Installing system lib: $f"
adb push $libc_path/$1 $tmp_dir
t_cp $tmp_dir/$f /lib/$f
t_chmod 0755 /lib/$f
t_cd_ln /lib/ -s $f $2
}
install_system_bin () {
local f=$(basename $1)
echo "Installing system bin: $1"
adb push $libc_path/$1 $tmp_dir
t_cp $tmp_dir/$f /bin/$f
t_chmod 0755 /bin/$f
}
install_libc () {
while [ -n "$1" ]; do
local lib=$1
shift
local symlink=$1
shift
install_system_lib $lib $symlink
done
}
install_bin () {
echo "Installing /opt/bin/$1"
t_cp $tmp_dir/bin/$1 /opt/bin/$1
t_chmod 755 /opt/bin/$1
}
install_ipkg () {
adb push opt $tmp_dir
t_mkdir_p /opt/bin
t_mkdir_p /opt/lib
install_bin ipkg
t_cp $tmp_dir/lib/libipkg.so.0.0.0 /opt/lib/libipkg.so.0.0.0
t_cd_ln /opt/lib/ -s libipkg.so.0.0.0 libipkg.so.0
t_cd_ln /opt/lib/ -s libipkg.so.0.0.0 libipkg.so
}
fetch_package_index () {
if [ ! -f Packages ]; then
echo "Downloading Optware package index"
wget -q $FEED/Packages
else
echo "Using cached Optware package index"
fi
}
get_package_fname () {
awk "/^Filename: ${1}_/ {print \$2}" Packages
}
fetch_package () {
if [ -z "$1" ]; then
echo "Unexpected error: package '$1' not found in index"
exit 1
fi
if [ ! -f "$1" ]; then
echo "Downloading Optware package $1"
wget -q $FEED/$1
else
echo "Using cached package $1"
fi
}
fetch_toolchain () {
if [ ! -f $cs08q1_fname ]; then
echo "You need CodeSourcery ARM-Linux toolchain release 2008q1: $cs08q1_fname"
echo "if you have this file on your system already, press Ctrl-C now and copy"
echo "it into the current directory. Otherwise, press Enter to download it (65MB)."
read
wget $cs08q1_url
fi
}
optware_uninstall () {
t_remount_rw /
adb shell su -c "rm -r $OPTWARE_DIR"
adb shell su -c "rm /lib"
adb shell su -c "rm /bin"
adb shell su -c "rm /opt"
adb shell su -c "rm /tmp"
t_remount_ro /
t_remount_rw /system
adb shell su -c "rm /etc/resolv.conf"
adb shell su -c "rm /etc/mtab"
adb shell su -c "rm /etc/passwd"
adb shell su -c "rm /etc/group"
t_rm_rf $tmp_dir
t_remount_ro /system
echo "Optware sucessfully uninstalled"
}
#
# Main code
#
if [ "$1" == "" ]; then
echo "This script installs NSLU Optware on an Android device connected using ADB"
echo "Usage: $0 install|uninstall"
exit 1
fi
if [ "$1" == "uninstall" ]; then
optware_uninstall
exit
fi
fetch_toolchain
fetch_package_index
ipkg_fname=$(get_package_fname ipkg-opt)
wget_fname=$(get_package_fname wget)
busybox_fname=$(get_package_fname busybox-base)
fetch_package $ipkg_fname
fetch_package $wget_fname
fetch_package $busybox_fname
t_remount_rw /
# Start from scratch
echo "== Initializing optware environment =="
t_rm_rf $tmp_dir
t_mkdir_p $tmp_dir
t_mkdir_p $OPTWARE_DIR
t_cd_ln . -s $OPTWARE_DIR /opt
t_mkdir_p $OPTWARE_DIR/rootbin
t_cd_ln . -s $OPTWARE_DIR/rootbin /bin
t_mkdir_p $OPTWARE_DIR/rootlib
t_cd_ln . -s $OPTWARE_DIR/rootlib /lib
t_mkdir_p $OPTWARE_DIR/tmp
t_cd_ln . -s $OPTWARE_DIR/tmp /tmp
t_mkdir_p $OPTWARE_DIR/home
t_mkdir_p $OPTWARE_DIR/home/root
t_mkdir_p $OPTWARE_DIR/home/user
echo "== Installing libc =="
extract_libc
install_libc $libc_libs
install_system_bin usr/bin/ldd
echo "== Installing bootstrap ipkg =="
rm -rf opt
tar -xOzf $ipkg_fname ./data.tar.gz | tar -xzf -
install_ipkg
echo "== Installing bootstrap wget =="
rm -rf opt
tar -xOzf $wget_fname ./data.tar.gz | tar -xzf -
adb push opt $tmp_dir
install_bin wget
echo "== Installing bootstrap busybox =="
rm -rf opt
tar -xOzf $busybox_fname ./data.tar.gz | tar -xzf -
adb push opt $tmp_dir
install_bin busybox
echo "== Initializing bootstrap /bin =="
# We need sane shell as /bin/sh
t_cd_ln /bin -s /opt/bin/busybox sh
# We need minimal set of sane shell commands to run update-alternatives
# script to properly (re)install busybox itself
t_cd_ln /bin -s /opt/bin/busybox echo
t_cd_ln /bin -s /opt/bin/busybox rm
t_cd_ln /bin -s /opt/bin/busybox rmdir
t_cd_ln /bin -s /opt/bin/busybox sed
t_cd_ln /bin -s /opt/bin/busybox mkdir
t_cd_ln /bin -s /opt/bin/busybox head
t_cd_ln /bin -s /opt/bin/busybox sort
t_cd_ln /bin -s /opt/bin/busybox dirname
t_cd_ln /bin -s /opt/bin/busybox ln
t_cd_ln /bin -s /opt/bin/busybox mv
t_cd_ln /bin -s /opt/bin/busybox cat
t_cd_ln /bin -s /opt/bin/busybox chown
t_cd_ln /bin -s /opt/bin/busybox chmod
# gzip and tar should be part of Android, but there were reports
# that some implementations may be broken
t_cd_ln /bin -s /opt/bin/busybox tar
t_cd_ln /bin -s /opt/bin/busybox gzip
echo "== Configuring package feed =="
t_mkdir_p /opt/etc
t_mkdir_p /opt/etc/ipkg
adb shell su -c "echo src cross $FEED >/opt/etc/ipkg/feeds.conf"
echo "== Configuring domain name resolution =="
adb shell su -c "echo nameserver 8.8.8.8 >/opt/etc/resolv.conf"
# On a normal Android system, /etc is symlink to /system/etc, but just in case...
t_mkdir_p /etc
# but for normal system, we need to remount /system
t_remount_rw /system
t_rm_f /etc/resolv.conf
t_cd_ln . -s /opt/etc/resolv.conf /etc/resolv.conf
echo "== Configuring GLIBC Namespace Switch =="
adb push nsswitch.conf $tmp_dir/nsswitch.conf
t_cp $tmp_dir/nsswitch.conf /etc/nsswitch.conf
t_chmod 0644 /etc/nsswitch.conf
t_rm_f $tmp_dir/nsswitch.conf
echo "== Configuring /etc/mtab =="
t_cd_ln . -s /proc/mounts /etc/mtab
echo "== Configuring users =="
adb shell su -c "echo root:x:0:0:root:/opt/home/root:/bin/sh >/opt/etc/passwd"
adb shell su -c "echo shell:x:2000:2000:shell:/opt/home/user:/bin/sh >>/opt/etc/passwd"
t_cd_ln . -s /opt/etc/passwd /etc/passwd
echo "== Configuring groups =="
adb shell su -c "echo root:x:0:root >/opt/etc/group"
adb shell su -c "echo shell:x:2000:shell >>/opt/etc/group"
t_cd_ln . -s /opt/etc/group /etc/group
t_remount_ro /system
echo "== Creating optware init script =="
adb shell su -c "echo \#\!/system/bin/sh >/opt/optware-init.sh"
adb shell su -c "echo 'ls /opt >/dev/null 2>&1 && exit' >>/opt/optware-init.sh"
adb shell su -c "echo echo Reinitializing optware rootfs links >>/opt/optware-init.sh"
adb shell su -c "echo mount -o rw,remount rootfs / >>/opt/optware-init.sh"
adb shell su -c "echo ln -s $OPTWARE_DIR /opt >>/opt/optware-init.sh"
adb shell su -c "echo ln -s $OPTWARE_DIR/rootlib /lib >>/opt/optware-init.sh"
adb shell su -c "echo ln -s $OPTWARE_DIR/rootbin /bin >>/opt/optware-init.sh"
adb shell su -c "echo ln -s $OPTWARE_DIR/tmp /tmp >>/opt/optware-init.sh"
adb shell su -c "echo mount -o ro,remount rootfs / >>/opt/optware-init.sh"
t_chmod 0755 /opt/optware-init.sh
echo "== Creating optware startup script =="
adb shell su -c "echo \#\!/system/bin/sh >/opt/$start_script"
adb shell su -c "echo 'ls /opt >/dev/null 2>&1 ||' su -c $OPTWARE_DIR/optware-init.sh >>/opt/$start_script"
adb shell su -c "echo \# You may want to add /opt/local/bin to PATH below >>/opt/$start_script"
adb shell su -c "echo export PATH=/opt/sbin:/opt/bin:/bin:/system/bin >>/opt/$start_script"
adb shell su -c "echo 'if busybox test \\\$(busybox id -u) = 0; then HOME=/opt/home/root; else HOME=/opt/home/user; fi' >>/opt/$start_script"
adb shell su -c "echo export HOME>>/opt/$start_script"
adb shell su -c "echo export TMPDIR=/tmp >>/opt/$start_script"
adb shell su -c "echo umask 022 >>/opt/$start_script"
adb shell su -c "echo /bin/sh >>/opt/$start_script"
t_chmod 0755 /opt/$start_script
# Create "s" symlink to ease typing on touchscreen devices
t_cd_ln /opt -s $start_script s
t_remount_ro /
echo "== Reinstalling bootstrap packages =="
echo "Make sure that your device is woken up and connected to the Internet"
echo "Press Enter to continue"
read
#
# Now that we have all dependencies to run ipkg bootstraped on device,
# we need to use ipkg to reinstall itself and all those dependencies,
# to make sure they're installed and configured properly.
#
adb shell PATH=/opt/bin:/bin /opt/bin/ipkg update
adb shell PATH=/opt/bin:/bin /opt/bin/ipkg install ipkg-opt
adb shell PATH=/opt/bin:/bin /opt/bin/ipkg install wget
adb shell PATH=/opt/bin:/bin /opt/bin/ipkg install busybox
echo "== Cleaning device tmp directory =="
t_rm_rf $tmp_dir
echo "== Cleaning local directory =="
rm -rf opt arm-2008q1
echo "Optware for Android installation complete."
echo "To start optware session, execute $OPTWARE_DIR/$start_script (aka $OPTWARE_DIR/s) on the device"