#!/bin/sh # (c) copyright 2010 by Thomas Tanner # create a bootable Maemo 5 root on /home or some mounted MMC partition # either symlink or copy all files on NAND # copy files relocated to /home # ignore or copy files from /opt # symlink or mount old home, or setup new home # for installation in /home move /home/opt to /home/opt.orig and update /opt symlink # $dest/nand - mount point for UBIFS or mount binds # for chroot mounts in $dest are: dev home media proc srv sys syspart tmp var/run mountpoints="cdrom dev floppy home initrd media mnt nand proc sys syspart tmp" mode=link # link or copy content withopt=no # copy or ignore files in /opt homedir=keep # link/mount old home (keep) or create new home (new) bootable=yes # bootable installation debug=: #debug=echo #set -x test "$#" -eq 0 && echo "$0 destination [source]" && exit 1 dest="$1" # rootfs destination (absolute path or device) #dest=`pwd` src= # default source (absolute path) test -n "$2" && src="$2" # or alternative rootfs copy case "$src" in */);; *) src="$src/" ;; esac # make sure src has trailing slash here=`dirname $0` here=`realpath $here` rawdest=no case $dest in /dev/mmcblk[01]p?) rawdest=yes echo destination is partition test -d /media/moebian && (echo cannot create mountdir; exit 1) echo -n formatting $dest as ext3. are you sure [y/N]: read go && test $go != y && echo aborting && exit 1 mkfs.ext3 $dest mkdir -p /media/moebian mount $dest /media/moebian dest=/media/moebian ;; esac if test $bootable = yes; then device=`cat /proc/mounts | grep " $dest " | awk '{print $1}'` case $device in /dev/mmcblk0*) card='${INT_CARD}'; cardname='eMMC' ;; /dev/mmcblk1*) card='${EXT_CARD}'; cardname='SD' ;; *) echo invalid destination exit 1 ;; esac partition=`echo $device | sed s%/dev/mmcblk.%%` card=$card$partition echo installing bootable rootfs in $dest on $device = $card else echo installing chroot in $dest fi echo mode: $mode, copy /opt: $withopt, $homedir /home cd "$dest" # create toplevel dirs and nand mount point mountpoints="cdrom floppy home initrd media mnt nand proc srv sys syspart tmp" content="usr" copydirs="bin boot etc dev lib sbin root var" checklinkdirs="bin boot etc lib sbin root usr var" mkdir -p $mountpoints mkdir -p mnt/initfs # bootmenu nand mount point (required for boot!) if test $dest = /home && test -L /opt; then if test -d opt.nand; then echo "opt for NAND does already exist. not updating" else mv opt opt.nand ln -sf $dest/opt.nand /opt echo "/home/opt moved to /home/opt.nand and symlink updated" fi fi if test $mode = link; then mkdir -p $content copydirs="$copydirs usr/local usr/share/man" # excluded shared dirs cd "$src" dontlink="usr/bin usr/games usr/include usr/lib usr/libexec usr/sbin \ usr/share usr/share/applications/*/ usr/X11R6" echo $dontlink cd "$dest" for d in $dontlink; do test -L "$d" && test ! -L "$src$d" && rm $d # remove existing links mkdir -p $d done elif test $mode = copy; then copydirs="$copydirs $content" else echo "error: unknown mode $mode" && exit 1 fi for d in $copydirs; do if test -d $d; then echo "skipping existing directory ${src}$d" continue fi echo copying ${src}$d mkdir -p $d cp -a ${src}$d $d/.. done modules=/lib/modules/2.6.28maemo-omap1 if test $bootable = yes && test -d $modules -a ! -d $dest$modules; then echo copying maemo kernel modules cp -a /lib/modules/2.6.28maemo-omap1 $dest/lib/modules fi if test $withopt = yes; then echo copying /opt cp -a ${src}home/opt/* $dest/opt else mkdir -p $dest/opt # create empty opt fi symlink () { # args: subdir path relpath # recursive symlinking: create or update $debug sub $1 $2 $topdir$2 $3 echo symlinking "$2" cd "$1" IFS="%" && for f in `/bin/ls -d * .[^.]* 2>/dev/null | tr '\n' '%'`; do #IFS=$'\n' && for f in `/bin/ls -d * .[^.]* 2>/dev/null`; do if test -L "$f"; then # update symlinks # target exists and is not symlink: ignore if test ! -e "$dest$2/$f" -o -L "$dest$2/$f"; then target=`readlink $f` case "$target" in /home/*) # copy relocated files mkdir -p "$dest$2/$f" echo copying $target cp -a $target "$dest$2/$f/.." continue ;; /*) $debug al "$2/$f" $target # if it links to rootfs make it a rel. symlink test -e "$3$target" && target="$3$target" ;; *) $debug rl "$2/$f" $target # just keep the rel. symlink ;; esac rm -f "$dest$2/$f" ln -s "$target" "$dest$2/$f" else echo "warning: $dest$2/$f exists but is not a symlink. ignoring" fi elif test -d "$f"; then # a subdirectory $debug sd "$2/$f" if test -L "$dest$2/$f" -o ! -e "$dest$2/$f"; then # target is a symlink or doesn't exist -> update symlink if test -L "$2/$f"; then # symlink on NAND, was relocated mkdir -p "$dest$2/$f" echo copying "$2/$f" cp -a $2/$f/* "$dest$2/$f" else rm -f "$dest$2/$f" ln -s "$3$2/$f" "$dest$2/$f" fi else if test -d "$dest$2/$f"; then # symlink contents if is an existing directory in root symlink "$f" "$2/$f" "../$3" else echo "warning: $dest$2/$f exists but is not a file. ignoring" fi fi else $debug fi "$2/$f" # update symlink is it not a existing file test -f "$dest$2/$f" || ln -sf "$3$2/$f" "$dest$2/$f" fi done cd .. } if test $mode = link; then # TODO: find files that were moved from NAND to /home and copy or symlink them for d in $content; do (symlink "$src$d" "/$d" ../nand) done elif test $mode = copy; then # process /home and /opt symlinks echo -n checking for external symlinks... tmp=`mktemp` find $checklinkdirs -type l > $tmp echo processing `wc -l $tmp | awk '{print $1}'` links while read l; do f=`readlink $l` case "$f" in /opt/*) test $withopt = yes || rm $l # delete /opt links ;; /home/*) # copy files relocated from NAND to /home rm $l test -d $f && echo copying $f cp -a $f $l # copy original file/dir ;; *) ;; esac done < $tmp rm $tmp fi if test $homedir = keep; then if test $dest = /home && test ! -d $dest/home/user; then echo symlinking existing home ln -s /user $dest/home/user fi elif test $homedir = new; then echo creating new home rm -rf $dest/home/user mkdir -p $dest/home/user (cd $src/etc/skel && cp -a . $dest/home/user) chown -R user:users $dest/home/user else echo "error: unknown homedir mode $mode" && exit 1 fi if test $bootable = yes; then stat=$(dpkg-query -W -f='${Status}' bootmenu 2>&1) || stat=none if test "$stat" != "install ok installed"; then echo installing bootmenu deb=/var/tmp/bootmenu.deb wget -O$deb "http://www.daimi.au.dk/~cvm/bootmenu_1.6_armel.deb" || \ (echo 'download failed'; exit 1) dpkg -i $deb || (echo 'installation failed'; exit 1) rm $deb echo bootmenu successfully installed else echo bootmenu is already installed fi bootitem=/etc/bootmenu.d/moebian.item cat > $bootitem <