[flashboot] script to write flash directly with split flashboot and msdos partition

Marcel Wiget mwiget at gmail.com
Mon Jul 2 20:48:39 EST 2007


While looking for a way to use larger than 128mb compact flash cards
and an easy way to

a) use Windows or OS/X to write configs and binaries directly on a flash card
b) avoid the "do you want to initialize the flash" question in OS/X
(and possible windows)
c) A way to upload SW updates to a flashboot running device safely
with recovery possibilities

I created a little script, based on build-diskimage.sh that creates 2
partitions on the flash, split the available space in half and make
the OpenBSD one bootable and populated with a generated kernel image.
The idea, when running from ramdisk with modified rc scripts, is to
allow the user to upload new configs/images/packages to the msdos
partition, do some sanity checks, and then copy it over to the
production part of the flash.

WRAP specific issue with >128MB compact flash cards: The BIOS detects
a different flash geometry than a PC. I found a workaround by starting
the bootable OpenBSD partition on the last sector of the first track
and head. It worked for my 128MB, 512MB and 1GB compact flash cards.
Not sure if it breaks on other platforms though.

Feel free to incorporate this script (or portions/ideas) into
flashboot distribution if deemed useful.

Marcel



#!/bin/sh
#
# $Id$
#
# Written by Marcel Wiget <mwiget at gmail.com> in 2007
# portions based on flashboot build-diskimage.sh
# flashboot can be found at http://www.mindrot.org/projects/flashboot/)

BASE=`pwd`
DESTDIR=${DESTDIR:-${BASE}/flash-dist}
KERNELFILE=${KERNELFILE:-${BASE}/obj/bsd.gz}
SUDO=sudo
MOUNTPOINT=/mnt

# This is for boot.conf and should match the kernel ttyspeed.
# Which should be 9600 for GENERIC-RD, 38400 for WRAP12 and 19200 for the rest.
TTYSPEED=${TTYSPEED:-38400}

# Don't start without a device contain the fash as a parameter
if [ "$1" = "" ]; then
  cat << __EOC

usage: $0 device

This script erases any existing data on the specified flash drive
and creates 2 equal size partitions and formats them, a bootable
flashboot OpenBSD partition and a FAT-32 formatted MSDOS partition.

The OpenBSD partition will be updated and configured with the flashboot
standard distribution. A properly installed and compiled flashboot
distribution is required. See http://www.mindrot.org/projects/flashboot/

WARNING: the content of the specified flash device will be DESTROYED!

Example: $0 sd0

__EOC
  exit 1
fi

DEVICE=$1

# Does the kernel exist at all
if [ ! -r $KERNELFILE ]; then
  echo "ERROR! $KERNELFILE does not exist or is not readable."
  exit 1
fi

# get fdisk info from DEVICE
GEOMETRY=`${SUDO} fdisk $DEVICE 2>/dev/null | grep geometry: | awk
'{print $4}' `

# device for real?
if [ "X$GEOMETRY" == "X" ]; then
  echo "ERROR! /dev/$DEVICE does not exist or cant read flash geometry."
  exit 1
fi
#
echo -n "\n$DEVICE: Geometry is $GEOMETRY "

cylinders=`echo $GEOMETRY | cut -d / -f 1`
heads=`echo $GEOMETRY | cut -d / -f 2`
sectors=`echo $GEOMETRY | cut -d / -f 3`
let flashsize=$cylinders*$heads*$sectors/2048

echo "and holds about $flashsize MBytes"

# sanity check. If the flash is bigger than 1GB, we're probably
# dealing with a HD instead of a flash card!


if [ "$flashsize" -gt "1024" ]; then
  echo "\nERROR! /dev/$DEVICE seems rather large ($flashsize MB)."
  echo "If you're sure this isn't your HD, please modify this script."
  echo "This script assumes flash cards used are <= 512MB"
  exit 1
fi

echo "\nReady to partition and format flash drive in /dev/$DEVICE"
echo "Hit ^C now if you're not sure this is the right flash or"
echo "Enter to continue"

read null

# calculate CHS start end for OpenBSD and MSDOS partition
let startcyl1=0
let endcyl1=$cylinders/2
let startcyl2=$endcyl1+1
let endcyl2=$cylinders-1
let head=$heads-1

# Create a new Master Boot Record with 2 partitions:
# 0: OpenBSD bootable (where we will addd a disklabel)
# 3: MSDOS partition
# A standard behaviour of fdisk when using reinit is assumed.

# Using the odd starting CHS of 0/0/32 helps us getting around
# the problem on WRAP platforms where the bootstrap code has
# a different oppinion about the flash's geometry.

${SUDO} fdisk -ye $DEVICE << __EOC >/dev/null 2>&1
reinit
edit 0
A6
0
0
32
$endcyl1
$head
$sectors
edit 3
0B
$startcyl2
0
1
$endcyl2
$head
$sectors
flag 0
update
quit
__EOC

echo "\nNew partition table:"
${SUDO} fdisk $DEVICE 2>/dev/null

# Edit now the new disklabel by defining partition a
${SUDO} disklabel -c -d -E $DEVICE << __EOC >/dev/null 2>&1
m a
4.2BSD


w
q
__EOC

# disklabel $DEVICE

# initialize both new filesystems:
echo "\nFormat MSDOS Partition:"
${SUDO} newfs_msdos -L OpenBSD /dev/r${DEVICE}i
echo "\nFormat OpenBSD Partition:"
${SUDO} newfs /dev/r${DEVICE}a

echo "\nMounting destination to ${MOUNTPOINT}..."
if ! ${SUDO} mount -o async /dev/${DEVICE}a ${MOUNTPOINT}; then
  echo Mount failed..
  exit
fi

echo ""
echo "Copying bsd kernel, boot blocks and /etc/boot.conf..."
${SUDO} cp ${DESTDIR}/usr/mdec/boot ${MOUNTPOINT}/boot
${SUDO} cp ${KERNELFILE} ${MOUNTPOINT}/bsd
${SUDO} mkdir ${MOUNTPOINT}/etc
${SUDO} sed "/^stty/s/19200/${TTYSPEED}/" <
${BASE}/initial-conf/boot.conf > boot.conf$$
${SUDO} cp boot.conf$$  ${MOUNTPOINT}/etc/boot.conf
${SUDO} rm -f boot.conf$$

echo ""
echo "Installing boot blocks..."
${SUDO} /usr/mdec/installboot ${MOUNTPOINT}/boot
${DESTDIR}/usr/mdec/biosboot ${DEVICE}

${SUDO} mkdir ${MOUNTPOINT}/conf
${SUDO} mkdir ${MOUNTPOINT}/pkg
# Here is where you add your own packages and configuration to the flash...

echo ""
echo "Unmounting and cleaning up..."
${SUDO} umount $MOUNTPOINT
exit 0
################################################


More information about the flashboot mailing list