Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
executable file 390 lines (332 sloc) 11.7 KB
# NSLU2-Linux Optware setup script for Android
# Copyright (c) 2012 Paul Sokolovsky <>
# License: GPLv3,
# Optware ARM binary packages repositories (aka feeds):
# Optware source code Subversion repository:
# svn co
#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.)
# Particular field to install from, stable by default
# DO NOT edit anything below this line unless you know what you are doing
cs08q1_fname=$(basename $cs08q1_url)
libc_libs="lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
lib/ \
# On-target (device) commands
t_cp () {
# copy file on a device
adb shell su -c "cat $1 >$2"
t_cd_ln () {
local dir=$1
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
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
local symlink=$1
install_system_lib $lib $symlink
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/ /opt/lib/
t_cd_ln /opt/lib/ -s
t_cd_ln /opt/lib/ -s
fetch_package_index () {
if [ ! -f Packages ]; then
echo "Downloading Optware package index"
wget -q $FEED/Packages
echo "Using cached Optware package index"
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
if [ ! -f "$1" ]; then
echo "Downloading Optware package $1"
wget -q $FEED/$1
echo "Using cached package $1"
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)."
wget $cs08q1_url
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
if [ "$1" == "uninstall" ]; then
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 =="
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 -
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 >/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/"
adb shell su -c "echo 'ls /opt >/dev/null 2>&1 && exit' >>/opt/"
adb shell su -c "echo echo Reinitializing optware rootfs links >>/opt/"
adb shell su -c "echo mount -o rw,remount rootfs / >>/opt/"
adb shell su -c "echo ln -s $OPTWARE_DIR /opt >>/opt/"
adb shell su -c "echo ln -s $OPTWARE_DIR/rootlib /lib >>/opt/"
adb shell su -c "echo ln -s $OPTWARE_DIR/rootbin /bin >>/opt/"
adb shell su -c "echo ln -s $OPTWARE_DIR/tmp /tmp >>/opt/"
adb shell su -c "echo mount -o ro,remount rootfs / >>/opt/"
t_chmod 0755 /opt/
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/ >>/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"
# 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"