# installboot: install the boot package; runs on the installer's machine
-PROG= installboot
+PROG= installboot_minix
BINDIR= /usr/bin
SRCS= installboot.c rawfs.c
cp $MDEC/boot $BOOT
echo Patching position of $BOOT into $ROOT.
-installboot -d "$ROOT" $MDEC/bootblock $BOOT
+installboot_minix -d "$ROOT" $MDEC/bootblock $BOOT
sync
+20120202
+ Rename installboot to installboot_minix.
+
+ Do this BEFORE a 'make world':
+ # rm -f /usr/bin/installboot /usr/sbin/installboot
+ # make -C boot/installboot clean install
+ # make -C usr.sbin/installboot clean install
+ Then 'make clean world' as usual.
+
20120119:
Follow up to previous entry. The same problem also exists for
the man pages.
.else
image: includes services
${PAD_KERNEL_TEXT}
- installboot -image $@ $(KERNEL) $(PROGRAMS)
+ installboot_minix -image $@ $(KERNEL) $(PROGRAMS)
.endif
# rebuild the program or system libraries
# Install the boot monitor on the root device and make it bootable.
install -cs -m 644 $mdec/boot $rootdir/boot/boot || exit
sync
- installboot -device $root $mdec/bootblock /boot/boot || exit
+ installboot_minix -device $root $mdec/bootblock /boot/boot || exit
test $realroot != $root && umount $root
;;
hdboot)
umount $dev || exit
# Make bootable and copy the boot parameters.
- installboot -d $dev $mdec/bootblock /boot/boot || exit
+ installboot_minix -d $dev $mdec/bootblock /boot/boot || exit
pfile=fdbootparams
if [ -f $pfile ]
then echo "Using floppy boot parameters from file $pfile."
# installboot -m needs at least 1KB
dd < /dev/zero >tmpimage count=2
partition -fm tmpimage 2 81:$rootsects* 0:0 81:$usrsects
- installboot -m tmpimage /usr/mdec/masterboot
+ installboot_minix -m tmpimage /usr/mdec/masterboot
dd < tmpimage > subpart count=1
primsects=`expr 1 + $rootsects + $usrsects`
dd < /dev/zero count=$padsects
} > hdimage
partition -m hdimage 81:`expr $primsects + $padsects`*
- installboot -m hdimage /usr/mdec/masterboot
+ installboot_minix -m hdimage /usr/mdec/masterboot
}
retrieve()
hdemu_root_changes()
{
- $RELEASEDIR/usr/bin/installboot -d $TMPDISKROOT \
+ $RELEASEDIR/usr/bin/installboot_minix -d $TMPDISKROOT \
$RELEASEDIR/usr/mdec/bootblock boot/boot
echo \
'bootcd=2
usb_root_changes()
{
- $RELEASEDIR/usr/bin/installboot -d $TMPDISKROOT \
+ $RELEASEDIR/usr/bin/installboot_minix -d $TMPDISKROOT \
$RELEASEDIR/usr/mdec/bootblock boot/boot
echo \
'bios_wini=yes
dd if=$TMPDISKUSR bs=$BS count=$USRBLOCKS ) >m
mv m $IMG
# Make CD partition table
- installboot -m $IMG /usr/mdec/masterboot
+ installboot_minix -m $IMG /usr/mdec/masterboot
# Make sure there is no hole..! Otherwise the ISO format is
# unreadable.
partition -m $IMG 0 81:$isosects 81:$ROOTSECTS 81:$USRSECTS
.include <bsd.own.mk>
-PROG= installboot
-MAN= installboot.8
-SRCS= installboot.c sum.c machines.c fstypes.c
+PROG= installboot_nbsd
+MAN= installboot_nbsd.8
+SRCS= installboot.c sum.c machines.c fstypes.c install_master.c
-ARCH_XLAT= amd64-i386.c news68k-news.c newsmips-news.c
-ARCH_XLAT+= sun2-sun68k.c sun3-sun68k.c
+ARCH_XLAT= amd64-i386.c
+#ARCH_XLAT= amd64-i386.c news68k-news.c newsmips-news.c
+#ARCH_XLAT+= sun2-sun68k.c sun3-sun68k.c
.if !defined(SMALLPROG) && !defined(ARCH_FILES)
-ARCH_FILES= alpha.c amiga.c emips.c ews4800mips.c hp300.c hp700.c i386.c
-ARCH_FILES+= landisk.c macppc.c news.c next68k.c pmax.c
-ARCH_FILES+= sparc.c sparc64.c sun68k.c vax.c x68k.c
+ARCH_FILES= i386.c
+#ARCH_FILES= alpha.c amiga.c emips.c ews4800mips.c hp300.c hp700.c i386.c
+#ARCH_FILES+= landisk.c macppc.c news.c next68k.c pmax.c
+#ARCH_FILES+= sparc.c sparc64.c sun68k.c vax.c x68k.c
.else
ARCH_FILES?= ${ARCH_XLAT:M${MACHINE}-*:S/${MACHINE}-//}
.if empty(ARCH_FILES)
SRCS+=${ARCH_FILES}
-.if empty(ARCH_FILES:C/(macppc|news|sparc|sun68k|x68k)/stg2/:Mstg2.c)
CPPFLAGS += -DNO_STAGE2
-.else
-SRCS+= bbinfo.c
+#.if empty(ARCH_FILES:C/(macppc|news|sparc|sun68k|x68k)/stg2/:Mstg2.c)
+#CPPFLAGS += -DNO_STAGE2
+#.else
+#SRCS+= bbinfo.c
# fstypes are only needed for 'stage2' and then only from bbinfo.
-SRCS+= ffs.c
-.if SMALLPROG
-CPPFLAGS+= -DNO_FFS_SWAP
-.else
-SRCS+= ffs_bswap.c
-.endif
+#SRCS+= ffs.c
+#.if SMALLPROG
+#CPPFLAGS+= -DNO_FFS_SWAP
+#.else
+#SRCS+= ffs_bswap.c
+#.endif
#SRCS+= ext2fs.c ext2fs_bswap.c
-.endif
+#.endif
+
+SRCS+= minixfs3.c
-UFSSRC= ${NETBSDSRCDIR}/sys/ufs
+#UFSSRC= ${NETBSDSRCDIR}/sys/ufs
+#.PATH: ${.CURDIR}/arch ${UFSSRC}/ffs ${UFSSRC}/ext2fs
+.PATH: ${.CURDIR}/arch
CPPFLAGS+= -I${.CURDIR} -I.
-.PATH: ${.CURDIR}/arch ${UFSSRC}/ffs ${UFSSRC}/ext2fs
.if !defined(HOSTPROGNAME)
.if defined(HAVE_GCC) || defined(HAVE_PCC)
IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT |
IB_MODULES | IB_BOOTCONF };
+#ifdef __minix
+struct ib_mach ib_mach_i686 =
+ { "i686", i386_setboot, no_clearboot, i386_editboot,
+ IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
+ IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT |
+ IB_MODULES | IB_BOOTCONF };
+#endif
+
struct ib_mach ib_mach_amd64 =
{ "amd64", i386_setboot, no_clearboot, i386_editboot,
IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR |
--- /dev/null
+/* Based on original installboot from MINIX 3.
+ *
+ * installboot 3.0 - Make a device bootable Author: Kees J. Bot
+ * 21 Dec 1991
+ */
+
+#define _POSIX_SOURCE 1
+#define _MINIX 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#define BOOTBLOCK 0 /* Of course */
+#define BOOT_BLOCK_SIZE 1024
+#define SIGNATURE 0xAA55 /* Boot block signature. */
+#define SIGPOS 510 /* Where to put signature word. */
+#define PARTPOS 446 /* Offset to the partition table in a master
+ * boot block.
+ */
+
+
+static int rawfd; /* File descriptor to open device. */
+static const char *rawdev; /* Name of device. */
+
+
+static void report(const char *label)
+/* installboot: label: No such file or directory */
+{
+ fprintf(stderr, "installboot: %s: %s\n", label, strerror(errno));
+}
+
+static void fatal(const char *label)
+{
+ report(label);
+ exit(1);
+}
+
+static void bread(FILE *f, char *name, void *buf, size_t len)
+/* Read len bytes. Don't dare return without them. */
+{
+ if (len > 0 && fread(buf, len, 1, f) != 1) {
+ if (ferror(f)) fatal(name);
+ fprintf(stderr, "installboot: Unexpected EOF on %s\n", name);
+ exit(1);
+ }
+}
+
+static void readblock(off_t blk, char *buf, int block_size)
+/* For rawfs, so that it can read blocks. */
+{
+ int n;
+
+ if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
+ || (n= read(rawfd, buf, block_size)) < 0
+ ) fatal(rawdev);
+
+ if (n < block_size) {
+ fprintf(stderr, "installboot: Unexpected EOF on %s\n", rawdev);
+ exit(1);
+ }
+}
+
+static void writeblock(off_t blk, const char *buf, int block_size)
+/* Add a function to write blocks for local use. */
+{
+ if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
+ || write(rawfd, buf, block_size) < 0
+ ) fatal(rawdev);
+}
+
+
+/* A temp stub until fdisk is ported to MINIX */
+void install_master(const char *device, char *masterboot, char **guide)
+/* Booting a hard disk is a two stage process: The master bootstrap in sector
+ * 0 loads the bootstrap from sector 0 of the active partition which in turn
+ * starts the operating system. This code installs such a master bootstrap
+ * on a hard disk. If guide[0] is non-null then the master bootstrap is
+ * guided into booting a certain device.
+ */
+{
+ FILE *masf;
+ unsigned long size;
+ static char buf[_MAX_BLOCK_SIZE];
+
+ /* Open device. */
+ if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
+
+ /* Open the master boot code. */
+ if ((masf= fopen(masterboot, "r")) == NULL) fatal(masterboot);
+
+ size= PARTPOS;
+
+ /* Read the master boot block, patch it, write. */
+ readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
+
+ memset(buf, 0, PARTPOS);
+ (void) bread(masf, masterboot, buf, size);
+
+ /* Install signature. */
+ buf[SIGPOS+0]= (SIGNATURE >> 0) & 0xFF;
+ buf[SIGPOS+1]= (SIGNATURE >> 8) & 0xFF;
+
+ writeblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
+}
+
+int isoption(const char *option, const char *test)
+/* Check if the option argument is equals "test". Also accept -i as short
+ * for -image, and the special case -x for -extract.
+ */
+{
+ if (strcmp(option, test) == 0) return 1;
+ if (option[0] != '-' && strlen(option) != 2) return 0;
+ if (option[1] == test[1]) return 1;
+ if (option[1] == 'x' && test[1] == 'e') return 1;
+ return 0;
+}
#include <sys/ioctl.h>
#include <sys/utsname.h>
+#include <sys/ttycom.h>
#include <assert.h>
#include <err.h>
const char *op;
ib_flags unsupported_flags;
+ /* XXX Temp stuff for MINIX until fdisk is ported */
+ if ((4 <= argc && argc <= 6) && isoption(argv[1], "-master")) {
+ install_master(argv[2], argv[3], argv + 4);
+ exit(0);
+ }
+
setprogname(argv[0]);
params = &installboot_params;
memset(params, 0, sizeof(*params));
op = "write";
mode = O_RDWR;
}
+
+ if (minixfs3_is_minix_partition(params->filesystem)) {
+ /* Old setups has just 1 sector for bootblock,
+ * but bootxx_minixfs is ~8Kb, so we require new setups
+ * to have 32 sectors before the first subpartition.
+ * This prevents from overwriting FS on old setups.
+ */
+ if (!minixfs3_has_bootblock_space(params->filesystem)) {
+ err(1, "No space for bootxx, you should have 32 sectors"
+ " before the first subpartition on %s",
+ params->filesystem);
+ }
+ }
+
/* XXX should be specified via option */
params->sectorsize = DFL_SECSIZE;
if ((params->fsfd = open(params->filesystem, mode, 0600)) == -1)
int ext2fs_match(ib_params *);
int ext2fs_findstage2(ib_params *, uint32_t *, ib_block *);
+ /* install_master.c */
+void install_master(const char *device, char *masterboot, char **guide);
+int isoption(const char *option, const char *test);
+
+ /* minixfs3.c */
+int minixfs3_is_minix_partition(const char* partition);
+int minixfs3_has_bootblock_space(const char* partition);
+
+
/* machines.c */
extern struct ib_mach ib_mach_alpha;
extern struct ib_mach ib_mach_amd64;
extern struct ib_mach ib_mach_hp300;
extern struct ib_mach ib_mach_hp700;
extern struct ib_mach ib_mach_i386;
+#ifdef __minix
+extern struct ib_mach ib_mach_i386;
+#endif
extern struct ib_mach ib_mach_landisk;
extern struct ib_mach ib_mach_macppc;
extern struct ib_mach ib_mach_news68k;
-.\" $NetBSD: installboot.8,v 1.79 2011/11/03 20:09:18 martin Exp $
+.\" $NetBSD: installboot_nbsd.8,v 1.79 2011/11/03 20:09:18 martin Exp $
.\"
.\" Copyright (c) 2002-2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
.Dt INSTALLBOOT 8
.Os
.Sh NAME
-.Nm installboot
+.Nm installboot_nbsd
.Nd install disk bootstrap software
.
.Sh SYNOPSIS
.Op Fl fnv
.Op Fl B Ar s2bno
.Op Fl b Ar s1bno
-.Op Fl m Ar machine
.Op Fl o Ar options
.Op Fl t Ar fstype
.Ar filesystem
.Nm
.Fl c
.Op Fl fnv
-.Op Fl m Ar machine
.Op Fl o Ar options
.Op Fl t Ar fstype
.Ar filesystem
.Nm
.Fl e
.Op Fl fnv
-.Op Fl m Ar machine
.Op Fl o Ar options
.Ar bootstrap
+.Nm
+.Fl m(aster)
+.Ar device
+.Ar masterboot
.
.Sh DESCRIPTION
The
.Nm
to ignore some errors.
.
-.It Fl m Ar machine
-Use
-.Ar machine
-as the target machine type.
-The default machine is determined from
-.Xr uname 3
-and then
-.Ev MACHINE .
-The following machines are currently supported by
-.Nm :
-.Bd -ragged -offset indent
-.Sy alpha ,
-.Sy amd64 ,
-.Sy amiga ,
-.Sy ews4800mips ,
-.Sy hp300 ,
-.Sy hp700 ,
-.Sy i386 ,
-.Sy landisk ,
-.Sy macppc ,
-.Sy news68k ,
-.Sy newsmips ,
-.Sy next68k ,
-.Sy pmax ,
-.Sy sparc ,
-.Sy sparc64 ,
-.Sy sun2 ,
-.Sy sun3 ,
-.Sy vax ,
-.Sy x68k
-.Ed
-.
-.
.It Fl n
Do not write to
.Ar filesystem .
.Ss common
Verbosely install the Berkeley Fast File System primary bootstrap on to disk
.Sq sd0 :
-.Dl Ic installboot -v /dev/rsd0c /usr/mdec/bootxx_ffs
+.Dl Ic installboot_nbsd -v /dev/rsd0c /usr/mdec/bootxx_ffs
Note: the
.Dq whole disk
partition (c on some ports, d on others) is used here, since the a partition
.Pp
Remove the primary bootstrap from disk
.Sq sd1 :
-.Dl Ic installboot -c /dev/rsd1c
+.Dl Ic installboot_nbsd -c /dev/rsd1c
.
.Ss Nx Ns Tn /amiga
Modify the command line to change the default from "netbsd -ASn2" to
"netbsd -S":
-.Dl Ic installboot -m amiga -o command="netbsd -S" /dev/rsd0a /usr/mdec/bootxx_ffs
+.Dl Ic installboot_nbsd -m amiga -o command="netbsd -S" /dev/rsd0a /usr/mdec/bootxx_ffs
.
.Ss Nx Ns Tn /ews4800mips
Install the System V Boot File System primary bootstrap on to disk
with the secondary bootstrap
.Sq Pa /boot
already present in the SysVBFS partition on the disk:
-.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx_bfs
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx_bfs
.
.Ss Nx Ns Tn /i386 and Nx Ns Tn /amd64
Install new boot blocks on an existing mounted root file system on
setting the timeout to five seconds, after copying a new secondary
bootstrap:
.Dl Ic cp /usr/mdec/boot /boot
-.Dl Ic installboot -v -o timeout=5 /dev/rwd0a /usr/mdec/bootxx_ffsv1
+.Dl Ic installboot_nbsd -v -o timeout=5 /dev/rwd0a /usr/mdec/bootxx_ffsv1
.
.Pp
Create a bootable CD-ROM with an ISO9660
.Dl Ic cp sys/arch/i386/compile/mykernel/netbsd cdrom/netbsd
.Dl Ic cp /usr/mdec/boot cdrom/boot
.Dl Ic cp /usr/mdec/bootxx_cd9660 bootxx
-.Dl Ic installboot -o console=com0,speed=19200 -m i386 -e bootxx
+.Dl Ic installboot_nbsd -o console=com0,speed=19200 -m i386 -e bootxx
.Dl Ic makefs -t cd9660 -o 'bootimage=i386;bootxx,no-emul-boot' boot.iso \
cdrom
.
.Dl Ic cp /usr/mdec/boot /mnt/boot
.Dl Ic gzip -9 \*[Lt] sys/arch/i386/compile/mykernel/netbsd \*[Gt] /mnt/netbsd.gz
.Dl Ic umount /mnt
-.Dl Ic installboot -v /dev/rfd0a /usr/mdec/bootxx_ffsv1
+.Dl Ic installboot_nbsd -v /dev/rfd0a /usr/mdec/bootxx_ffsv1
.
.Pp
Create a bootable FAT file system on
.Dl Ic cp /usr/mdec/boot /mnt/boot
.Dl Ic cp path/to/kernel /mnt/netbsd
.Dl Ic umount /mnt
-.Dl Ic installboot -t raw /dev/rwd1a /usr/mdec/bootxx_msdos
+.Dl Ic installboot_nbsd -t raw /dev/rwd1a /usr/mdec/bootxx_msdos
.Pp
Make the existing FAT16 filesystem on
.Sq sd0e
.Dl Ic cp /usr/mdec/boot /mnt/boot
.Dl Ic cp path/to/kernel /mnt/netbsd
.Dl Ic umount /mnt
-.Dl Ic installboot /dev/rsd0e /usr/mdec/bootxx_fat16
+.Dl Ic installboot_nbsd /dev/rsd0e /usr/mdec/bootxx_fat16
It may also be necessary to use
.Nm fdisk
to make the device itself bootable.
.Pp
Switch the existing installed bootstrap to use a serial console without
reinstalling or altering other options such as timeout.
-.Dl Ic installboot -e -o console=com0 /dev/rwd0a
+.Dl Ic installboot_nbsd -e -o console=com0 /dev/rwd0a
.Ss Nx Ns Tn /macppc
Note the
.Nm
.Pp
Install the Berkeley Fast File System primary bootstrap on to disk
.Sq wd0 :
-.Dl Ic installboot /dev/rwd0c /usr/mdec/bootxx /ofwboot
+.Dl Ic installboot_nbsd /dev/rwd0c /usr/mdec/bootxx /ofwboot
.Pp
The secondary
.Nx Ns Tn /macppc
.Ss Nx Ns Tn /next68k
Install the bootstrap on to disk
.Sq sd0 :
-.Dl Ic installboot /dev/rsd0c /usr/mdec/boot
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/boot
.Pp
.
.Ss Nx Ns Tn /pmax
Install the Berkeley Fast File System primary bootstrap on to disk
.Sq sd0 :
-.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx_ffs
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx_ffs
.Pp
.Nx Ns Tn /pmax
requires that this file system starts at block 0 of the disk.
.Pp
Install the ISO 9660 primary bootstrap in the file
.Pa /tmp/cd-image :
-.Dl Ic installboot -m pmax /tmp/cd-image /usr/mdec/bootxx_cd9660
+.Dl Ic installboot_nbsd -m pmax /tmp/cd-image /usr/mdec/bootxx_cd9660
.Pp
Make an ISO 9660 filesystem in the file
.Pa /tmp/cd-image
.Dl ...
.Dl 48 51 iso-source-dir/bootxx_cd9660
.Dl ...
-.Dl Ic installboot -b `expr 48 \e* 4` /tmp/cd-image /usr/mdec/bootxx_cd9660
+.Dl Ic installboot_nbsd -b `expr 48 \e* 4` /tmp/cd-image /usr/mdec/bootxx_cd9660
.
.Ss Nx Ns Tn /sparc
Install the Berkeley Fast File System primary bootstrap on to disk
with the secondary bootstrap
.Sq Pa /boot
already present:
-.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx /boot
.
.Ss Nx Ns Tn /sparc64
Install the primary bootstrap on to disk
.Sq sd0 :
-.Dl Ic installboot /dev/rsd0c /usr/mdec/bootblk
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootblk
.Pp
The secondary
.Nx Ns Tn /sparc64
with the secondary bootstrap
.Sq Pa /boot
already present:
-.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot
+.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx /boot
.
.Sh SEE ALSO
.Xr uname 3 ,
ib_mach_hp300,
ib_mach_hp700,
ib_mach_i386,
+#ifdef __minix
+ ib_mach_i686,
+#endif
ib_mach_landisk,
ib_mach_macppc,
ib_mach_news68k,
&ib_mach_hp300,
&ib_mach_hp700,
&ib_mach_i386,
+#ifdef __minix
+ &ib_mach_i686,
+#endif
&ib_mach_landisk,
&ib_mach_macppc,
&ib_mach_news68k,
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/bootblock.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef DFL_SECSIZE
+#define DFL_SECSIZE 512
+#endif
+
+#define MFS_FIRST_SUBP_OFFSET 32
+
+static int minixfs3_read_mbr(const char* device, char* buf)
+{
+ int fd;
+ int bytes;
+ int n;
+
+ fd = open(device, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "Can't open %s: %s\n", device, strerror(errno));
+ return 1;
+ }
+
+ if (lseek(fd, MBR_PART_OFFSET, SEEK_SET) != MBR_PART_OFFSET) {
+ fprintf(stderr, "Can't seek in %s to %d: %s\n",
+ device, MBR_PART_OFFSET, strerror(errno));
+ close(fd);
+ return 1;
+ }
+
+ bytes = DFL_SECSIZE - MBR_PART_OFFSET;
+
+ if ((n = read(fd, buf, bytes)) != bytes) {
+ fprintf(stderr, "Can't read %d bytes from %s, %d read instead"
+ ": %s\n",
+ bytes, device, n, strerror(errno));
+ close(fd);
+ return 1;
+ }
+
+ if ((uint8_t)buf[bytes-2] != 0x55 || (uint8_t)buf[bytes-1] != 0xAA) {
+ fprintf(stderr, "No MBR on %s, signature is %x\n",
+ device, *(uint16_t*)(&buf[bytes-2]));
+ close(fd);
+ return 1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+
+int minixfs3_is_minix_partition(const char* partition)
+{
+ char buf[DFL_SECSIZE]; /* part table + signature */
+ int name_length = strlen(partition);
+
+ /* partition must be 0-3 */
+ if (atol(&partition[name_length-1]) >= 4) {
+ fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
+ partition);
+ return 0;
+ }
+
+ /* it should be partition device, not disk */
+ if (partition[name_length-2] != 'p') {
+ fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
+ partition);
+ return 0;
+ }
+
+ /* MINIX 3 partition with current scheme *must* have subpartitions,
+ * thus MBR has signature. minixfs3_read_mbr checks the signature.
+ */
+ if (minixfs3_read_mbr(partition, buf))
+ return 0;
+ return 1;
+}
+
+/* bootxx from NetBSD is ~8Kb, and old MINIX installations have just
+ * 1Kb of space for their bootblock. Check if there is enough space
+ * to install bootxx_minixfs3. New installation should have 16Kb before
+ * the first subpartition.
+ */
+int minixfs3_has_bootblock_space(const char* partition)
+{
+ char buf[DFL_SECSIZE]; /* part table + signature */
+ char disk[NAME_MAX];
+ struct mbr_partition *part;
+ uint32_t first_subpartition = (uint32_t) ~0;
+ uint32_t parent_partition = 0;
+ int i;
+ int name_length = strlen(partition);
+
+ /* partition must be 0-3 */
+ if (atol(&partition[name_length-1]) >= 4) {
+ fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
+ partition);
+ exit(1);
+ }
+ /* it should be partition device, not disk */
+ if (partition[name_length-2] != 'p') {
+ fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
+ partition);
+ exit(1);
+ }
+
+ if (minixfs3_read_mbr(partition, buf))
+ exit(1);
+
+ part = (struct mbr_partition *) buf;
+
+ for (i = 0; i < 4; i++) {
+ if (part[i].mbrp_size && part[i].mbrp_start < first_subpartition)
+ first_subpartition = part[i].mbrp_start;
+ }
+
+ strncpy(disk, partition, name_length - 2);
+ disk[name_length - 2] = '\0';
+
+ if (minixfs3_read_mbr(disk, buf))
+ exit(1);
+
+ for (i = 0; i < 4; i++) {
+ struct mbr_partition *p = &part[i];
+ if (p->mbrp_size && p->mbrp_start <= first_subpartition
+ && (p->mbrp_start + p->mbrp_size) > first_subpartition) {
+ parent_partition = p->mbrp_start;
+ break;
+ }
+ }
+
+ if ((first_subpartition - parent_partition) < MFS_FIRST_SUBP_OFFSET)
+ return 0;
+ else
+ return 1;
+}