|
@@ -1,132 +1,328 @@
|
|
|
#!/usr/bin/env bash
|
|
|
-# This file is part of the OpenADK project. OpenADK is copyrighted
|
|
|
-# material, please see the LICENCE file in the top-level directory.
|
|
|
+#-
|
|
|
+# Copyright © 2010
|
|
|
+# Waldemar Brodkorb <wbx@openadk.org>
|
|
|
+# Thorsten Glaser <tg@mirbsd.org>
|
|
|
+#
|
|
|
+# Provided that these terms and disclaimer and all copyright notices
|
|
|
+# are retained or reproduced in an accompanying document, permission
|
|
|
+# is granted to deal in this work without restriction, including un‐
|
|
|
+# limited rights to use, publicly perform, distribute, sell, modify,
|
|
|
+# merge, give away, or sublicence.
|
|
|
+#
|
|
|
+# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
|
|
|
+# the utmost extent permitted by applicable law, neither express nor
|
|
|
+# implied; without malicious intent or gross negligence. In no event
|
|
|
+# may a licensor, author or contributor be held liable for indirect,
|
|
|
+# direct, other damage, loss, or other issues arising in any way out
|
|
|
+# of dealing in the work, even if advised of the possibility of such
|
|
|
+# damage or existence of a defect, except proven that it results out
|
|
|
+# of said person’s immediate fault when using the work as intended.
|
|
|
+#
|
|
|
+# Alternatively, this work may be distributed under the terms of the
|
|
|
+# General Public License, any version, as published by the Free Soft-
|
|
|
+# ware Foundation.
|
|
|
+#-
|
|
|
+# Prepare a USB stick or CF/SD/MMC card or hard disc for installation
|
|
|
+# of OpenADK:
|
|
|
+# • install a Master Boot Record containing a MirBSD PBR loading GRUB
|
|
|
+# • write GRUB2 core.img just past the MBR
|
|
|
+# • create a root partition with ext2fs and extract the OpenADK image
|
|
|
+# just built there
|
|
|
+# • create a cfgfs partition
|
|
|
|
|
|
TOPDIR=$(pwd)
|
|
|
+me=$0
|
|
|
|
|
|
-if [ $(id -u) -ne 0 ];then
|
|
|
- printf "Installation is only possible as root\n"
|
|
|
- exit 1
|
|
|
+case :$PATH: in
|
|
|
+(*:$TOPDIR/bin/tools:*) ;;
|
|
|
+(*) export PATH=$PATH:$TOPDIR/bin/tools ;;
|
|
|
+esac
|
|
|
+
|
|
|
+test -n "$KSH_VERSION" || if ! which mksh >/dev/null 2>&1; then
|
|
|
+ make package=mksh fetch || exit 1
|
|
|
+ df=$(cd package/mksh; TOPDIR="$TOPDIR" gmake show=DISTFILES)
|
|
|
+ mkdir -p build_mksh
|
|
|
+ gzip -dc dl/"$df" | (cd build_mksh; cpio -mid)
|
|
|
+ cd build_mksh/mksh
|
|
|
+ bash Build.sh -r || exit 1
|
|
|
+ cp mksh "$TOPDIR"/bin/tools/
|
|
|
+ cd "$TOPDIR"
|
|
|
+ rm -rf build_mksh
|
|
|
fi
|
|
|
|
|
|
-printf "Checking if mke2fs is installed"
|
|
|
-mke2fs=$(which mke2fs)
|
|
|
+test -n "$KSH_VERSION" || exec mksh "$me" "$@"
|
|
|
+if test -z "$KSH_VERSION"; then
|
|
|
+ echo >&2 Fatal error: could not run myself with mksh!
|
|
|
+ exit 255
|
|
|
+fi
|
|
|
|
|
|
-if [ ! -z $mke2fs -a -x $mke2fs ];then
|
|
|
- printf "...okay\n"
|
|
|
-else
|
|
|
- printf "...failed\n"
|
|
|
+### run with mksh from here onwards ###
|
|
|
+
|
|
|
+me=${me##*/}
|
|
|
+
|
|
|
+if (( USER_ID )); then
|
|
|
+ print -u2 Installation is only possible as root!
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
+TOPDIR=$(realpath .)
|
|
|
+ostype=$(uname -s)
|
|
|
+
|
|
|
cfgfs=1
|
|
|
quiet=0
|
|
|
-console=0
|
|
|
serial=0
|
|
|
-while getopts "nq" option
|
|
|
-do
|
|
|
- case $option in
|
|
|
- q)
|
|
|
- quiet=1
|
|
|
- ;;
|
|
|
- n)
|
|
|
- cfgfs=0
|
|
|
- ;;
|
|
|
- *)
|
|
|
- printf "Option not recognized\n"
|
|
|
+speed=115200
|
|
|
+
|
|
|
+function usage {
|
|
|
+cat >&2 <<EOF
|
|
|
+Syntax: $me [-c cfgfssize] [±qt] [-s serialspeed] /dev/sdb image
|
|
|
+Defaults: -c 1 -s 115200
|
|
|
+EOF
|
|
|
+ exit $1
|
|
|
+}
|
|
|
+
|
|
|
+while getopts "c:hqs:t" ch; do
|
|
|
+ case $ch {
|
|
|
+ (c) if (( (cfgfs = OPTARG) < 0 || cfgfs > 5 )); then
|
|
|
+ print -u2 "$me: -c $OPTARG out of bounds"
|
|
|
+ exit 1
|
|
|
+ fi ;;
|
|
|
+ (h) usage 0 ;;
|
|
|
+ (q) quiet=1 ;;
|
|
|
+ (+q) quiet=0 ;;
|
|
|
+ (s) if [[ $OPTARG != @(96|192|384|576|1152)00 ]]; then
|
|
|
+ print -u2 "$me: serial speed $OPTARG invalid"
|
|
|
exit 1
|
|
|
- ;;
|
|
|
- esac
|
|
|
+ fi
|
|
|
+ speed=$OPTARG ;;
|
|
|
+ (t) serial=1 ;;
|
|
|
+ (+t) serial=0 ;;
|
|
|
+ (*) usage 1 ;;
|
|
|
+ }
|
|
|
done
|
|
|
-shift $(($OPTIND - 1))
|
|
|
+shift $((OPTIND - 1))
|
|
|
|
|
|
+(( $# == 2 )) || usage 1
|
|
|
|
|
|
-if [ -z $1 ];then
|
|
|
- printf "Please give your compact flash or USB device as first parameter\n"
|
|
|
+f=0
|
|
|
+tools='mke2fs tune2fs'
|
|
|
+case $ostype {
|
|
|
+(DragonFly|*BSD*)
|
|
|
+ ;;
|
|
|
+(Darwin)
|
|
|
+ tools="$tools fuse-ext2"
|
|
|
+ ;;
|
|
|
+(Linux)
|
|
|
+ ;;
|
|
|
+(*)
|
|
|
+ print -u2 Sorry, not ported to the OS "'$ostype'" yet.
|
|
|
exit 1
|
|
|
-else
|
|
|
- if [ -z $2 ];then
|
|
|
- printf "Please give your install tar archive as second parameter\n"
|
|
|
- exit 2
|
|
|
- fi
|
|
|
- if [ -f $2 ];then
|
|
|
- printf "Installing $2 on $1\n"
|
|
|
- else
|
|
|
- printf "$2 is not a file, Exiting\n"
|
|
|
- exit 1
|
|
|
- fi
|
|
|
- if [ -b $1 ];then
|
|
|
- printf "Using $1 as CF/USB disk for installation\n"
|
|
|
- if [ $quiet -eq 0 ];then
|
|
|
- printf "This will destroy all data on $1, are you sure?\n"
|
|
|
- printf "Type "y" to continue\n"
|
|
|
- read y
|
|
|
- fi
|
|
|
+ ;;
|
|
|
+}
|
|
|
+for tool in $tools; do
|
|
|
+ print -n Checking if $tool is installed...
|
|
|
+ if whence -p $tool >/dev/null; then
|
|
|
+ print " okay"
|
|
|
else
|
|
|
- printf "Sorry $1 is not a block device\n"
|
|
|
- exit 1
|
|
|
+ print " failed"
|
|
|
+ f=1
|
|
|
fi
|
|
|
+done
|
|
|
+(( f )) && exit 1
|
|
|
+
|
|
|
+tgt=$1
|
|
|
+src=$2
|
|
|
+
|
|
|
+if [[ ! -b $tgt ]]; then
|
|
|
+ print -u2 "'$tgt' is not a block device, exiting"
|
|
|
+ exit 1
|
|
|
fi
|
|
|
-
|
|
|
-if [ $(mount | grep $1| wc -l) -ne 0 ];then
|
|
|
- printf "Block device $1 is in use, please umount first.\n"
|
|
|
+if [[ ! -f $src ]]; then
|
|
|
+ print -u2 "'$src' is not a file, exiting"
|
|
|
exit 1
|
|
|
fi
|
|
|
+(( quiet )) || print "Installing $src on $tgt."
|
|
|
|
|
|
-case $2 in
|
|
|
- wrap*)
|
|
|
- speed=38400
|
|
|
- ;;
|
|
|
- *)
|
|
|
- speed=115200
|
|
|
- ;;
|
|
|
-esac
|
|
|
-
|
|
|
-rootpart=${1}1
|
|
|
-pt=$TOPDIR/bin/tools/pt
|
|
|
-# get sector size from block device
|
|
|
-maxsector=$(sudo $pt -g $1)
|
|
|
-head=16
|
|
|
-sect=63
|
|
|
-rsize=$(($maxsector / 2))
|
|
|
-
|
|
|
-printf "Creating partition table ...\n"
|
|
|
-table=$(mktemp)
|
|
|
-# generate partition table
|
|
|
-$pt -o $table -s $sect -h $head -p ${rsize}K
|
|
|
-# write partition table to block device
|
|
|
-dd if=$table of=$1 bs=512 count=1 2> /dev/null
|
|
|
-printf "Creating ext2 filesystem ...\n"
|
|
|
-$mke2fs -q ${1}1
|
|
|
-
|
|
|
-printf "Extracting install archive ...\n"
|
|
|
-tmp=$(mktemp -d)
|
|
|
-mount -t ext2 ${rootpart} $tmp
|
|
|
-tar -C $tmp -xzpf $2
|
|
|
-printf "Fixing permissions ...\n"
|
|
|
-chmod 1777 $tmp/tmp
|
|
|
-chmod 4755 $tmp/bin/busybox
|
|
|
-
|
|
|
-printf "Installing GRUB bootloader ...\n"
|
|
|
-mkdir -p $tmp/boot/grub
|
|
|
-cat << EOF > $tmp/boot/grub/grub.cfg
|
|
|
-set default=0
|
|
|
-set timeout=1
|
|
|
-terminal_output console
|
|
|
-terminal_input console
|
|
|
-
|
|
|
-menuentry "GNU/Linux (OpenADK)" {
|
|
|
- insmod ext2
|
|
|
- set root=(hd0,1)
|
|
|
- linux /boot/vmlinuz-adk init=/init
|
|
|
+case $ostype {
|
|
|
+(DragonFly|*BSD*)
|
|
|
+ basedev=${tgt%c}
|
|
|
+ tgt=${basedev}c
|
|
|
+ part=${basedev}i
|
|
|
+ match=\'${basedev}\''[a-p]'
|
|
|
+ function mount_ext2fs {
|
|
|
+ mount -t ext2fs "$1" "$2"
|
|
|
+ }
|
|
|
+ ;;
|
|
|
+(Darwin)
|
|
|
+ basedev=$tgt
|
|
|
+ part=${basedev}s1
|
|
|
+ match=\'${basedev}\''?(s+([0-9]))'
|
|
|
+ function mount_ext2fs {
|
|
|
+ fuse-ext2 "$1" "$2" -o force
|
|
|
+ sleep 3
|
|
|
+ }
|
|
|
+ ;;
|
|
|
+(Linux)
|
|
|
+ basedev=$tgt
|
|
|
+ part=${basedev}1
|
|
|
+ match=\'${basedev}\''+([0-9])'
|
|
|
+ function mount_ext2fs {
|
|
|
+ mount -t ext2 "$1" "$2"
|
|
|
+ }
|
|
|
+ ;;
|
|
|
}
|
|
|
-EOF
|
|
|
-./bin/tools/sbin/grub-install \
|
|
|
- --grub-setup=./bin/tools/sbin/grub-setup \
|
|
|
- --grub-mkimage=./bin/tools/bin/grub-mkimage \
|
|
|
- --grub-mkdevicemap=./bin/tools/sbin/grub-mkdevicemap \
|
|
|
- --no-floppy --modules=ext2 --root-directory=$tmp $1
|
|
|
-umount $tmp
|
|
|
-printf "Successfully installed.\n"
|
|
|
-rm -rf $tmp
|
|
|
+
|
|
|
+mount | while read dev rest; do
|
|
|
+ [[ $dev = $match ]] || continue
|
|
|
+ print -u2 "Block device $tgt is in use, please umount first."
|
|
|
+ exit 1
|
|
|
+done
|
|
|
+
|
|
|
+if (( !quiet )); then
|
|
|
+ print "WARNING: This will overwrite $basedev - type Yes to continue!"
|
|
|
+ read x
|
|
|
+ [[ $x = Yes ]] || exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+dksz=$(dkgetsz "$tgt")
|
|
|
+heads=64
|
|
|
+secs=32
|
|
|
+(( cyls = dksz / heads / secs ))
|
|
|
+if (( cyls < (cfgfs + 2) )); then
|
|
|
+ print -u2 "Size of $tgt is $dksz, this looks fishy?"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+if stat --help >/dev/null 2>&1; then
|
|
|
+ statcmd='stat -c %s' # GNU stat
|
|
|
+else
|
|
|
+ statcmd='stat -f %z' # BSD stat (or so we assume)
|
|
|
+fi
|
|
|
+
|
|
|
+if ! T=$(mktemp -d /tmp/openadk.XXXXXXXXXX); then
|
|
|
+ print -u2 Error creating temporary directory.
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+"$TOPDIR/scripts/tar" -xOzf "$src" ./usr/share/grub-bin/core.img >"$T/core.img"
|
|
|
+integer coreimgsz=$($statcmd "$T/core.img")
|
|
|
+if (( coreimgsz < 1024 )); then
|
|
|
+ print -u2 core.img is probably too small: $coreimgsz
|
|
|
+ rm -rf "$T"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+if (( coreimgsz > 65024 )); then
|
|
|
+ print -u2 core.img is larger than 64K-512: $coreimgsz
|
|
|
+ rm -rf "$T"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+(( coreendsec = (coreimgsz + 511) / 512 ))
|
|
|
+# partition offset: at least coreendsec+1 but aligned on a multiple of secs
|
|
|
+(( partofs = ((coreendsec / secs) + 1) * secs ))
|
|
|
+
|
|
|
+(( quiet )) || print Preparing MBR and GRUB2...
|
|
|
+dd if=/dev/zero of="$T/firsttrack" count=$partofs 2>/dev/null
|
|
|
+echo 1 $coreendsec | mksh "$TOPDIR/scripts/bootgrub.mksh" \
|
|
|
+ -A -g $((cyls-cfgfs)):$heads:$secs -M 1:0x83 -O $partofs | \
|
|
|
+ dd of="$T/firsttrack" conv=notrunc 2>/dev/null
|
|
|
+dd if="$T/core.img" of="$T/firsttrack" conv=notrunc seek=1 2>/dev/null
|
|
|
+# set partition where it can find /boot/grub
|
|
|
+print -n '\0\0\0\0' | \
|
|
|
+ dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x414)) 2>/dev/null
|
|
|
+
|
|
|
+# create cfgfs partition (mostly taken from bootgrub.mksh)
|
|
|
+set -A thecode
|
|
|
+typeset -Uui8 thecode
|
|
|
+mbrpno=0
|
|
|
+set -A g_code $cyls $heads $secs
|
|
|
+(( psz = g_code[0] * g_code[1] * g_code[2] ))
|
|
|
+(( pofs = (cyls - cfgfs) * g_code[1] * g_code[2] ))
|
|
|
+set -A o_code # g_code equivalent for partition offset
|
|
|
+(( o_code[2] = pofs % g_code[2] + 1 ))
|
|
|
+(( o_code[1] = pofs / g_code[2] ))
|
|
|
+(( o_code[0] = o_code[1] / g_code[1] + 1 ))
|
|
|
+(( o_code[1] = o_code[1] % g_code[1] + 1 ))
|
|
|
+# boot flag; C/H/S offset
|
|
|
+thecode[mbrpno++]=0x00
|
|
|
+(( thecode[mbrpno++] = o_code[1] - 1 ))
|
|
|
+(( cylno = o_code[0] > 1024 ? 1023 : o_code[0] - 1 ))
|
|
|
+(( thecode[mbrpno++] = o_code[2] | ((cylno & 0x0300) >> 2) ))
|
|
|
+(( thecode[mbrpno++] = cylno & 0x00FF ))
|
|
|
+# partition type; C/H/S end
|
|
|
+(( thecode[mbrpno++] = 0x88 ))
|
|
|
+(( thecode[mbrpno++] = g_code[1] - 1 ))
|
|
|
+(( cylno = g_code[0] > 1024 ? 1023 : g_code[0] - 1 ))
|
|
|
+(( thecode[mbrpno++] = g_code[2] | ((cylno & 0x0300) >> 2) ))
|
|
|
+(( thecode[mbrpno++] = cylno & 0x00FF ))
|
|
|
+# partition offset, size (LBA)
|
|
|
+(( thecode[mbrpno++] = pofs & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pofs >> 8) & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pofs >> 16) & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pofs >> 24) & 0xFF ))
|
|
|
+(( pssz = psz - pofs ))
|
|
|
+(( thecode[mbrpno++] = pssz & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pssz >> 8) & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pssz >> 16) & 0xFF ))
|
|
|
+(( thecode[mbrpno++] = (pssz >> 24) & 0xFF ))
|
|
|
+# write partition table entry
|
|
|
+ostr=
|
|
|
+curptr=0
|
|
|
+while (( curptr < 16 )); do
|
|
|
+ ostr=$ostr\\0${thecode[curptr++]#8#}
|
|
|
+done
|
|
|
+print -n "$ostr" | \
|
|
|
+ dd of="$T/firsttrack" conv=notrunc bs=1 seek=$((0x1CE)) 2>/dev/null
|
|
|
+
|
|
|
+(( quiet )) || print Writing MBR and GRUB2 to target device...
|
|
|
+dd if="$T/firsttrack" of="$tgt"
|
|
|
+
|
|
|
+(( quiet )) || print "Creating ext2fs on ${part}..."
|
|
|
+q=
|
|
|
+(( quiet )) && q=-q
|
|
|
+mke2fs $q "$part"
|
|
|
+#partuuid=$(tune2fs -l /dev/sd0i | sed -n '/^Filesystem UUID:[ ]*/s///p')
|
|
|
+
|
|
|
+(( quiet )) || print Extracting installation archive...
|
|
|
+mount_ext2fs "$part" "$T"
|
|
|
+gzip -dc "$src" | (cd "$T"; tar -xpf -)
|
|
|
+cd "$T"
|
|
|
+rnddev=/dev/urandom
|
|
|
+[[ -c /dev/arandom ]] && rnddev=/dev/arandom
|
|
|
+dd if=$rnddev bs=16 count=1 >>etc/.rnd 2>/dev/null
|
|
|
+(( quiet )) || print Fixing up permissions...
|
|
|
+chown 0:0 tmp
|
|
|
+chmod 1777 tmp
|
|
|
+chmod 4755 bin/busybox
|
|
|
+(( quiet )) || print Configuring GRUB2 bootloader...
|
|
|
+mkdir -p boot/grub
|
|
|
+(
|
|
|
+ print set default=0
|
|
|
+ print set timeout=1
|
|
|
+ if (( serial )); then
|
|
|
+ print serial --unit=0 --speed=$speed
|
|
|
+ print terminal_output serial
|
|
|
+ print terminal_input serial
|
|
|
+ consargs="console=ttyS0,$speed console=tty0"
|
|
|
+ else
|
|
|
+ print terminal_output console
|
|
|
+ print terminal_input console
|
|
|
+ consargs="console=tty0"
|
|
|
+ fi
|
|
|
+ print
|
|
|
+ print 'menuentry "GNU/Linux (OpenADK)" {'
|
|
|
+# print "\tlinux /boot/vmlinuz-adk root=UUID=$partuuid $consargs panic=10"
|
|
|
+ print "\tlinux /boot/vmlinuz-adk $consargs panic=10"
|
|
|
+ print '}'
|
|
|
+) >boot/grub/grub.cfg
|
|
|
+set -A grubfiles
|
|
|
+ngrubfiles=0
|
|
|
+for a in usr/lib/grub/*-pc/{*.mod,efiemu??.o,command.lst,moddep.lst,fs.lst,handler.lst,parttool.lst}; do
|
|
|
+ [[ -e $a ]] && grubfiles[ngrubfiles++]=$a
|
|
|
+done
|
|
|
+cp "${grubfiles[@]}" boot/grub/
|
|
|
+(( quiet )) || print Finishing up...
|
|
|
+cd "$TOPDIR"
|
|
|
+umount "$T"
|
|
|
+
|
|
|
+rm -rf "$T"
|
|
|
exit 0
|