summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2010-10-31 19:51:33 +0100
committerWaldemar Brodkorb <wbx@openadk.org>2010-10-31 19:51:33 +0100
commit8f5add1754284c4e0f6162797b20b5d08b2e2882 (patch)
treeefdbb6e29576ae5347acb7c85aa7064f3eef1b80
parent119fb7326416a7d22f2aa89cc3c3b9d686030f43 (diff)
rework installation scripts for block devices
Avoid sfdisk, parted and chroot to be more portable. Compile Host grub in target/tools, only used for ibmx40 target right now. Add pt - partition table manager from OpenWrt with some additions and portability fixes. Cfgfs support missing, coming soon.
-rwxr-xr-xscripts/install-rb532.sh152
-rwxr-xr-xscripts/install.sh200
-rw-r--r--target/ibmx40/Makefile8
-rw-r--r--target/tools/grub/Makefile24
-rw-r--r--tools/adk/Makefile6
-rw-r--r--tools/adk/pt.c256
6 files changed, 488 insertions, 158 deletions
diff --git a/scripts/install-rb532.sh b/scripts/install-rb532.sh
new file mode 100755
index 000000000..9011388c7
--- /dev/null
+++ b/scripts/install-rb532.sh
@@ -0,0 +1,152 @@
+#!/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.
+
+if [ $(id -u) -ne 0 ];then
+ printf "Installation is only possible as root\n"
+ exit 1
+fi
+
+printf "Checking if sfdisk is installed"
+sfdisk=$(which sfdisk)
+
+if [ ! -z $sfdisk -a -x $sfdisk ];then
+ printf "...okay\n"
+else
+ printf "...failed\n"
+ exit 1
+fi
+
+printf "Checking if parted is installed"
+parted=$(which parted)
+
+if [ ! -z $parted -a -x $parted ];then
+ printf "...okay\n"
+else
+ printf "...failed\n"
+ exit 1
+fi
+
+printf "Checking if mke2fs is installed"
+mke2fs=$(which mke2fs)
+
+if [ ! -z $mke2fs -a -x $mke2fs ];then
+ printf "...okay\n"
+else
+ printf "...failed\n"
+ exit 1
+fi
+
+printf "Checking if tune2fs is installed"
+tune2fs=$(which tune2fs)
+
+if [ ! -z $tune2fs -a -x $tune2fs ];then
+ printf "...okay\n"
+else
+ printf "...failed\n"
+ exit 1
+fi
+
+if [ -z $1 ];then
+ printf "Please give your compact flash or USB device as first parameter\n"
+ 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 [ -z $3 ];then
+ printf "Please give the kernel as third parameter\n"
+ exit 2
+ fi
+ if [ -f $3 ];then
+ printf "Installing $3 on $1\n"
+ else
+ printf "$3 is not a file, Exiting\n"
+ exit 1
+ fi
+ if [ -b $1 ];then
+ printf "Using $1 as CF/USB disk for installation\n"
+ printf "This will destroy all data on $1, are you sure?\n"
+ printf "Type "y" to continue\n"
+ read y
+ if [ "$y" = "y" ];then
+ $sfdisk -l $1 2>&1 |grep 'No medium'
+ if [ $? -eq 0 ];then
+ exit 1
+ else
+ printf "Starting with installation\n"
+ fi
+ else
+ printf "Exiting.\n"
+ exit 1
+ fi
+ else
+ printf "Sorry $1 is not a block device\n"
+ exit 1
+ fi
+fi
+
+
+if [ $(mount | grep $1| wc -l) -ne 0 ];then
+ printf "Block device $1 is in use, please umount first.\n"
+ exit 1
+fi
+
+
+if [ $($sfdisk -l $1 2>/dev/null|grep Empty|wc -l) -ne 4 ];then
+ printf "Partitions already exist, should I wipe them?\n"
+ printf "Type y to continue\n"
+ read y
+ if [ $y = "y" ];then
+ printf "Wiping existing partitions\n"
+ dd if=/dev/zero of=$1 bs=512 count=1 >/dev/null 2>&1
+ else
+ printf "Exiting.\n"
+ exit 1
+ fi
+fi
+
+printf "Create partition and filesystem for rb532\n"
+rootpart=${1}2
+$parted -s $1 mklabel msdos
+sleep 2
+maxsize=$(env LC_ALL=C $parted $1 -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
+rootsize=$(($maxsize-2))
+
+$parted -s $1 unit cyl mkpart primary ext2 0 1
+$parted -s $1 unit cyl mkpart primary ext2 1 $rootsize
+$parted -s $1 unit cyl mkpart primary fat32 $rootsize $maxsize
+$parted -s $1 set 1 boot on
+$sfdisk --change-id $1 1 27
+$sfdisk --change-id $1 3 88
+sleep 2
+$mke2fs ${1}2
+sync
+dd if=$3 of=${1}1 bs=2048
+sync
+sleep 2
+$tune2fs -c 0 -i 0 -m 1 ${rootpart} >/dev/null
+if [ $? -eq 0 ];then
+ printf "Successfully disabled filesystem checks on ${rootpart}\n"
+else
+ printf "Disabling filesystem checks failed, Exiting.\n"
+ exit 1
+fi
+
+tmp=$(mktemp -d)
+mount -t ext2 ${rootpart} $tmp
+printf "Extracting install archive\n"
+tar -C $tmp -xzpf $2
+printf "Fixing permissions\n"
+chmod 1777 $tmp/tmp
+chmod 4755 $tmp/bin/busybox
+umount $tmp
+printf "Successfully installed.\n"
+exit 0
diff --git a/scripts/install.sh b/scripts/install.sh
index b436767a5..3e07a7181 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -1,26 +1,11 @@
#!/usr/bin/env bash
-if [ $(id -u) -ne 0 ];then
- printf "Installation is only possible as root\n"
- exit 1
-fi
-
-printf "Checking if sfdisk is installed"
-sfdisk=$(which sfdisk)
-
-if [ ! -z $sfdisk -a -x $sfdisk ];then
- printf "...okay\n"
-else
- printf "...failed\n"
- exit 1
-fi
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
-printf "Checking if parted is installed"
-parted=$(which parted)
+TOPDIR=$(pwd)
-if [ ! -z $parted -a -x $parted ];then
- printf "...okay\n"
-else
- printf "...failed\n"
+if [ $(id -u) -ne 0 ];then
+ printf "Installation is only possible as root\n"
exit 1
fi
@@ -34,27 +19,17 @@ else
exit 1
fi
-printf "Checking if tune2fs is installed"
-tune2fs=$(which tune2fs)
-
-if [ ! -z $tune2fs -a -x $tune2fs ];then
- printf "...okay\n"
-else
- printf "...failed\n"
- exit 1
-fi
-
cfgfs=1
-rb532=0
-while getopts "nr" option
+quiet=0
+while getopts "nq" option
do
case $option in
+ q)
+ quiet=1
+ ;;
n)
cfgfs=0
;;
- r)
- rb532=1
- ;;
*)
printf "Option not recognized\n"
exit 1
@@ -78,33 +53,12 @@ else
printf "$2 is not a file, Exiting\n"
exit 1
fi
- if [ $rb532 -eq 1 ];then
- if [ -z $3 ];then
- printf "Please give the kernel as third parameter\n"
- exit 2
- fi
- if [ -f $3 ];then
- printf "Installing $3 on $1\n"
- else
- printf "$3 is not a file, Exiting\n"
- exit 1
- fi
- fi
if [ -b $1 ];then
printf "Using $1 as CF/USB disk for installation\n"
- printf "This will destroy all data on $1, are you sure?\n"
- printf "Type "y" to continue\n"
- read y
- if [ "$y" = "y" ];then
- $sfdisk -l $1 2>&1 |grep 'No medium'
- if [ $? -eq 0 ];then
- exit 1
- else
- printf "Starting with installation\n"
- fi
- else
- printf "Exiting.\n"
- exit 1
+ 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
else
printf "Sorry $1 is not a block device\n"
@@ -112,26 +66,11 @@ else
fi
fi
-
if [ $(mount | grep $1| wc -l) -ne 0 ];then
printf "Block device $1 is in use, please umount first.\n"
exit 1
fi
-
-if [ $($sfdisk -l $1 2>/dev/null|grep Empty|wc -l) -ne 4 ];then
- printf "Partitions already exist, should I wipe them?\n"
- printf "Type y to continue\n"
- read y
- if [ $y = "y" ];then
- printf "Wiping existing partitions\n"
- dd if=/dev/zero of=$1 bs=512 count=1 >/dev/null 2>&1
- else
- printf "Exiting.\n"
- exit 1
- fi
-fi
-
case $2 in
wrap*)
speed=38400
@@ -141,102 +80,51 @@ case $2 in
;;
esac
-if [ $rb532 -ne 0 ];then
- printf "Create partition and filesystem for rb532\n"
- rootpart=${1}2
- $parted -s $1 mklabel msdos
- sleep 2
- maxsize=$(env LC_ALL=C $parted $1 -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
- rootsize=$(($maxsize-2))
-
- $parted -s $1 unit cyl mkpart primary ext2 0 1
- $parted -s $1 unit cyl mkpart primary ext2 1 $rootsize
- $parted -s $1 unit cyl mkpart primary fat32 $rootsize $maxsize
- $parted -s $1 set 1 boot on
- $sfdisk --change-id $1 1 27
- $sfdisk --change-id $1 3 88
- sleep 2
- $mke2fs ${1}2
- sync
- dd if=$3 of=${1}1 bs=2048
- sync
-else
- rootpart=${1}1
- if [ $cfgfs -eq 0 ];then
- printf "Create partition and filesystem without cfgfs\n"
-$sfdisk $1 << EOF
-,,L
-;
-;
-;
-y
-EOF
- $mke2fs ${rootpart}
- else
- printf "Create partition and filesystem with cfgfs\n"
- $parted -s $1 mklabel msdos
- sleep 2
- maxsize=$(env LC_ALL=C $parted $1 -s unit cyl print |awk '/^Disk/ { print $3 }'|sed -e 's/cyl//')
- rootsize=$(($maxsize-2))
-
- $parted -s $1 unit cyl mkpart primary ext2 0 $rootsize
- $parted -s $1 unit cyl mkpart primary fat32 $rootsize $maxsize
- $parted -s $1 set 1 boot on
- $sfdisk --change-id $1 2 88
- $mke2fs ${1}1
- fi
-fi
-
-if [ $? -eq 0 ];then
- printf "Successfully created partition ${rootpart}\n"
-else
- printf "Partition creation failed, Exiting.\n"
- exit 1
-fi
-
-sleep 2
-$tune2fs -c 0 -i 0 -m 1 ${rootpart} >/dev/null
-if [ $? -eq 0 ];then
- printf "Successfully disabled filesystem checks on ${rootpart}\n"
-else
- printf "Disabling filesystem checks failed, Exiting.\n"
- exit 1
-fi
-
+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
-printf "Extracting install archive\n"
tar -C $tmp -xzpf $2
-printf "Fixing permissions\n"
+printf "Fixing permissions ...\n"
chmod 1777 $tmp/tmp
chmod 4755 $tmp/bin/busybox
-if [ $rb532 -eq 0 ];then
- printf "Installing GRUB bootloader\n"
- mkdir -p $tmp/boot/grub
- mount -o bind /dev $tmp/dev
- chroot $tmp mount -t proc /proc /proc
- chroot $tmp mount -t sysfs /sys /sys
+printf "Installing GRUB bootloader ...\n"
+mkdir -p $tmp/boot/grub
cat << EOF > $tmp/boot/grub/grub.cfg
set default=0
set timeout=1
-serial --unit=0 --speed=$speed
-terminal_output serial
-terminal_input serial
+terminal_output console
+terminal_input console
menuentry "GNU/Linux (OpenADK)" {
insmod ext2
set root=(hd0,1)
- linux /boot/vmlinuz-adk root=/dev/sda1 ro init=/init console=ttyS0,$speed console=tty0 panic=10
+ linux /boot/vmlinuz-adk init=/init
}
EOF
- chroot $tmp grub-install $1
- umount $tmp/proc
- umount $tmp/sys
- umount $tmp/dev
-fi
-
+./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 --root-directory=$tmp $1
umount $tmp
-
printf "Successfully installed.\n"
+rm -rf $tmp
exit 0
diff --git a/target/ibmx40/Makefile b/target/ibmx40/Makefile
index 3c95fc2d1..b50a864fc 100644
--- a/target/ibmx40/Makefile
+++ b/target/ibmx40/Makefile
@@ -7,6 +7,12 @@ include $(TOPDIR)/mk/modules.mk
include $(TOPDIR)/mk/kernel-build.mk
include $(TOPDIR)/mk/image.mk
+$(TOOLS_BUILD_DIR):
+ mkdir -p $(TOOLS_BUILD_DIR)
+
+tools-compile: $(TOOLS_BUILD_DIR)
+ $(MAKE) -C ../tools/grub prepare compile install
+
KERNEL:=$(LINUX_DIR)/arch/x86/boot/bzImage
createinitcrypt:
@@ -26,7 +32,7 @@ imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL)
@echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)"
endif
ifeq ($(FS),usb)
-imageinstall: $(BIN_DIR)/$(ROOTFSTARBALL)
+imageinstall: tools-compile $(BIN_DIR)/$(ROOTFSTARBALL)
@echo "The RootFS tarball is: $(BIN_DIR)/$(ROOTFSTARBALL)"
@echo "To install everything to USB use scripts/install.sh"
endif
diff --git a/target/tools/grub/Makefile b/target/tools/grub/Makefile
new file mode 100644
index 000000000..95d7b2397
--- /dev/null
+++ b/target/tools/grub/Makefile
@@ -0,0 +1,24 @@
+# This file is part of the OpenADK project. OpenADK is copyrighted
+# material, please see the LICENCE file in the top-level directory.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:= grub
+PKG_VERSION:= 1.98
+PKG_RELEASE:= 1
+PKG_MD5SUM:= c0bcf60e524739bb64e3a2d4e3732a59
+PKG_SITES:= ftp://alpha.gnu.org/gnu/grub/
+
+include ../rules.mk
+
+$(WRKBUILD)/.compiled: ${WRKDIST}/.prepared
+ cd $(WRKBUILD) && ./configure --prefix=$(TOPDIR)/bin/tools
+ $(MAKE) -C $(WRKBUILD)
+ touch $@
+
+$(TOPDIR)/bin/tools/bin/grub-install: $(WRKBUILD)/.compiled
+ $(MAKE) -C $(WRKBUILD) install
+
+install: $(TOPDIR)/bin/tools/bin/grub-install
+
+include $(TOPDIR)/mk/tools.mk
diff --git a/tools/adk/Makefile b/tools/adk/Makefile
index 3f2048e68..fd1d0e2c0 100644
--- a/tools/adk/Makefile
+++ b/tools/adk/Makefile
@@ -9,6 +9,10 @@ ${TOPDIR}/bin/tools/depmaker:
${TOPDIR}/bin/tools/pkgrebuild:
$(HOSTCC) -o $(TOPDIR)/bin/tools/pkgrebuild pkgrebuild.c strmap.c
-install: ${TOPDIR}/bin/tools/depmaker ${TOPDIR}/bin/tools/pkgrebuild
+${TOPDIR}/bin/tools/pt:
+ $(HOSTCC) -o $(TOPDIR)/bin/tools/pt pt.c
+
+install: ${TOPDIR}/bin/tools/depmaker ${TOPDIR}/bin/tools/pkgrebuild \
+ $(TOPDIR)/bin/tools/pt
include $(TOPDIR)/mk/tools.mk
diff --git a/tools/adk/pt.c b/tools/adk/pt.c
new file mode 100644
index 000000000..e98550b31
--- /dev/null
+++ b/tools/adk/pt.c
@@ -0,0 +1,256 @@
+/*
+ * pt - partition table utility
+ * Copyright (C) 2010 by Waldemar Brodkorb <wbx@openadk.org>
+ *
+ * just adds some required code to ptgen - partition table generator
+ * Copyright (C) 2006 by Felix Fietkau <nbd@openwrt.org>
+ *
+ * uses parts of afdisk
+ * Copyright (C) 2002 by David Roetzel <david@roetzel.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#if defined(__linux__)
+#include <linux/fs.h>
+#endif
+
+#if defined(__APPLE__)
+#include <sys/disk.h>
+#define BLKGETSIZE DKIOCGETBLOCKCOUNT
+#endif
+
+#define bswap16(x) ( \
+ ((((x) )&(unsigned int)0xff)<< 8) \
+ |((((x)>> 8)&(unsigned int)0xff) ) \
+)
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_le16(x) bswap16(x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le16(x) (x)
+#else
+#error unknown endianness!
+#endif
+
+/* Partition table entry */
+struct pte {
+ unsigned char active;
+ unsigned char chs_start[3];
+ unsigned char type;
+ unsigned char chs_end[3];
+ unsigned int start;
+ unsigned int length;
+};
+
+struct partinfo {
+ unsigned long size;
+ int type;
+};
+
+int verbose = 0;
+int active = 1;
+int heads = -1;
+int sectors = -1;
+struct partinfo parts[4];
+char *filename = NULL;
+
+/*
+ * get the sector size of the block device
+ *
+ * print the sector size
+ */
+
+static void getmaxsize(char *device) {
+ int fd;
+ unsigned long maxsectors=0;
+
+ fd = open(device, O_RDONLY);
+ ioctl(fd, BLKGETSIZE, &maxsectors);
+ printf("%lu\n", maxsectors);
+ close(fd);
+}
+
+/*
+ * parse the size argument, which is either
+ * a simple number (K assumed) or
+ * K, M or G
+ *
+ * returns the size in KByte
+ */
+static long to_kbytes(const char *string) {
+ int exp = 0;
+ long result;
+ char *end;
+
+ result = strtoul(string, &end, 0);
+ switch (tolower(*end)) {
+ case 'k' :
+ case '\0' : exp = 0; break;
+ case 'm' : exp = 1; break;
+ case 'g' : exp = 2; break;
+ default: return 0;
+ }
+
+ if (*end)
+ end++;
+
+ if (*end) {
+ fprintf(stderr, "garbage after end of number\n");
+ return 0;
+ }
+
+ /* result: number + 1024^(exp) */
+ return result * ((2 << ((10 * exp) - 1)) ?: 1);
+}
+
+/* convert the sector number into a CHS value for the partition table */
+static void to_chs(long sect, unsigned char chs[3]) {
+ int c,h,s;
+
+ s = (sect % sectors) + 1;
+ sect = sect / sectors;
+ h = sect % heads;
+ sect = sect / heads;
+ c = sect;
+
+ chs[0] = h;
+ chs[1] = s | ((c >> 2) & 0xC0);
+ chs[2] = c & 0xFF;
+
+ return;
+}
+
+/* round the sector number up to the next cylinder */
+static inline unsigned long round_to_cyl(long sect) {
+ int cyl_size = heads * sectors;
+
+ return sect + cyl_size - (sect % cyl_size);
+}
+
+/* check the partition sizes and write the partition table */
+static int gen_ptable(int nr)
+{
+ struct pte pte[4];
+ unsigned long sect = 0;
+ unsigned int start, len;
+ int i, fd, ret = -1;
+
+ memset(pte, 0, sizeof(struct pte) * 4);
+ for (i = 0; i < nr; i++) {
+ if (!parts[i].size) {
+ fprintf(stderr, "Invalid size in partition %d!\n", i);
+ return -1;
+ }
+ pte[i].active = ((i + 1) == active) ? 0x80 : 0;
+ pte[i].type = parts[i].type;
+ pte[i].start = cpu_to_le16(start = sect + sectors);
+ sect = round_to_cyl(start + parts[i].size * 2);
+ pte[i].length = cpu_to_le16(len = sect - start);
+ to_chs(start, pte[i].chs_start);
+ to_chs(start + len - 1, pte[i].chs_end);
+ if (verbose)
+ fprintf(stderr, "Partition %d: start=%u, end=%u, size=%u\n", i, start * 512, (start + len) * 512, len * 512);
+ }
+
+ if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
+ fprintf(stderr, "Can't open output file '%s'\n",filename);
+ return -1;
+ }
+
+ lseek(fd, 446, SEEK_SET);
+ if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) {
+ fprintf(stderr, "write failed.\n");
+ goto fail;
+ }
+ lseek(fd, 510, SEEK_SET);
+ if (write(fd, "\x55\xaa", 2) != 2) {
+ fprintf(stderr, "write failed.\n");
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ close(fd);
+ return ret;
+}
+
+static void usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [[-t <type>] -p <size>...] \n", prog);
+ fprintf(stderr, "Usage: %s -g <device>\n", prog);
+ exit(1);
+}
+
+int main (int argc, char **argv)
+{
+ char type = 0x83;
+ int ch;
+ int part = 0;
+
+ while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vg:")) != -1) {
+ switch (ch) {
+ case 'o':
+ filename = optarg;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'h':
+ heads = (int) strtoul(optarg, NULL, 0);
+ break;
+ case 's':
+ sectors = (int) strtoul(optarg, NULL, 0);
+ break;
+ case 'p':
+ if (part > 3) {
+ fprintf(stderr, "Too many partitions\n");
+ exit(1);
+ }
+ parts[part].size = to_kbytes(optarg);
+ parts[part++].type = type;
+ break;
+ case 't':
+ type = (char) strtoul(optarg, NULL, 16);
+ break;
+ case 'a':
+ active = (int) strtoul(optarg, NULL, 0);
+ if ((active < 0) || (active > 4))
+ active = 0;
+ break;
+ case 'g':
+ getmaxsize(optarg);
+ exit(0);
+ case '?':
+ default:
+ usage(argv[0]);
+ }
+ }
+ argc -= optind;
+ if (argc || (heads <= 0) || (sectors <= 0) || !filename)
+ usage(argv[0]);
+
+ return gen_ptable(part);
+}