#!/bin/bash # # Auto-Installer for Debian on the Openmoko Neo phones (GTA01 and GTA02) # # Copyright 2008 Joachim Breitner # Copyright 2008-2009 Luca Capello # Copyright 2009 Steffen Moeller # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. set -e # This helper function expects names of variables as arguments # and converts all their contents to lower case. lc () { # chosing a rarely seen variable name to avoid masking for i_____i in $* do cmd="$i_____i=\$(echo \$$i_____i|tr 'A-Z' 'a-z')" #echo $cmd eval $cmd done } # # INSTALLER CONFIGURATION # # user variables APT_OPTIONS=${APT_OPTIONS:- --yes} APT_RECOMMENDS=${APT_RECOMMENDS:-false} BOOTSTRAPPER=${BOOTSTRAPPER:-cdebootstrap} CDEBOOTSTRAP_EXTRA_FLAGS=${CDEBOOTSTRAP_EXTRA_FLAGS:-} DASH_BINSH=${DASH_BINSH:-true} DEBOOTSTRAP_EXTRA_FLAGS=${DEBOOTSTRAP_EXTRA_FLAGS:-} DISPLAY_MANAGER=${DISPLAY_MANAGER:-nodm} FSO_MIRROR=${FSO_MIRROR:-http://pkg-fso.alioth.debian.org/debian} INST_DIR=${INST_DIR:-/mnt/debian} INST_MIRROR=${INST_MIRROR:-http://ftp2.de.debian.org/debian} LOCALEPURGE=${LOCALEPURGE:-} QI=${QI:-false} QI_VERBOSE_BOOT=${QI_VERBOSE_BOOT:-false} ROOT_PASSWORD=${ROOT_PASSWORD:-changeme} SD_DEVICE=${SD_DEVICE:-/dev/mmcblk0} SD_SYS_BLK=${SD_SYS_BLK:-/sys/block/${SD_DEVICE#/dev/}} SD_PART1_FS=${SD_PART1_FS:-ext2} SD_PART1_SIZE=${SD_PART1_SIZE:-8} SD_PART2_FS=${SD_PART2_FS:-ext3} SD_SWAP_SIZE=${SD_SWAP_SIZE:-0} SINGLE_PART=${SINGLE_PART:-$QI} TRAYER=${TRAYER:-trayer} ZHONE=${ZHONE:-true} # let us all see the same error messages and possibly suppress some by apt-get export LANG=C.UTF-8 # hardening for the case that a user uses capitals lc APT_RECOMMENDS BOOTSTRAPPER FSO_DEVICE QI QI_VERBOSE_BOOT SD_PART1_FS SD_PART2_FS # device autodetection if the user has not set FSO_DEVICE FSO_DEVICE_AUTODETECTED=`grep GTA /proc/cpuinfo | awk '{print $3}' | tr "[:upper:]" "[:lower:]"` if [ -z "$FSO_DEVICE" -a -n "$FSO_DEVICE_AUTODETECTED" ]; then FSO_DEVICE=$FSO_DEVICE_AUTODETECTED fi # this is an user variable, which by default depends on the FSO_DEVICE value HOSTNAME=${HOSTNAME:-debian} if [ "$HOSTNAME" = debian ]; then HOSTNAME="debian-$FSO_DEVICE" fi # general variables VERBOSE=${VERBOSE:-} TESTHOST=${TESTHOST:-www.debian.org} RDATEHOST=${RDATEHOST:-ntp.fu-berlin.de} DROPBEAR_KEYS="/etc/dropbear/dropbear_rsa_host_key /etc/dropbear/dropbear_dss_host_key" MOUNT_PROC=true # internal variables internal_version="3.1" # the version of this file intern_instdir_already_present="" intern_no_partitioning="" # debootstrap and cdebootstrap options # with packages for a basic debian with network connectivity CDEBOOTSTRAP_FLAVOUR=minimal DEBOOTSTRAP_VARIANT=minbase CDEBOOTSTRAP_PACKAGE=$INST_MIRROR/pool/main/c/cdebootstrap/cdebootstrap-static_0.5.9_armel.deb DEBOOTSTRAP_PACKAGE=$INST_MIRROR/pool/main/d/debootstrap/debootstrap_1.0.42_all.deb CDEBOOTSTRAP_EXTRA_PACKAGES= DEBOOTSTRAP_EXTRA_PACKAGES=install-info # This gets passed to boot strappers. currently not used BOOTSTRAP_EXCLUDE_PACKAGES=hello # Those packages should be installed with every Debian install, invariant of the bootstrapper used. DEBIAN_EXTRA_PACKAGES=ifupdown,dropbear,udev,procps,netbase,vim-tiny,module-init-tools,wget,openssh-client # freesmartphone.org packages # because of some apt-get bug, console-setup must be listed # before any other X.Org package, for more information see # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=435662#45 FSO_PACKAGES="matchbox-window-manager fso-frameworkd openmoko-panel-plugin dbus-x11 $TRAYER fso-utils mtd-utils \ console-setup xserver-xorg-core xorg omhacks xserver-xorg-video-glamo xserver-xorg-input-tslib xterm xinit xfonts-base x11-xserver-utils" # well-suited software for the FreeRunner PACKAGES_TASK_AUDIO="intone" PACKAGES_TASK_GAMES="mokomaze sgt-puzzles" PACKAGES_TASK_GPS="gpsd foxtrotgps monav navit" PACKAGES_TASK_COM="phoneui-apps pidgin" PACKAGES_TASK_NET="inetutils-ping host iptables" PACKAGES_TASK_TEXT="less" PACKAGES_TASK_WEB="midori epdfview" PACKAGES_TASK_WIFI="wicd dhcp3-client wpasupplicant wireless-tools" PACKAGES_TASK_UTILS="scrot debfoster" # tasks defined intern_tasks_defined="AUDIO,GAMES,GPS,COM,NET,TEXT,WEB,WIFI,UTILS" # device-specific values UBOOT_ENV_SIZE=262144 # mkfs.vfat is not installed by default in most of the Openmoko images DOSFSTOOLS_PACKAGE=$INST_MIRROR/pool/main/d/dosfstools/dosfstools_3.0.1-1_armel.deb # FSO-MS5 busybox's tar does not support -z TAR_PACKAGE=$INST_MIRROR/pool/main/t/tar/tar_1.26-2_armel.deb TAR_APPLICATION=tar # # FUNCTIONS # # for the installation of packages, /proc is sometimes required to be # installed. cdebootstrap is installing it itself. ensure_proc_is_mounted () { if [ -z "$MOUNT_PROC" ]; then if [ ! -r "$INST_DIR"/proc/cpuinfo ]; then echo "W: /proc not mounted in chroot, install may fail." fi return 0; fi if [ ! -d "$INST_DIR/proc" ]; then mkdir "$INST_DIR/proc"; fi if mount | grep -q "$INST_DIR/proc"; then if [ -n "$VERBOSE" ]; then echo "I: /proc is already mounted in chroot" fi return 0; fi if mount -t proc none "$INST_DIR/proc"; then echo "I: installed /proc in chroot" return 0; else echo "E: could not mount /proc in chroot" return 1; fi } # cdebootstrap performs that automatically, but we need to take some # extra precaution when installing packages that would normally # start services. Those might interfere with local services or just # expect bits to be mounted that are not mounted or ... you name it. diverting_invoke_rc_d () { if [ ! -r "$INST_DIR"/usr/sbin/invoke-rc.d.diverted ]; then mv "$INST_DIR"/usr/sbin/invoke-rc.d "$INST_DIR"/usr/sbin/invoke-rc.d.diverted echo "I: diverted invoke-rc.d" else echo "I: invoke-rc.d is already diverted - was previous install interrupted?" # continuing anyway, since functional existence of dummy is not guaranteed. fi cat > "$INST_DIR"/usr/sbin/invoke-rc.d < DESCRIPTION This script is to be executed on an OpenMoko Neo devices (either 1973 or FreeRunner), two openly designed telephones, to install the Debian operating system on an SD card. The system goes through multiple stages, and can be modified to adapt to local preferences. The individual stages are described below. The script uses cdebootstrap or debootstrap to prepare a directory to which it can chroot(8) and complete the configuration. ENVIRONMENT To influence the program's behaviour, set the following environment variables or leave the default values. APT_OPTIONS extra parameters sent to apt for installing packages (set to '$APT_OPTIONS'). HOSTNAME the name of the machine (set to '$HOSTNAME'). SD_DEVICE the character device to access the microSD card (set to '$SD_DEVICE'). SD_SYS_BLK the directory under /sys/block that refers to the microSD card (set to '$SD_SYS_BLK', or derived from the value of SD_DEVICE). SD_PART1_FS the filesystem for the first microSD card partition, i.e. the one containing the uImage.bin (set to '$SD_PART1_FS', possible values are ext2/vfat, also ext3 when using Qi as bootloader). SD_PART1_SIZE number of megabytes for first partition (set to '$SD_PART1_SIZE'). SD_SWAP_SIZE number of megabytes of swap partition (set to '$SD_SWAP_SIZE'). INST_DIR the directory where the microSD card partitions will be mounted to (set to '$INST_DIR'). INST_MIRROR the Debian mirror used during installation, it should be set to a mirror nearby that carries armel binaries for unstable (set to '$INST_MIRROR'). LOCALEPURGE set this to true, if you want to install the package of the same name. It reduces disk space enormously, but needs user interaction for the install (set to '$LOCALEPURGE'). APT_RECOMMENDS control if APT should install recommends by default (set to '$APT_RECOMMENDS', possible values are false/true). BOOTSTRAPPER determines the bootstrapper to use, should be set to deboostrap or cdebootstrap - cdebootstrap is somewhat faster and you may have to "opkg install perl", but it seems to work less reliably (set to '$BOOTSTRAPPER'). For debootstrap please do not run anything besides install.sh as you will need all your memory. CDEBOOTSTRAP_EXTRA_FLAGS parameters to be added to invocation of cdebootstrap, only active if BOOTSTRAPPER is not set to debootstrap. DASH_BINSH configure dash as default /bin/sh (set to '$DASH_BINSH', possible values are true/false). DEBOOTSTRAP_EXTRA_FLAGS parameters to be added to invocation of debootstrap, only active if BOOTSTRAPPER is not set to cdebootstrap. FSO_MIRROR the Debian freesmartphone.org repository (set to '$FSO_MIRROR'). FSO_DEVICE the device the installation is being performed on (set to '$FSO_DEVICE', default to autodetection, possible values are gta01/gta02). QI if you use Qi bootloader set this to true (set to '$QI'). QI_VERBOSE_BOOT set this to true if you want to see the kernel messages; do this only when QI=true (set to '$QI_VERBOSE_BOOT'). RDATEHOST machine with which to sync against with ntp (set to '$RDATEHOST'). SINGLE_PART set this to true if only one partition should be created; this is true by default for QI=true and false if SD_PART1_FS=vfat (set to '$SINGLE_PART'). TRAYER name of package to fill the menu bar, supported are 'trayer' and 'stalonetray' (set to '$TRAYER'). TESTHOST name of machine that should be tested for availability (set to '$TESTHOST'). VERBOSE increase amount of information that is forwarded to stdout (set to '$VERBOSE'). DISPLAY_MANAGER choose the Display Manager to be installed (default to '$DISPLAY_MANAGER', possible values are any *dm package in the Debian archive, which could require a LOT of disk space; set this to none if you do not want a Display Manager). ZHONE set this to true to install the Zhone GUI (set to '$ZHONE'). ROOT_PASSWORD the password for the root account (set to '$ROOT_PASSWORD'). Stages: all Runs all the stages in the following order: testing time partition format mount debian apt fso configuration tasks kernel cleanup unmount testing Verifys that everything is in place for this installer to work time Fetches the current time from $RDATEHOST via rdate partition Partitions the microSD card found in $SD_DEVICE (WARNING, this will destroy all the data on the microSD card unless the partioning is the same as used before; this can be used to recover a broken partiton table due to the suspend/resume problem) format Formats the microSD card found in '$SD_DEVICE' (WARNING, this will destroy all the data on the microSD card) mount Mounts microSD card partitions under '$INST_DIR' debian Installs a basic Debian system, including an SSH server apt Configure APT fso Install freesmartphone.org packages (by default this also include the Zhone GUI, see the ZHONE variable) tasks Installs packages for a series of tasks. Supported are AUDIO ($PACKAGES_TASK_AUDIO) COM software supporting the communication of users ($PACKAGES_TASK_COM). GAMES installs games that were designed with FreeRunner-like devices in mind or that have been found compatible ($PACKAGES_TASK_GAMES) GPS software for GPS, geocaching and navigation ($PACKAGES_TASK_GPS) NET software that is beneficial to investigate the network setup and/or forward traffic to USB-attached devices, e.g. to connect a a laptop to the internet via the freephone's internet connection (GPRS or Wifi). See http://wiki.openmoko.org/wiki/Tethering for the setup ($PACKAGES_TASK_NET). TEXT allows improved handling of text ($PACKAGES_TASK_TEXT) WEB ($PACKAGES_TASK_WEB) WIFI ($PACKAGES_TASK_WIFI) UTILS whatever was wanted that does not belong to the other classes ($PACKAGES_TASK_UTILS) ALL Selection of all the tasks listed above. To specify the tasks shall be assigned to the TASKS environment variable as a comma separated list (set to '$TASKS'). configuration Configures various parts of the system, such as the X server kernel Downloads and installs the Debian kernel package (only when SD_PART1_FS is set to ext2, now '$SD_PART1_FS') cleanup Remove unnecessary package and clean APT cache unmount Unmounts the Debian filesystem mounted at '$INST_DIR' Unsupported or buggy stages, use at your own risk: uboot Configures the U-Boot environment to boot Debian (it needs to run between the debian and the unmount stage, only when SD_PART1_FS is set to ext2, now '$SD_PART1_FS') OPTIONS For users uncomfortable with setting environment variables, the following options have been implemented to be set as arguments: -h|--help shows this information --verbose same as invocation with VERBOSE=true as environment variable --apt-options sets the APT_OPTIONS variable --hostname sets the HOSTNAME variable --mount-proc mounts /proc directory in Debian chroot -np|--no-partitioning disable the partitioning when otherwise doing "all" --part1-fs sets the SD_PART1_FS variable --part1-size sets the SD_PART1_SIZE variable --swap-size sets the SD_SWAP_SIZE variable --with-tasks sets the TASKS variable --with-localepurge will install the localepurge package --trayer sets the TRAYER variable --bootstrapper (debootstrap|cdebootstrap) sets the BOOTSTRAPPER variable EXAMPLE Next to your install.sh script you may want to create a file that remembers the parameters for you that you have chosen for your previous setup. ./install.sh --part1-fs vfat --part1-size 16 all Performs a complete installation. Tasks would be addressed if the TASKS environment variable would have been set. TASKS="GAMES,GPS" ./install.sh --part1-fs vfat --part1-size 16 all As before, but now extra packages are installed (and configured) to prepare a selection of games and a reasonably complete utilisation of the GPS funcionality. TASKS="GAMES,GPS" ./install.sh --part1-fs vfat --part1-size 16 tasks This is the delta between the prior two examples. TASKS="GAMES,GPS" ./install.sh --part1-fs vfat --part1-size 16 E: This does nothing since no install target is defined. BUGS Only the current (second) generation of devices is fully supported. This script should be functional with the GTA01 except for the installation of the kernel. For comments or contributions, you can directly send emails to the list mentioned below. However, please be aware of the pkg-fso git repository that helps orchestrating our efforts. You can check it out with git clone git://git.debian.org/pkg-fso/files.git perform your changes and prepare patches with git format-patch origin/master to send to the authors or to the pkg-fso mailing list pkg-fso-maint@lists.alioth.debian.org . AUTHORS Copyright 2008 Joachim Breitner Copyright 2008 Luca Capello Copyright 2009 Steffen Moeller This program is licensed under the terms of GNU General Public License either version 2, or (at your option) any later version. SEE ALSO This project's homepage: http://wiki.debian.org/DebianOnFreeRunner The OpenMoko project: http://www.openmoko.org __END__ exit 0 } vfat_check () { # /boot on vfat is no more supported (http://bugs.debian.org/315493) # http://lists.linuxtogo.org/pipermail/smartphones-userland/2008-November/000502.html if [ "$SD_PART1_FS" = "vfat" ]; then cat <<__END__ *********** * WARNING * *********** For the /boot partition you have chosen to use vfat, which is not a POSIX-compliant filesystem. Because dpkg, the Debian package manager, does not support non-POSIX filesystems, the Debian kernel package can not be installed. More information are available at http://bugs.debian.org/315493. Press any key within 5 seconds to quit __END__ five_seconds_to_quit SINGLE_PART="false" fi } # # Stage all # action_all () { cat <<__END__ I: Running all stages with these settings: I: hostname set to $HOSTNAME I: microSD card device at $SD_DEVICE I: $SD_PART1_FS as filesystem for the first microSD card partition I: installing into '$INST_DIR' I: using Debian mirror at $INST_MIRROR I: APT recommends set to $APT_RECOMMENDS I: dash as default /bin/sh set to $DASH_BINSH __END__ for f in testing time partition format mount debian apt fso configuration tasks kernel cleanup unmount do case "$f" in "partition") if [ -n "$intern_no_partitioning" ]; then echo " * Skipping partitioning since --no-partitioning flag set" else action_partition fi ;; "tasks") if [ -z "$TASKS" ]; then echo " * Skipping over installing tasks since none were specified" else action_tasks fi ;; *) if [ -n "$VERBOSE" ]; then echo "calling '$f'"; fi action_$f ;; esac done cat <<__END__ I: All done! __END__ if [ "$SD_PART1_FS" = "vfat" ]; then echo "Now reboot, switch on the Openmoko FreeRunner with both AUX+PWR," echo "buttons, choose \"Boot from microSD (FAT+ext2)\" and wait!" else echo "Now reboot, and hope for the best!" fi echo exit 0 } # # Stage test # action_testing () { echo "I: Testing system setup" intern_packages_required="wget ping fdisk mount umount mkfs.$SD_PART1_FS mkswap gunzip dd sed rdate ar basename dirname" if [ "mkfs.$SD_PART2_FS" != "mkfs.$SD_PART1_FS" ]; then intern_packages_required="$intern_packages_required mkfs.$SD_PART2_FS" fi if [ "deboostrap" = "$BOOTSTRAPPER" ]; then intern_packages_required="$intern_packages_required perl" fi intern_packages_missing="" intern_extra_information="" for intern_binary in $intern_packages_required; do if ! which $intern_binary > /dev/null; then if [ -n "$VERBOSE" ]; then echo " * Missing binary '$intern_binary'" fi intern_packages_missing="$intern_packages_missing $intern_binary" if [ "ar" = "$intern_binary" ]; then intern_extra_information="${intern_extra_information}\n the 'ar' binary is expected to ship with a package named 'binutils'" fi fi if [ -n "$VERBOSE" ]; then echo " * $intern_binary installed" fi done if [ -n "$intern_packages_missing" ]; then echo -e "E: Could not find the following binaries: $intern_packages_missing.$intern_extra_information" exit 1 fi if ! test -e $SD_DEVICE; then echo "E: Could not find microSD card device file $SD_DEVICE" exit 1 fi echo " * microSD card device: $SD_DEVICE present" if $TAR_APPLICATION --help 2>&1 | grep "Usage: $TAR_APPLICATION \-\[cxtvO\]" >/dev/null; then echo "W: $TAR_APPLICATION does not support gzip archives" echo "Downloading tar package" wget $TAR_PACKAGE -O /tmp/tar.deb rm -f /tmp/data.tar.gz # FIXME: ar should just overwrite it ( cd /tmp && ar -x tar.deb data.tar.gz ) mkdir -p /usr/local gunzip -c /tmp/data.tar.gz | $TAR_APPLICATION -x -C /usr/local/ TAR_APPLICATION=/usr/local/bin/tar rm -f /tmp/data.tar.gz rm -f /tmp/tar.deb fi if [ "$SD_PART1_FS" = "vfat" ]; then if ! which mkfs.vfat >/dev/null; then echo "W: Could not find mkfs.vfat binary" # it should try first to install dosfstools through opkg # and then try to install the Debian dosfstools echo "Downloading dosfstools package" wget $DOSFSTOOLS_PACKAGE -O /tmp/dosfstools.deb rm -f /tmp/data.tar.gz # FIXME: ar should just overwrite it ( cd /tmp && ar -x dosfstools.deb data.tar.gz ) $TAR_APPLICATION -xz -C / -f /tmp/data.tar.gz rm -f /tmp/data.tar.gz rm -f /tmp/dosfstools.deb fi # let's test again for safety reasons if ! which mkfs.vfat >/dev/null; then echo "E: Could not find mkfs.vfat binary" exit 1 else echo " * mkfs.vfat installed" fi fi if [ $(uname -m) != armv4tl ]; then echo "E: System is not claiming to be an armv4tl." echo " Are you sure that this is your Openmoko FreeRunner (GTA02)?" exit 1 fi if ! ping -c 2 $TESTHOST > /dev/null; then echo "E: Could not ping $TESTHOST, is the network running?" exit 1 fi echo " * network running" if ps -C qpe >/dev/null; then echo "E: Qtopia wants to continually access /media/card. You need to" echo -n " stop it with " if [ -x "/etc/init.d/qpe" ]; then echo -n "\`/etc/init.d/qpe stop\` or" elif [ -x "/etc/init.d/qpe.sh" ]; then echo -n "\`/etc/init.d/qpe.sh stop\` or" fi echo " \`killall qpe\`" echo " and then restart the installation!" exit 1 fi echo "I: Testing system setup - done - looks good" } # # Stage time # action_time () { echo "Fetching time from $RDATEHOST with rdate" rdate -s "$RDATEHOST" >/dev/null 2>&1 echo "I: Time is now `date`" } # # Stage partitioning # action_partition () { echo "I: Partitioning SD" card_data_warning partition umount_all # put the partition table in a "known state" echo " * Clearing MBR of SD." if ! dd if=/dev/zero of=$SD_DEVICE bs=512 count=1 >/dev/null 2>&1; then echo "Clearing MBR of SD with dd failed ($?)." exit 1 fi # run partitioner bootfstypeno=83 if [ -z "$SD_SWAP_SIZE" ]; then SD_SWAP_SIZE=0; fi mb=$(( $(cat /sys/block/mmcblk0/size) * 8 / 15625 )) # If one were willing to assume that cylinders are always 64 * 512, then we could calculate the # next line thus: $(( $(cat /sys/block/mmcblk0/size) / 64 )) cylinders=$(echo -e "p\nq" | fdisk ${SD_DEVICE} | grep cylinders|grep heads|cut -f 5 -d\ ) lastcylinder=$(($cylinders-($cylinders*$SD_SWAP_SIZE/$mb))) ##### TODO: Evaluate the suggestion by x #+# mb=$(echo pq | fdisk /dev/mmcblk0 | grep Disk | cut -f 3 -d \ ) #+ mb=$(sfdisk -s ${SD_DEVICE} 2>/dev/null) #+# cylinders=$(echo -e "p\nq" | fdisk /dev/mmcblk0 | grep cylinders | grep heads | cut -f 5 -d\ ) #+ cylinders=$(sfdisk -G ${SD_DEVICE} 2>/dev/null | grep "^${SD_DEVICE}" | awk "{ print \$2 }") #+ lastcylinder=$(($cylinders-($cylinders*$SD_SWAP_SIZE/($mb/1024)))) # if [ "vfat" = "$SD_PART1_FS" ]; then bootfstypeno=4 fi partitionno=0 if [ "$SINGLE_PART" = "true" ]; then echo "Preparing SD as a single Linux device." partitionno=$(($partitionno+1)) cat < /tmp/argsToFdisk$$ n p $partitionno $lastcylinder EOSINGLECONF else partitionno=$(($partitionno+1)) cat < /tmp/argsToFdisk$$ n p $partitionno +${SD_PART1_SIZE}M t $bootfstypeno EOBOOTCONF partitionno=$(($partitionno+1)) cat <> /tmp/argsToFdisk$$ n p $partitionno $lastcylinder t $partitionno 83 EOROOTCONF fi if [ 0 -lt "$SD_SWAP_SIZE" ]; then partitionno=$(($partitionno+1)) cat <> /tmp/argsToFdisk$$ n p $partitionno t $partitionno 82 p EOSWAPCONF fi echo "w" >> /tmp/argsToFdisk$$ if fdisk $SD_DEVICE < /tmp/argsToFdisk$$; then echo "Partitioning was successful." if [ -n "$VERBOSE" ]; then echo "The following partitions have been created:" echo -e "p\nq" | fdisk $SD_DEVICE fi #rm /tmp/argsToFdisk$$ else echo "Partitioning failed, could not execute with fdisk:" cat /tmp/argsToFdisk$$ exit 1 fi echo " * Waiting for partitions to appear" intern_sleep_seconds=3 if [ "$SINGLE_PART" = "true" ]; then intern_devtest="test -e ${SD_DEVICE}p1" else intern_devtest="test -e ${SD_DEVICE}p1 -a -e ${SD_DEVICE}p2" fi while ! $intern_devtest; do if [ "$intern_sleep_seconds" = 15 ]; then echo "E: Partitioning has failed, partitions have not been created" exit 1 fi sleep 3 intern_sleep_seconds=$(( $intern_sleep_seconds + 3 )) done echo "I: Partitioning SD - done - Partition table created" } # # Stage format # action_format () { echo "I: Formatting SD" card_data_warning format umount_all if [ -z "$SD_SWAP_SIZE" ]; then SD_SWAP_SIZE=0; fi echo " * Formatting ${SD_PART1_FS} on ${SD_DEVICE}p1" mkfs.$SD_PART1_FS ${SD_DEVICE}p1 nextpart=2 if [ "$SINGLE_PART" != "true" ]; then echo " * Formatting ${SD_PART2_FS} on ${SD_DEVICE}p2" mkfs.$SD_PART2_FS ${SD_DEVICE}p2 nextpart=3 fi if [ 0 -lt "$SD_SWAP_SIZE" ]; then echo " * Formatting swap on ${SD_DEVICE}p${nextpart}" mkswap ${SD_DEVICE}p${nextpart} fi echo "I: Formatting SD - done - microSD card ready" } # # Stage mount # action_mount () { echo "I: Mounting the newly created system" if [ ! -d "$INST_DIR" ]; then mkdir -p "$INST_DIR"; intern_instdir_already_present="" elif [ -n "$VERBOSE" ]; then echo "Not creating directory '$INST_DIR', it is already existing." intern_instdir_already_present="true" fi if [ "$SINGLE_PART" = "true" ]; then if [ -n "$VERBOSE" ]; then echo "Preparing single ext2 device."; fi mount -t auto ${SD_DEVICE}p1 "$INST_DIR" mkdir -p "$INST_DIR/boot" else if [ -n "$VERBOSE" ]; then echo "Mounting root partition to '$INST_DIR'."; fi mount -t auto ${SD_DEVICE}p2 "$INST_DIR" if [ "vfat" = "$SD_PART1_FS" ]; then echo "You have a vfat boot filesystem. This is not mounted to /boot." else if [ ! -d "$INST_DIR/boot" ]; then mkdir "$INST_DIR/boot"; fi mount -t auto ${SD_DEVICE}p1 "$INST_DIR/boot" fi fi echo "I: Mounting the newly created system - done - microSD card partitions mounted" } # # Stage debian # action_debian () { echo "I: Install a basic Debian system" #For users of local apt proxy mkdir -p $INST_DIR/etc if [ -f /etc/hosts ]; then cp /etc/hosts $INST_DIR/etc echo "I: /etc/hosts copied from this machine" fi intern_bootstrapper_package= if [ "cdebootstrap" = "$BOOTSTRAPPER" ]; then intern_bootstrapper_package=$CDEBOOTSTRAP_PACKAGE elif [ "debootstrap" = "$BOOTSTRAPPER" ]; then intern_bootstrapper_package=$DEBOOTSTRAP_PACKAGE else echo "Unknown bootstrapper: '$BOOTSTRAPPER'" exit 1 fi if [ -x /usr/bin/"$BOOTSTRAPPER" ]; then echo echo "I: Found $BOOTSTRAPPER installed," echo " will nonetheless download reference version." echo fi echo " * Downloading bootstrapper package '`basename $intern_bootstrapper_package`'" if [ -n "$VERBOSE" ]; then echo " from $intern_bootstrapper_package"; fi internal_localpackagename=/tmp/debootstrapOrCdebootstrap.deb if ! wget $intern_bootstrapper_package -O "$internal_localpackagename"; then echo <> "$INST_DIR/etc/apt/sources.list" <<__END__ deb $INST_MIRROR unstable main deb $FSO_MIRROR unstable main __END__ echo " * Install APT recommends by default: $APT_RECOMMENDS" echo "APT::Install-Recommends \"$APT_RECOMMENDS\";" > "$INST_DIR/etc/apt/apt.conf.d/99recommends" echo " * Learning public key for pkg-fso-keyring" chroot "$INST_DIR" apt-key add - <<__END__ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.9 (GNU/Linux) mQGiBEicYhYRBACvesYUC+rkRpp0j/PTEimmuPkZqjLuRnpXqlCXV9Y1TZxvPmFl TwoeBHYoh3Uipbj0WypAJ3N989OQPiPo+lyrPNscRYc9+H/k7Q47Oc0ms23EQSWX AdnuhRezNF98cW/bmykVO9uZo+OjA501R9SCrMkhkbuifB57OMdXA0o67wCg0NWM EOAqQ/DCoo9Nqnb5sWotwisD/15dgunBY1BCyz8o7Ky1gn+Cel3LfNaqCIHwgCNf oxdAzHViNHMJa13Hab/nBY1GPpfJ3VIvLNs309JTDoKnYFvUkinvt+OJcY4z/3XN yloHhUoFBOSuZUy/xqB5PVrlQYJ07WKQHOkjvcp5LCH7pTLjCu8ih+YIIr4uipNl ZjBwA/9bCGQysO4xaHCR+qEZcQ1J4tW2A1g6Kr8p2CHxvGVCCQW7hhIRVIVGXF83 EViOVobmG8RHZFpAJzdsrJ/jkYBZp62wCs1DTljxLdMfY9vlKzpui3RSPv10fdPX t2iPG4Qc9Qm2H6LkWDfSJx6FLzDKrcj8tmbLTpr+fdJZtehudLRNcGtnLWZzbyBB cmNoaXZlIEF1dG9tYXRpYyBTaWduaW5nIEtleSA8cGtnLWZzby1tYWludEBsaXN0 cy5hbGlvdGguZGViaWFuLm9yZz6IYAQTEQIAIAIbAwYLCQgHAwIEFQIIAwQWAgMB Ah4BAheABQJKfuQXAAoJEOK53mqOezI71/IAnR6ZRbCHzuDRZecGvOtd8qNtcW+Q AJ9Cbbi6oyybgvrJ2KGjWXkoYTJnfw== =IG3W -----END PGP PUBLIC KEY BLOCK----- __END__ echo " * Updating APT database" chroot "$INST_DIR" apt-get update echo " * Installing pkg-fso keyring" diverting_invoke_rc_d # to ensure to avoid problem from previously failed installs # to spot this separate apt-get invocation cost me about 2h chroot "$INST_DIR" apt-get $APT_OPTIONS install pkg-fso-keyring restoring_invoke_rc_d echo " * Completing install of Debian basic packages to circumvent bug #542955" # dropbear at least cannot be installed without preventing the restart to happen diverting_invoke_rc_d chroot "$INST_DIR" apt-get $APT_OPTIONS install $(echo $DEBIAN_EXTRA_PACKAGES | tr "," " ") restoring_invoke_rc_d echo " * Cleaning APT cache" chroot "$INST_DIR" apt-get clean echo "I: Configuring APT - done - APT configured" } # # Stage fso # action_fso () { echo "I: Installing freesmartphone.org software" ensure_proc_is_mounted echo "* core packages" diverting_invoke_rc_d chroot "$INST_DIR" /bin/sh -e <<__END_CHROOT__ export DEBIAN_FRONTEND=noninteractive apt-get $APT_OPTIONS install $FSO_PACKAGES apt-get clean __END_CHROOT__ restoring_invoke_rc_d echo "skipped (\$ZHONE=$ZHONE)" echo "I: Installing freesmartphone.org software - done" } # # Stage tasks # # These steps shall be executed only after all basic packages # have been installed. # action_tasks () { if [ -z "$TASKS" ]; then if [ -n "$VERBOSE" ]; then echo echo "No task selected." echo fi return 0; fi # tasks should be defined case-invariantly TASKS=$(echo "$TASKS"|tr "a-z" "A-Z") if [ "ALL" = "$TASKS" ]; then TASKS="$intern_tasks_defined" fi echo "I: Performing selected tasks: $TASKS" ensure_proc_is_mounted for intern_task in $( echo $TASKS|tr "," " ") do echo " * task: $intern_task" eval chroot "$INST_DIR" apt-get install $APT_OPTIONS \$PACKAGES_TASK_$intern_task chroot "$INST_DIR" apt-get clean echo "I: Selection of packages for task '$intern_task' successfully installed." case "$intern_task" in "WIFI") echo " * modifying .xsession to autostart wicd-client" sed -i '/^exec/i#wicd-client --no-animate &' "$INST_DIR/root/.xsession" echo " * Installing wicd for wifi setup" if [ -r "$INST_DIR/etc/wicd/manager-settings.conf" ]; then grep -v ^wired_interface "$INST_DIR/etc/wicd/manager-settings.conf" > \ "$INST_DIR/etc/wicd/manager-settings.conf" else mkdir "$INST_DIR/etc/wicd" echo "[Settings]" >> "$INST_DIR/etc/wicd/manager-settings.conf" fi echo "wired_interface =" >> "$INST_DIR/etc/wicd/manager-settings.conf" chroot "$INST_DIR" apt-get install $APT_OPTIONS wicd echo " * All extra activity for task '$intern_task' completed." ;; *) echo " * No extra activity for task '$intern_task'." ;; esac done echo "I: Performing selected tasks - done" } # # Stage configuration # action_configuration () { echo "I: Configuring system files for ${FSO_DEVICE}" root_password_warning ensure_proc_is_mounted if [ "true" = "$LOCALEPURGE" ]; then echo " * installing localepurge" echo " ... skipped since Erich reported it to break unsupervised install" #chroot "$INST_DIR" apt-get $APT_OPTIONS install localepurge fi if [ -z "$SD_SWAP_SIZE" ]; then SD_SWAP_SIZE=0; fi echo " * Installing the fso-${FSO_DEVICE} package" chroot "$INST_DIR" apt-get $APT_OPTIONS install fso-${FSO_DEVICE} echo " * Creating /etc/X11/xorg.conf" cat > "$INST_DIR/etc/X11/xorg.conf" <<__END__ # Xorg configuration for an Openmoko FreeRunner Section "Module" Load "glx" Load "dri2" EndSection Section "Monitor" Identifier "LCD Panel" EndSection Section "Device" Identifier "Glamo Graphics Chip" Driver "glamo" EndSection Section "Screen" Identifier "Default Screen" Device "Glamo Graphics Chip" Monitor "LCD Panel" EndSection Section "InputDevice" Identifier "Power Button" Driver "evdev" Option "Device" "/dev/input/event0" EndSection Section "InputDevice" Identifier "AUX Button" Driver "evdev" Option "Device" "/dev/input/event2" EndSection Section "InputDevice" Identifier "Touchscreen" Driver "evdev" Option "Device" "/dev/input/event1" Option "Calibration" "107 918 911 98" Option "SwapAxes" "On" EndSection Section "ServerFlags" Option "AutoAddDevices" "False" EndSection Section "ServerLayout" Identifier "Default Layout" Screen "Default Screen" InputDevice "Power Button" InputDevice "AUX Button" InputDevice "Touchscreen" EndSection __END__ echo " * Creating /etc/inittab (all but tty1 disabled to save memory)" cat > "$INST_DIR/etc/inittab" <<__END__ id:2:initdefault: si::sysinit:/etc/init.d/rcS ~~:S:wait:/sbin/sulogin l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 z6:6:respawn:/sbin/sulogin ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now pf::powerwait:/etc/init.d/powerfail start pn::powerfailnow:/etc/init.d/powerfail now po::powerokwait:/etc/init.d/powerfail stop 1:2345:respawn:/sbin/getty 38400 tty1 #2:23:respawn:/sbin/getty 38400 tty2 #3:23:respawn:/sbin/getty 38400 tty3 #4:23:respawn:/sbin/getty 38400 tty4 #5:23:respawn:/sbin/getty 38400 tty5 #6:23:respawn:/sbin/getty 38400 tty6 __END__ if [ -r "$INST_DIR"/etc/frameworkd.conf ]; then echo " * Disabling automated screen lock " # FIXME: should become optional if [ ! -r "$INST_DIR"/etc/frameworkd.conf.orig ]; then chroot "$INST_DIR" cp /etc/frameworkd.conf /etc/frameworkd.conf.orig fi cat "$INST_DIR"/etc/frameworkd.conf.orig | sed -e 's/^idle_prelock.*/idle_prelock = 0/' -e 's/^lock.*/lock = 0/' > "$INST_DIR"/etc/frameworkd.conf else echo "W: Missing file /etc/frameworkd.conf to disable automated screen lock" fi if [ -r "$INST_DIR"/etc/freesmartphone/oevents/rules.yaml ]; then echo " * Allow screen unlock to work without shutting off (AUX pressed, followed by Power shortly pressed)" if [ ! -r "$INST_DIR"/etc/freesmartphone/oevents/rules.yaml.orig ]; then chroot "$INST_DIR" cp /etc/freesmartphone/oevents/rules.yaml /etc/freesmartphone/oevents/rules.yaml.orig fi cat "$INST_DIR"/etc/freesmartphone/oevents/rules.yaml.orig | sed -e '/Suspend Handling/,/Suspend\(\)/ d' > "$INST_DIR"/etc/freesmartphone/oevents/rules.yaml else echo "W: Missing file /etc/freesmartphone/oevents/rules.yaml to allow screen unlock to work without shutting off" fi echo " * Creating /etc/modules" cat > "$INST_DIR/etc/modules" <<__END__ # USB RNDIS/Ethernet Gadget g_ether # bluetooth ohci-hcd hci_usb # buttons neo1973kbd __END__ if [ "$FSO_DEVICE" = gta01 ]; then cat >> "$INST_DIR/etc/modules" <<__END__ # audio snd-soc-neo1973-wm8753 __END__ else cat >> "$INST_DIR/etc/modules" <<__END__ # audio snd-soc-neo1973-gta02-wm8753 # leds leds-neo1973-gta02 __END__ fi echo " * Setting FSCKFIX=yes in /etc/default/rcS" sed -i 's/FSCKFIX=.*/FSCKFIX=yes'/ "$INST_DIR/etc/default/rcS" echo " * Creating /etc/fstab" mkdir -p "$INST_DIR/mnt/flash" cat > "$INST_DIR/etc/fstab" <<__END__ rootfs / auto defaults,errors=remount-ro,noatime 0 1 __END__ if [ "$SINGLE_PART" != "true" ]; then if [ "ext2" = "$SD_PART1_FS" -o "ext3" = "$SD_PART1_FS" ]; then cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mmcblk0p1 /boot auto defaults,noatime 0 2 __END__ else cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mmcblk0p1 /boot auto defaults,noatime,noauto 0 2 __END__ fi if [ 0 -lt "$SD_SWAP_SIZE" ]; then cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mmcblk0p3 none swap sw 0 0 __END__ fi else # $SINGLE_PART = "true" if [ 0 -lt "$SD_SWAP_SIZE" ]; then cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mmcblk0p2 none swap sw 0 0 __END__ fi fi if [ "$FSO_DEVICE" = gta01 ]; then cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mtdblock4 /mnt/flash jffs2 defaults,noatime,noauto 0 2 __END__ else cat >> "$INST_DIR/etc/fstab" <<__END__ /dev/mtdblock6 /mnt/flash jffs2 defaults,noatime,noauto 0 2 __END__ fi cat >> "$INST_DIR/etc/fstab" <<__END__ proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults,noatime 0 0 __END__ echo " * Setting /etc/hostname to $HOSTNAME" echo "$HOSTNAME" > "$INST_DIR/etc/hostname" for FILE in /etc/network/interfaces /etc/resolv.conf; do echo " * $FILE copied from this machine" cat > "$INST_DIR$FILE" <$FILE done # empty passwords now require modification to PAM # http://lists.alioth.debian.org/pipermail/pkg-fso-maint/2009-May/001225.html # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=525153 echo " * Setting root password to '$ROOT_PASSWORD'" echo "root:$ROOT_PASSWORD" | chroot "$INST_DIR" chpasswd for HOST_KEY in $DROPBEAR_KEYS; do if [ -f "$HOST_KEY" ]; then echo " * copying ssh host key $HOST_KEY" intern_d=`dirname $INST_DIR$HOST_KEY` if [ ! -d "$intern_d" ]; then echo " Creating directory '$intern_d'" mkdir -p "$intern_d" fi cat >"$INST_DIR$HOST_KEY" <$HOST_KEY fi done echo " * Installing dash as /bin/sh: $DASH_BINSH" echo 'dash dash/sh string $DASH_BINSH' | chroot "$INST_DIR" debconf-set-selections chroot "$INST_DIR" apt-get $APT_OPTIONS install dash echo " * Installing /root/.xsession" cat > "$INST_DIR"/root/.xsession <> "$INST_DIR"/root/.xsession <> "$INST_DIR"/root/.xsession <> "$INST_DIR"/root/.stalonetrayrc < "$INST_DIR"/root/.panel-pluginrc <$BOOT_DIR/append-GTA02 else echo "root=$ROOT_PART rootdelay=1" >$BOOT_DIR/append-GTA02 fi fi fi echo "I: Installing kernel package - done" } # # Stage uboot # action_uboot () { echo "I: Modifying U-Boot bootloader menu" if [ "$SD_PART1_FS" = "vfat" ]; then echo "W: When using $SD_PART1_FS as filesystem for the first microSD card" echo " partition, you should not modify the U-Boot environment." return 1 fi cat > "$INST_DIR/root/uboot_menu.in" <<'__END__' bootcmd= setenv bootargs ${bootargs_base} ${mtdparts} rootfstype=ext2 root=/dev/mmcblk0p2 rootdelay=5; mmcinit; ext2load mmc 1 0x32000000 ${sd_image_name}; bootm 0x32000000 menu_1= Boot from Flash: setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel 0x200000; bootm 0x32000000 menu_2= Reboot: reset menu_3= Power off: neo1973 power-off menu_4= Set console to USB: setenv stdin usbtty; setenv stdout usbtty; setenv stderr usbtty menu_5= Set console to serial: setenv stdin serial; setenv stdout serial; setenv stderr serial menu_6= menu_7= menu_8= __END__ echo " * Checking for a sane MTD configuration" if ! fgrep mtd2 < /proc/mtd |fgrep -q "u-boot_env"; then echo "E: U-Boot environment not found at expected location in mtd2" exit 1 fi echo " * Mounting /dev inside the chroot at '$INST_DIR'" mount -o bind /dev "$INST_DIR/dev" chroot "$INST_DIR" /bin/sh -e <<__END_CHROOT__ echo " * Dumping current U-Boot environment" #dd if=/dev/mtdblock2 of=\$INST_DIR/root/env.orig nanddump /dev/mtd2 -o -b -f /root/env.orig if [ ! \$(wc -c /root/env.orig | awk '{print \$1}') -eq $UBOOT_ENV_SIZE ]; then echo "Environment did not have the expected size of $UBOOT_ENV_SIZE" exit 1 fi echo " * Merging Debian menu entries into U-Boot environment (can take up to 70s)" uboot-envedit -i /root/env.orig -f /root/uboot_menu.in -o /root/env.new if [ ! \$(wc -c /root/env.new | awk '{print \$1}') -eq $UBOOT_ENV_SIZE ]; then echo "Newly created environment did not have the expected size of $UBOOT_ENV_SIZE" exit 1 fi echo " * Writing back U-Boot environment" flash_eraseall /dev/mtd2 nandwrite /dev/mtd2 /root/env.new __END_CHROOT__ echo " * Unmounting /dev" umount "$INST_DIR/dev" echo "I: Modifying U-Boot bootloader menu - done" } # # Stage cleaunp # action_cleanup () { echo "I: Cleaning the environment" echo " * Remove additional packages" intern_delenda='' intern_proposed_delenda='cdebootstrap-helper-rc.d xserver-xorg-input-synaptics' #carthago' for pakket in $intern_proposed_delenda; do if dpkg -s $pakket > /dev/null 2> /dev/null; then intern_delenda="$intern_delenda $pakket" fi done chroot "$INST_DIR" apt-get --yes --purge remove $intern_delenda echo " * Cleaning APT cache" chroot "$INST_DIR" apt-get clean echo "I: Cleaning the environment - done - the environment is now clean!" } # # Stage unmount # action_unmount () { echo "I: Unmounting - start" if mount | grep -q "$INST_DIR/proc"; then echo -n " * Unmounting proc from install directory" if umount "$INST_DIR/proc"; then echo " [ok]" else echo " [failed]" fi elif [ -n "$VERBOSE" ]; then echo "I: /proc directory not mounted to install directory" fi echo " * Unmounting microSD card partitions" if [ "$SINGLE_PART" != "true" ]; then umount "$INST_DIR/boot" fi if ! umount "$INST_DIR"; then echo "W: Could not unmount install directory '$INST_DIR'." return 1; fi echo "I: microSD card partitions unmounted" intern_fstablines='E: the intern_fstablines remained unset' intern_line_or_lines='E: the intern_fstablines remained unset' if [ -z "$intern_instdir_already_present" -o "no" = "$intern_instdir_already_present" ]; then if ! rmdir "$INST_DIR"; then echo "W: Could not remove directory '$INST_DIR'." echo fi if [ "$SINGLE_PART" = "true" ]; then intern_fstablines="${SD_DEVICE}p1 $INST_DIR auto defaults,async 0 0" intern_line_or_lines="line" else intern_fstablines="${SD_DEVICE}p1 $INST_DIR/boot auto defaults,async 0 0 ${SD_DEVICE}p2 $INST_DIR auto defaults,async 0 0" intern_line_or_lines="lines" fi cat <