|
@@ -1,8 +1,9 @@
|
|
|
#!/usr/bin/env bash
|
|
|
#-
|
|
|
+# Copyright © 2010, 2011, 2012
|
|
|
+# Thorsten Glaser <tg@mirbsd.org>
|
|
|
# Copyright © 2010, 2011
|
|
|
# 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
|
|
@@ -19,17 +20,12 @@
|
|
|
# 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-
|
|
|
+# 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
|
|
|
+# Create a hard disc image, bootable using GNU GRUB2, with an ext2fs
|
|
|
+# root partition and an OpenADK cfgfs partition.
|
|
|
|
|
|
TOPDIR=$(pwd)
|
|
|
me=$0
|
|
@@ -41,17 +37,18 @@ 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)
|
|
|
+ df=$(make -s package=mksh show=DISTFILES)
|
|
|
+ rm -rf build_mksh
|
|
|
mkdir -p build_mksh
|
|
|
gzip -dc dl/"$df" | (cd build_mksh; cpio -mid)
|
|
|
cd build_mksh/mksh
|
|
|
- bash Build.sh -r -c lto || exit 1
|
|
|
+ bash Build.sh -r -c lto || bash Build.sh -r || exit 1
|
|
|
cp mksh "$TOPDIR"/bin/tools/
|
|
|
cd "$TOPDIR"
|
|
|
rm -rf build_mksh
|
|
|
fi
|
|
|
|
|
|
-test -n "$KSH_VERSION" || exec mksh -x "$me" "$@"
|
|
|
+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
|
|
@@ -61,51 +58,62 @@ fi
|
|
|
|
|
|
me=${me##*/}
|
|
|
|
|
|
-if (( USER_ID )); then
|
|
|
- print -u2 Installation is only possible as root!
|
|
|
- exit 1
|
|
|
-fi
|
|
|
-
|
|
|
TOPDIR=$(realpath .)
|
|
|
ostype=$(uname -s)
|
|
|
|
|
|
-cfgfs=1
|
|
|
-noformat=0
|
|
|
-quiet=0
|
|
|
-serial=0
|
|
|
-speed=115200
|
|
|
-panicreboot=10
|
|
|
-
|
|
|
function usage {
|
|
|
-cat >&2 <<EOF
|
|
|
-Syntax: $me [-c cfgfssize] [-p panictime] [±q] [-s serialspeed]
|
|
|
- [±t] -n /dev/sdb image
|
|
|
-Defaults: -c 1 -p 10 -s 115200; -t = enable serial console
|
|
|
+ cat >&2 <<EOF
|
|
|
+Syntax: $me [-c cfgfssize] [-i imagesize] [-p panictime]
|
|
|
+ [-s serialspeed] [-t] [-T imagetype] [+U] target.ima source.tgz
|
|
|
+Explanation/Defaults:
|
|
|
+ -c: minimum 0, maximum 5, default 1 (MiB)
|
|
|
+ -i: total image, default 512 (MiB; max. approx. 2 TiB)
|
|
|
+ -p: default 10 (seconds; 0 disables; max. 300)
|
|
|
+ -s: default 115200 (bps, others: 9600 19200 38400 57600)
|
|
|
+ -t: enable serial console (+t disables it, default)
|
|
|
+ -T: image type (default raw, others: vdi)
|
|
|
+ +U: disables using root=UUID= (-U enables it, default)
|
|
|
EOF
|
|
|
- exit $1
|
|
|
+ exit ${1:-1}
|
|
|
}
|
|
|
|
|
|
-while getopts "c:hp:qs:nt" ch; do
|
|
|
+cfgfs=1
|
|
|
+tgtmib=512
|
|
|
+panicreboot=10
|
|
|
+speed=115200
|
|
|
+serial=0
|
|
|
+tgttype=raw
|
|
|
+useuuid=1
|
|
|
+
|
|
|
+while getopts "c:hi:p:s:tT:U" ch; do
|
|
|
case $ch {
|
|
|
(c) if (( (cfgfs = OPTARG) < 0 || cfgfs > 5 )); then
|
|
|
print -u2 "$me: -c $OPTARG out of bounds"
|
|
|
- exit 1
|
|
|
+ usage
|
|
|
fi ;;
|
|
|
(h) usage 0 ;;
|
|
|
+ (i) if (( (tgtmib = OPTARG) < 7 || tgtmib > 2097150 )); then
|
|
|
+ print -u2 "$me: -i $OPTARG out of bounds"
|
|
|
+ usage
|
|
|
+ fi ;;
|
|
|
(p) if (( (panicreboot = OPTARG) < 0 || panicreboot > 300 )); then
|
|
|
print -u2 "$me: -p $OPTARG out of bounds"
|
|
|
- exit 1
|
|
|
+ usage
|
|
|
fi ;;
|
|
|
- (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
|
|
|
+ usage
|
|
|
fi
|
|
|
speed=$OPTARG ;;
|
|
|
- (n) noformat=1 ;;
|
|
|
(t) serial=1 ;;
|
|
|
(+t) serial=0 ;;
|
|
|
+ (T) if [[ $OPTARG != @(raw|vdi) ]]; then
|
|
|
+ print -u2 "$me: image type $OPTARG invalid"
|
|
|
+ usage
|
|
|
+ fi
|
|
|
+ tgttype=$OPTARG ;;
|
|
|
+ (U) useuuid=1 ;;
|
|
|
+ (+U) useuuid=0 ;;
|
|
|
(*) usage 1 ;;
|
|
|
}
|
|
|
done
|
|
@@ -114,20 +122,8 @@ shift $((OPTIND - 1))
|
|
|
(( $# == 2 )) || usage 1
|
|
|
|
|
|
f=0
|
|
|
-tools='genext2fs'
|
|
|
-case $ostype {
|
|
|
-(DragonFly|*BSD*)
|
|
|
- ;;
|
|
|
-(Darwin)
|
|
|
- tools="$tools fuse-ext2"
|
|
|
- ;;
|
|
|
-(Linux)
|
|
|
- ;;
|
|
|
-(*)
|
|
|
- print -u2 Sorry, not ported to the OS "'$ostype'" yet.
|
|
|
- exit 1
|
|
|
- ;;
|
|
|
-}
|
|
|
+tools='bc genext2fs'
|
|
|
+[[ $tgttype = vdi ]] && tools="$tools VBoxManage"
|
|
|
for tool in $tools; do
|
|
|
print -n Checking if $tool is installed...
|
|
|
if whence -p $tool >/dev/null; then
|
|
@@ -138,73 +134,36 @@ for tool in $tools; do
|
|
|
fi
|
|
|
done
|
|
|
(( f )) && exit 1
|
|
|
+if bc --help >/dev/null 2>&1; then
|
|
|
+ # GNU bc shows a “welcome message” which irritates scripts
|
|
|
+ bc='bc -q'
|
|
|
+else
|
|
|
+ bc=bc
|
|
|
+fi
|
|
|
|
|
|
tgt=$1
|
|
|
+[[ $tgt = /* ]] || tgt=$PWD/$tgt
|
|
|
src=$2
|
|
|
|
|
|
if [[ ! -f $src ]]; then
|
|
|
print -u2 "'$src' is not a file, exiting"
|
|
|
exit 1
|
|
|
fi
|
|
|
-(( quiet )) || print "Installing $src on $tgt."
|
|
|
-
|
|
|
-qemu-img create -f raw $tgt 524288k
|
|
|
-
|
|
|
-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 rw+
|
|
|
- sleep 3
|
|
|
- }
|
|
|
- ;;
|
|
|
-(Linux)
|
|
|
- basedev=$tgt
|
|
|
- part=${basedev}1
|
|
|
- match=\'${basedev}\''+([0-9])'
|
|
|
- function mount_ext2fs {
|
|
|
- mount -t ext2 "$1" "$2"
|
|
|
- }
|
|
|
- ;;
|
|
|
-}
|
|
|
-
|
|
|
-if (( !quiet )); then
|
|
|
- print "WARNING: This will overwrite $basedev - type Yes to continue!"
|
|
|
- read x
|
|
|
- [[ $x = Yes ]] || exit 0
|
|
|
+if ! T=$(mktemp -d /tmp/openadk.XXXXXXXXXX); then
|
|
|
+ print -u2 Error creating temporary directory.
|
|
|
+ exit 1
|
|
|
fi
|
|
|
+print "Installing $src on $tgt."
|
|
|
|
|
|
+cyls=$tgtmib
|
|
|
+heads=64
|
|
|
+secs=32
|
|
|
if stat -qs .>/dev/null 2>&1; then
|
|
|
statcmd='stat -f %z' # BSD stat (or so we assume)
|
|
|
else
|
|
|
statcmd='stat -c %s' # GNU stat
|
|
|
fi
|
|
|
|
|
|
-dksz=$(($($statcmd "$tgt")*2))
|
|
|
-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 ! T=$(mktemp -d /tmp/openadk.XXXXXXXXXX); then
|
|
|
- print -u2 Error creating temporary directory.
|
|
|
- exit 1
|
|
|
-fi
|
|
|
tar -xOzf "$src" usr/share/grub-bin/core.img >"$T/core.img"
|
|
|
integer coreimgsz=$($statcmd "$T/core.img")
|
|
|
if (( coreimgsz < 1024 )); then
|
|
@@ -218,22 +177,17 @@ if (( coreimgsz > 65024 )); then
|
|
|
exit 1
|
|
|
fi
|
|
|
(( coreendsec = (coreimgsz + 511) / 512 ))
|
|
|
-if [[ $basedev = /dev/svnd+([0-9]) ]]; then
|
|
|
- # BSD svnd0 mode: protect sector #1
|
|
|
- corestartsec=2
|
|
|
- (( ++coreendsec ))
|
|
|
- corepatchofs=$((0x614))
|
|
|
-else
|
|
|
- corestartsec=1
|
|
|
- corepatchofs=$((0x414))
|
|
|
-fi
|
|
|
+corestartsec=1
|
|
|
+corepatchofs=$((0x414))
|
|
|
# partition offset: at least coreendsec+1 but aligned on a multiple of secs
|
|
|
(( partofs = ((coreendsec / secs) + 1) * secs ))
|
|
|
+# calculate size of ext2fs in KiB as image size minus cfgfs minus firsttrack
|
|
|
+((# partfssz = ((cyls - cfgfs) * 64 * 32 - partofs) / 2 ))
|
|
|
|
|
|
-(( quiet )) || print Preparing MBR and GRUB2...
|
|
|
+print Preparing MBR and GRUB2...
|
|
|
dd if=/dev/zero of="$T/firsttrack" count=$partofs 2>/dev/null
|
|
|
echo $corestartsec $coreendsec | mksh "$TOPDIR/scripts/bootgrub.mksh" \
|
|
|
- -A -g $((cyls-cfgfs)):$heads:$secs -M 1:0x83 -O $partofs | \
|
|
|
+ -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=$corestartsec \
|
|
|
2>/dev/null
|
|
@@ -246,7 +200,7 @@ 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] ))
|
|
|
+(( pssz = cfgfs * 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 ))
|
|
@@ -270,7 +224,6 @@ thecode[mbrpno++]=0x00
|
|
|
(( 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 ))
|
|
@@ -284,57 +237,20 @@ 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"
|
|
|
-
|
|
|
-if [[ $basedev = /dev/svnd+([0-9]) ]]; then
|
|
|
- (( quiet )) || print "Creating BSD disklabel on target device..."
|
|
|
- # c: whole device (must be so)
|
|
|
- # i: ext2fs (matching first partition)
|
|
|
- # j: cfgfs (matching second partition)
|
|
|
- # p: MBR and GRUB2 area (by tradition)
|
|
|
- cat >"$T/bsdlabel" <<-EOF
|
|
|
- type: vnd
|
|
|
- disk: vnd device
|
|
|
- label: OpenADK
|
|
|
- flags:
|
|
|
- bytes/sector: 512
|
|
|
- sectors/track: $secs
|
|
|
- tracks/cylinder: $heads
|
|
|
- sectors/cylinder: $((heads * secs))
|
|
|
- cylinders: $cyls
|
|
|
- total sectors: $((cyls * heads * secs))
|
|
|
- rpm: 3600
|
|
|
- interleave: 1
|
|
|
- trackskew: 0
|
|
|
- cylinderskew: 0
|
|
|
- headswitch: 0
|
|
|
- track-to-track seek: 0
|
|
|
- drivedata: 0
|
|
|
-
|
|
|
- 16 partitions:
|
|
|
- c: $((cyls * heads * secs)) 0 unused
|
|
|
- i: $(((cyls - cfgfs) * heads * secs - partofs)) $partofs ext2fs
|
|
|
- j: $((cfgfs * heads * secs)) $(((cyls - cfgfs) * heads * secs)) unknown
|
|
|
- p: $partofs 0 unknown
|
|
|
-EOF
|
|
|
- disklabel -R ${basedev#/dev/} "$T/bsdlabel"
|
|
|
-fi
|
|
|
-
|
|
|
-(( quiet )) || print "Creating ext2fs on ${part}..."
|
|
|
-
|
|
|
-gzip -dc "$src" | (cd "$T"; tar -xvpf -)
|
|
|
-cd "$T"
|
|
|
+print Extracting installation archive...
|
|
|
+mkdir "$T/src"
|
|
|
+gzip -dc "$src" | (cd "$T/src"; tar -xpf -)
|
|
|
+cd "$T/src"
|
|
|
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
|
|
|
+print Fixing up permissions...
|
|
|
+#chown 0:0 tmp
|
|
|
chmod 1777 tmp
|
|
|
chmod 4755 bin/busybox
|
|
|
[[ -f usr/bin/Xorg ]] && chmod 4755 usr/bin/Xorg
|
|
|
[[ -f usr/bin/sudo ]] && chmod 4755 usr/bin/sudo
|
|
|
-(( quiet )) || print Configuring GRUB2 bootloader...
|
|
|
+print Configuring GRUB2 bootloader...
|
|
|
mkdir -p boot/grub
|
|
|
(
|
|
|
print set default=0
|
|
@@ -351,7 +267,7 @@ mkdir -p boot/grub
|
|
|
fi
|
|
|
print
|
|
|
print 'menuentry "GNU/Linux (OpenADK)" {'
|
|
|
- linuxargs="root=UUID=$partuuid $consargs"
|
|
|
+ linuxargs="root=/dev/sda1 $consargs"
|
|
|
(( panicreboot )) && linuxargs="$linuxargs panic=$panicreboot"
|
|
|
print "\tlinux /boot/kernel $linuxargs"
|
|
|
print '}'
|
|
@@ -363,12 +279,59 @@ for a in usr/lib/grub/*-pc/{*.mod,efiemu??.o,command.lst,moddep.lst,fs.lst,handl
|
|
|
done
|
|
|
cp "${grubfiles[@]}" boot/grub/
|
|
|
|
|
|
-genext2fs -q -b 524286 -d $T ${tgt}.new
|
|
|
+print "Creating ext2fs filesystem image..."
|
|
|
+cd "$T"
|
|
|
+f=0
|
|
|
+genext2fs -U -b $((partfssz)) -d src fsimg || f=1
|
|
|
+if (( !f )); then
|
|
|
+ # use bc(1): this may be over the shell’s 32-bit arithmetics
|
|
|
+ wantsz=$($bc <<<"$((partfssz))*1024")
|
|
|
+ gotsz=$($statcmd fsimg)
|
|
|
+ if [[ $wantsz != "$gotsz" ]]; then
|
|
|
+ print -u2 "Error: want $wantsz bytes, got $gotsz bytes!"
|
|
|
+ f=1
|
|
|
+ fi
|
|
|
+fi
|
|
|
+if (( f )); then
|
|
|
+ print -u2 "Error creating ext2fs filesystem image"
|
|
|
+ cd /
|
|
|
+ rm -rf "$T"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+# delete source tree, to save disc space
|
|
|
+rm -rf src
|
|
|
|
|
|
-(( quiet )) || print Finishing up...
|
|
|
-dd if=${tgt}.new of=$tgt seek=65536
|
|
|
+if [[ $tgttype = raw ]]; then
|
|
|
+ tgttmp=$tgt
|
|
|
+else
|
|
|
+ tgttmp=$T/dst.ima
|
|
|
+fi
|
|
|
+print "Putting together raw output image $tgttmp..."
|
|
|
+dd if=/dev/zero bs=1048576 count=$cfgfs 2>/dev/null | \
|
|
|
+ cat firsttrack fsimg - >"$tgttmp"
|
|
|
+# use bc(1): this may be over the shell’s 32-bit arithmetics
|
|
|
+wantsz=$($bc <<<"$tgtmib*1048576")
|
|
|
+gotsz=$($statcmd "$tgttmp")
|
|
|
+if [[ $wantsz != "$gotsz" ]]; then
|
|
|
+ print -u2 "Error: want $wantsz bytes, got $gotsz bytes!"
|
|
|
+ cd /
|
|
|
+ rm -rf "$T"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
|
|
|
-cd "$TOPDIR"
|
|
|
+case $tgttype {
|
|
|
+(raw)
|
|
|
+ ;;
|
|
|
+(vdi)
|
|
|
+ print "Converting raw image to VDI..."
|
|
|
+ VBoxManage convertdd dst.ima dst.vdi
|
|
|
+ rm dst.ima
|
|
|
+ print "Moving VDI image to $tgt..."
|
|
|
+ mv -f dst.vdi "$tgt"
|
|
|
+ ;;
|
|
|
+}
|
|
|
|
|
|
+print Finishing up...
|
|
|
+cd "$TOPDIR"
|
|
|
rm -rf "$T"
|
|
|
exit 0
|