diff --git a/qiboot/6410-partition-sd.sh b/qiboot/6410-partition-sd.sh index 81db829..8dd5f30 100755 --- a/qiboot/6410-partition-sd.sh +++ b/qiboot/6410-partition-sd.sh @@ -3,7 +3,7 @@ # (C) 2008 Openmoko, Inc # Author: Andy Green -# LAYOUT +# LAYOUT (if partition parameter is not specified) # Partition table, then # VFAT takes up remaining space here # then... @@ -13,7 +13,7 @@ EXT3_BACKUP_FS_SECTORS=$(( 8 * 1024 * 2 )) QI_ALLOCATION=$(( 256 * 2 )) # # lastly fixed stuff: 8KByte initial boot, sig, padding - +# # ---------------------- echo "s3c6410 bootable SD partitioning utility" @@ -24,109 +24,258 @@ echo QI_INITIAL=$(( 8 * 2 )) SIG=1 -FDISK_SCRIPT=/tmp/_fds -if [ -z "$1" -o -z "$2" -o -z "$3" ] ; then - echo "This formats a SD card for usage on SD Card boot" - echo " on 6410 based systems" +# display usage message and exit +# any arguments are displayed as an error message +USAGE() +{ echo - echo "Usage:" + [ -z "$1" ] || echo ERROR: $* echo - echo "$0 " + echo 'This formats a SD card for usage on SD Card boot' + echo ' on 6410 based systems' + echo + echo Usage: $(basename "$0") ' ' + echo ' device = disk device name for SD Card, e.g. sde /dev/sdf' + echo ' card = sd | sdhc' + echo ' bootloader = /path/to/qi-binary' + echo ' partition = vfat | NN | NN,NN | NN,NN,NN | NN,NN,NN,NN | no' + echo ' * vfat -> main-vfat[rest] + rootfs[256M] + backupfs[8M]' + echo ' NN -> rootfs1[NN%] + .. + rootfs4[NN%]' + echo ' NN=0 -> will skip the partition' + echo ' no -> leave partitions alone' + echo + echo 'Note: * => default action if no parameter specified' + echo ' sum(NN) must be in [1..100]' + echo + echo 'e.g. '$(basename "$0")' sdb sdhc images/qi 0,30,0,45' + echo ' will format an SDHC with partition 2 receiving 20% and partition 4' + echo ' receiving 45% of the disk capacity and the remaining 35% will be' + echo ' unused.' + echo ' Capacity is calculated after subtracting the space reserved for Qi.' + echo ' Partitions 1 and 3 will not be used.' exit 1 -fi +} -if [ $2 = "sdhc" ] ; then -PADDING=1025 -else -PADDING=1 -fi +[ -z "$1" -o -z "$2" -o -z "$3" ] && USAGE 'Missing arguments' -EXT3_TOTAL_SECTORS=$(( $EXT3_ROOTFS_SECTORS + $EXT3_BACKUP_FS_SECTORS )) -REARSECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING )) +dev="$1" +card="$2" +qi="$3" +partition="$4" -if [ ! -z "`grep $1 /proc/mounts`" ] ; then - echo "ERROR $1 seems to be mounted, that ain't right" - exit 2 -fi +case "${card}" in + [sS][dD][hH][cC]) + PADDING=1025 + ;; + [sS][dD]) + PADDING=1 + ;; + *) + USAGE "${card} is an unknown card type" +esac -bytes=`echo p | fdisk /dev/$1 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d'` -echo bytes = $bytes +# the amount of space that must remain unused at the end of the disk +REAR_SECTORS=$(( $QI_ALLOCATION + $QI_INITIAL + $SIG + $PADDING )) -SECTORS=`expr $bytes / 512` +# validate parameters +[ -b "${dev}" ] || dev="/dev/${dev}" +[ -b "${dev}" ] || USAGE "${dev} is not a valid block device" +[ X"${dev}" = X"${dev%%[0-9]}" ] || USAGE "${dev} is a partition, please use device: perhaps ${dev%%[0-9]}" -if [ -z "$SECTORS" ] ; then - echo "problem finding size for /dev/$1" - exit 4 -fi +echo "Checking for mounted partitions..." +grep "${dev}" /proc/mounts && USAGE "partitions on ${dev} are mounted, please unmount them" +[ -e "${qi}" ] || USAGE "bootloader file: ${qi} does not exist" -if [ "$SECTORS" -le 0 ] ; then - echo "problem finding size for /dev/$1" - exit 3 -fi +# get size of device +bytes=$(echo p | fdisk "${dev}" 2>&1 | sed '/^Disk.*, \([0-9]*\) bytes/s//\1/p;d') +SECTORS=$(($bytes / 512)) -echo "$1 is $SECTORS 512-byte blocks" +[ -z "$SECTORS" ] && USAGE "could not find size for ${dev}" +[ "$SECTORS" -le 0 ] && USAGE "invalid size: '${SECTORS}' for ${dev}" -if [ -z "$4" ] ; then +echo "${dev} is $SECTORS 512-byte blocks" - FATSECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS - $REARSECTORS )) - FATMB=$(( $FATSECTORS / 2048 )) +# Partition and format a disk (or SD card) +# Parameters to format function are: +# +# device -> device to partition e.g. /dev/sdX +# +# Partition 1 parameters: +# +# label -> file system volume label e.g. rootfs +# sizeMB -> size of the partition in MB e.g. 256 +# fstype -> filesystem type e.g. ext2, ext3, vfat (look at /sbin/mkfs.* for others) +# +# Notes: 1. Repeat "label, sizeMB, fstype" for partitions 2..4 +# 2. Partitions 2..4 are optional +# 3. Do not repeat device parameter +# 4. To skip a partition use: 'null 0 none' for that partition - echo "Creating VFAT section $FATMB MB" +FORMAT() +{ + local device label sizeMB fstype p partition flag skip + device="$1"; shift + ( + p=0 + flag=0 + echo o + while [ $# -gt 0 ] + do + label="$1"; shift + sizeMB="$1"; shift + fstype="$1"; shift + p=$((${p} + 1)) + skip=NO + [ ${sizeMB} -le 0 ] && skip=YES + case "${label}" in + [nN][uU][lL][lL]) + skip=YES + ;; + *) + ;; + esac + case "${skip}" in + [yY][eE][sS]|[yY]) + ;; + *) + echo n + echo p + echo ${p} + echo + echo +${sizeMB}M + case "${fstype}" in + [vV][fF][aA][tT]|[mM][sS][dD][oO][sS]) + echo t + # fdisk is "helpful" & will auto select partition if there is only one + # so do not output partition number if this is the first partition + [ "${flag}" -eq 1 ] && echo ${p} + echo 0b + ;; + *) + ;; + esac + flag=1 + ;; + esac + done + echo p + echo w + echo q + ) | fdisk "${device}" + p=0 + while [ $# -gt 0 ] + do + label="$1"; shift + sizeMB="$1"; shift + fstype="$1"; shift + p=$((${p} + 1)) + partition="${dev}${p}" + skip=NO + [ ${sizeMB} -eq 0 ] && skip=YES + case "${label}" in + [nN][uU][lL][lL]) + skip=YES + ;; + esac - # create the script for fdisk - # clear the existing partition table - echo "o" >$FDISK_SCRIPT + case "${skip}" in + [yY][eE][sS]|[yY]) + echo "Skipping: ${partition}" + ;; + *) + echo "Formatting: ${partition} -> ${fstype}[${sizeMB}MB]" + case "${fstype}" in + [vV][fF][aA][tT]|[mM][sS][dD][oO][sS]) + mkfs.${fstype} -n "${label}" "${partition}" + ;; + *) + mkfs.${fstype} -L "${label}" "${partition}" + ;; + esac + ;; + esac + done +} - # add main VFAT storage partition - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "1" >>$FDISK_SCRIPT - # first partition == 1 - echo "" >>$FDISK_SCRIPT - echo "+$FATMB"M >>$FDISK_SCRIPT +# format the disk +case "${partition}" in - # add the normal EXT3 rootfs - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "2" >>$FDISK_SCRIPT - # continue after last - echo "" >>$FDISK_SCRIPT - echo "+$(( $EXT3_ROOTFS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + # this case also hadles the default case (i.e. empty string: "") + [vV][fF][aA][tT]|"") + EXT3_TOTAL_SECTORS=$(( $EXT3_ROOTFS_SECTORS + $EXT3_BACKUP_FS_SECTORS )) + FAT_SECTORS=$(( $SECTORS - $EXT3_TOTAL_SECTORS - $REAR_SECTORS )) + FAT_MB=$(( $FAT_SECTORS / 2048 )) + EXT3_ROOTFS_MB=$(( ${EXT3_ROOTFS_SECTORS} / 2048 )) + EXT3_BACKUP_FS_MB=$(( ${EXT3_BACKUP_FS_SECTORS} / 2048 )) - # add the backup EXT3 rootfs - echo "n" >>$FDISK_SCRIPT - echo "p" >>$FDISK_SCRIPT - echo "3" >>$FDISK_SCRIPT - # continue after last - echo "" >>$FDISK_SCRIPT - echo "+$(( $EXT3_BACKUP_FS_SECTORS / 2048 ))"M >>$FDISK_SCRIPT + echo Creating VFAT partition of ${FAT_MB} MB + echo Creating Linux partition of ${EXT3_ROOTFS_MB} MB + echo Creating backup Linux partition of ${EXT3_BACKUP_FS_MB} MB + FORMAT "${dev}" \ + main-vfat "${FAT_MB}" vfat \ + rootfs "${EXT3_ROOTFS_MB}" ext3 \ + backupfs "${EXT3_BACKUP_FS_MB}" ext3 + ;; - # commit it and exit - echo "w" >>$FDISK_SCRIPT - echo "q" >>$FDISK_SCRIPT + # decode partition or partition list + *,*|100|[1-9][0-9]|[1-9]) + arg="${partition}," + for v in 1 2 3 4 + do + eval n${v}="\${arg%%,*}" + eval n${v}="\${n${v}:-0}" + arg="${arg#*,}," + done + total=$(( ${n1} + ${n2} + ${n3} + ${n4} )) + echo Percentage of disk partitioned = ${total}% + [ ${total} -gt 100 -o ${total} -lt 1 ] && USAGE partition: "'${partition}' => ${total}% outside [1..100]" - # do the partitioning action - fdisk /dev/$1 <$FDISK_SCRIPT + EXT3_TOTAL_SECTORS=$(( $SECTORS - $REAR_SECTORS )) + EXT3_ROOTFS1_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n1 / 100 )) + EXT3_ROOTFS2_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n2 / 100 )) + EXT3_ROOTFS3_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n3 / 100 )) + EXT3_ROOTFS4_SECTORS=$(( $EXT3_TOTAL_SECTORS * $n4 / 100 )) + EXT3_ROOTFS1_MB=$(( ${EXT3_ROOTFS1_SECTORS} / 2048 )) + EXT3_ROOTFS2_MB=$(( ${EXT3_ROOTFS2_SECTORS} / 2048 )) + EXT3_ROOTFS3_MB=$(( ${EXT3_ROOTFS3_SECTORS} / 2048 )) + EXT3_ROOTFS4_MB=$(( ${EXT3_ROOTFS4_SECTORS} / 2048 )) - # prep the filesystems + echo Creating Linux partition 1 of ${EXT3_ROOTFS1_MB} MB + echo Creating Linux partition 2 of ${EXT3_ROOTFS2_MB} MB + echo Creating Linux partition 3 of ${EXT3_ROOTFS3_MB} MB + echo Creating Linux partition 4 of ${EXT3_ROOTFS4_MB} MB - mkfs.vfat "/dev/$1"1 -n main-vfat - mkfs.ext3 "/dev/$1"2 -L rootfs - mkfs.ext3 "/dev/$1"3 -L backupfs + FORMAT "${dev}" \ + rootfs1 "${EXT3_ROOTFS1_MB}" ext3 \ + rootfs2 "${EXT3_ROOTFS2_MB}" ext3 \ + rootfs3 "${EXT3_ROOTFS3_MB}" ext3 \ + rootfs4 "${EXT3_ROOTFS4_MB}" ext3 + ;; + + [Nn]*) + # do not format + ;; + + *) + USAGE "'${partition}' is an unknown partition config" + ;; +esac -fi # if -z $4 # copy the full bootloader image to the right place after the # partitioned area -dd if=$3 of=/dev/$1 bs=512 count=512 \ - seek=$(( $SECTORS - $REARSECTORS )) -dd if=$3 of=/dev/$1 bs=512 \ - seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION )) \ +echo +echo Installing Qi bootloader from: ${qi} + +dd if="${qi}" of="${dev}" bs=512 count=512 \ + seek=$(( $SECTORS - $REAR_SECTORS )) +dd if="${qi}" of="${dev}" bs=512 \ + seek=$(( $SECTORS - $REAR_SECTORS + $QI_ALLOCATION )) \ count=$QI_INITIAL -dd if=/dev/zero of=/dev/$1 bs=512 \ - seek=$(( $SECTORS - $REARSECTORS + $QI_ALLOCATION + $QI_INITIAL )) \ +dd if=/dev/zero of="${dev}" bs=512 \ + seek=$(( $SECTORS - $REAR_SECTORS + $QI_ALLOCATION + $QI_INITIAL )) \ count=$(( $SIG + $PADDING )) # done