export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
-#
-# Artifacts from this script are stored in the IMG_DIR
-#
-rm -rf $IMG_DIR $IMG
-mkdir -p $IMG_DIR $CDFILES
-
while getopts "i" c
do
case "$c" in
: ${IMG=minix_x86.img}
+#
+# Artifacts from this script are stored in the IMG_DIR
+#
+rm -rf $IMG_DIR $IMG
+mkdir -p $IMG_DIR $CDFILES
+
#
# Call build.sh using a sloppy file list so we don't need to remove the installed /etc/fstag
#
cp ${MODDIR}/* $CDFILES/
. ./releasetools/release.functions
cd_root_changes # uses $CDFILES and writes $CDFILES/boot.cfg
- ${CROSS_TOOLS}/nbwriteisofs -s0x0 -l MINIX -B ${DESTDIR}/usr/mdec/bootxx_cd9660 -n $CDFILES ${IMG_DIR}/iso.img
- ISO_SIZE=$((`stat -c %s ${IMG_DIR}/iso.img` / 512))
+ # start the image off with the iso image; reduce root size to reserve
+ ${CROSS_TOOLS}/nbwriteisofs -s0x0 -l MINIX -B ${DESTDIR}/usr/mdec/bootxx_cd9660 -n $CDFILES $IMG
+ ISO_SIZE=$((`stat -c %s $IMG` / 512))
else # just make an empty iso partition
ISO_SIZE=8
fi
-# This script creates a bootable image and should at some point in the future
-# be replaced by makefs.
-#
-# All sized are written in 512 byte blocks
-#
-# we create a disk image of about 2 gig's
-# for alignment reasons, prefer sizes which are multiples of 4096 bytes
-#
-: ${ROOT_SIZE=$(( 64*(2**20) / 512))}
-: ${HOME_SIZE=$(( 128*(2**20) / 512))}
-: ${USR_SIZE=$((1536*(2**20) / 512))}
-
#
# create a fstab entry in /etc this is normally done during the
# setup phase on x86
${CROSS_TOOLS}/nbpwd_mkdb -V 0 -p -d ${DESTDIR} ${DESTDIR}/etc/master.passwd
-#
-# Now given the sizes above use DD to create separate files representing
-# the partitions we are going to use.
-#
-dd if=/dev/zero of=${IMG_DIR}/iso.img bs=512 count=1 seek=$(($ISO_SIZE -1)) 2>/dev/null
-dd if=/dev/zero of=${IMG_DIR}/root.img bs=512 count=1 seek=$(($ROOT_SIZE -1)) 2>/dev/null
-dd if=/dev/zero of=${IMG_DIR}/home.img bs=512 count=1 seek=$(($HOME_SIZE -1)) 2>/dev/null
-dd if=/dev/zero of=${IMG_DIR}/usr.img bs=512 count=1 seek=$(($USR_SIZE -1)) 2>/dev/null
-
# make the different file system. this part is *also* hacky. We first convert
# the METALOG.sanitised using mtree into a input METALOG containing uids and
# gids.
cat ${IMG_DIR}/input | grep "^\./usr/\|^. " | sed "s,\./usr,\.,g" | ${CROSS_TOOLS}/nbtoproto -b ${DESTDIR}/usr -o ${IMG_DIR}/usr.proto
cat ${IMG_DIR}/input | grep "^\./home/\|^. " | sed "s,\./home,\.,g" | ${CROSS_TOOLS}/nbtoproto -b ${DESTDIR}/home -o ${IMG_DIR}/home.proto
-# If in ISO mode, fit the FSes
+# This script creates a bootable image and should at some point in the future
+# be replaced by makefs.
+#
+# All sized are written in 512 byte blocks
+#
+# we create a disk image of about 2 gig's
+# for alignment reasons, prefer sizes which are multiples of 4096 bytes
+#
+: ${ROOT_SIZE=$(( 64*(2**20) / 512))}
+: ${HOME_SIZE=$(( 128*(2**20) / 512))}
+: ${USR_SIZE=$(( 1536*(2**20) / 512))}
+
if [ "$ISOMODE" ]
-then ROOTSIZEARG="-x 5" # give root fs a little breathing room on the CD
-else # give args with the right sizes
+then
+ # In iso mode, make all FSes fit (i.e. as small as possible), but
+ # leave some space on /
+ ROOTSIZEARG="-x 5"
+else
+ # In hd image mode, FSes have fixed sizes
ROOTSIZEARG="-b $((${ROOT_SIZE} / 8))"
USRSIZEARG="-b $((${USR_SIZE} / 8))"
HOMESIZEARG="-b $((${HOME_SIZE} / 8))"
fi
-#
-# Generate /root, /usr and /home partition images.
-#
echo "Writing Minix filesystem images"
-echo " - ROOT"
-${CROSS_TOOLS}/nbmkfs.mfs $ROOTSIZEARG ${IMG_DIR}/root.img ${IMG_DIR}/root.proto
-echo " - USR"
-${CROSS_TOOLS}/nbmkfs.mfs $USRSIZEARG ${IMG_DIR}/usr.img ${IMG_DIR}/usr.proto
-echo " - HOME"
-${CROSS_TOOLS}/nbmkfs.mfs $HOMESIZEARG ${IMG_DIR}/home.img ${IMG_DIR}/home.proto
-
-# Set the sizes based on what was just generated - should change nothing if sizes
-# were specified
-echo "$ROOT_SIZE $USR_SIZE $HOME_SIZE"
-ROOT_SIZE=$((`stat -c %s ${IMG_DIR}/root.img` / 512))
-USR_SIZE=$((`stat -c %s ${IMG_DIR}/usr.img` / 512))
-HOME_SIZE=$((`stat -c %s ${IMG_DIR}/home.img` / 512))
-echo "$ROOT_SIZE $USR_SIZE $HOME_SIZE"
# Do some math to determine the start addresses of the partitions.
# Ensure the start of the partitions are always aligned, the end will
# always be as we assume the sizes are multiples of 4096 bytes, which
# is always true as soon as you have an integer multiple of 1MB.
-#
-ISO_START=0
-ROOT_START=$(($ISO_START + $ISO_SIZE))
+ROOT_START=$ISO_SIZE
+
+echo " - ROOT"
+ROOT_SIZE=$((`${CROSS_TOOLS}/nbmkfs.mfs -d $ROOTSIZEARG -I $(($ROOT_START*512)) $IMG ${IMG_DIR}/root.proto`/512))
USR_START=$(($ROOT_START + $ROOT_SIZE))
+echo " - USR"
+USR_SIZE=$((`${CROSS_TOOLS}/nbmkfs.mfs -d $USRSIZEARG -I $(($USR_START*512)) $IMG ${IMG_DIR}/usr.proto`/512))
HOME_START=$(($USR_START + $USR_SIZE))
+echo " - HOME"
+HOME_SIZE=$((`${CROSS_TOOLS}/nbmkfs.mfs -d $HOMESIZEARG -I $(($HOME_START*512)) $IMG ${IMG_DIR}/home.proto`/512))
-#
-# Merge the partitions into a single image.
-#
-echo "Merging file systems"
-dd if=${IMG_DIR}/iso.img of=${IMG} seek=$ISO_START conv=notrunc
-dd if=${IMG_DIR}/root.img of=${IMG} seek=$ROOT_START conv=notrunc
-dd if=${IMG_DIR}/usr.img of=${IMG} seek=$USR_START conv=notrunc
-dd if=${IMG_DIR}/home.img of=${IMG} seek=$HOME_START conv=notrunc
-
-${CROSS_TOOLS}/nbpartition -m ${IMG} ${ISO_START} 81:${ISO_SIZE} 81:${ROOT_SIZE} 81:${USR_SIZE} 81:${HOME_SIZE}
+${CROSS_TOOLS}/nbpartition -m ${IMG} 0 81:${ISO_SIZE} 81:${ROOT_SIZE} 81:${USR_SIZE} 81:${HOME_SIZE}
mods="`( cd $MODDIR; echo mod* | tr ' ' ',' )`"
if [ "$ISOMODE" ]
#if !defined(__minix)
#define mul64u(a,b) ((uint64_t)(a) * (b))
-#define lseek64(a,b,c,d) lseek(a,b,c)
#endif
/* some Minix specific types that do not conflict with Posix */
int simple = 0, dflag = 0, verbose = 0;
int donttest; /* skip test if it fits on medium */
char *progname;
+uint64_t fs_offset_bytes, fs_offset_blocks, written_fs_size = 0;
time_t current_time;
char *zero;
void *alloc_block(void);
void print_fs(void);
int read_and_set(block_t n);
-void special(char *string);
+void special(char *string, int insertmode);
__dead void usage(void);
void get_block(block_t n, void *buf);
void get_super_block(void *buf);
void put_block(block_t n, void *buf);
+static uint64_t mkfs_seek(uint64_t pos, int whence);
+static ssize_t mkfs_write(void * buf, size_t count);
/*================================================================
* mkfs - make filesystem
ino_t inodes, root_inum;
char *token[MAX_TOKENS], line[LINE_LEN], *sfx;
struct fs_size fssize;
+ int insertmode = 0;
progname = argv[0];
#endif
zone_shift = 0;
extra_space_percent = 0;
- while ((ch = getopt(argc, argv, "B:b:di:ltvx:z:")) != EOF)
+ while ((ch = getopt(argc, argv, "B:b:di:ltvx:z:I:")) != EOF)
switch (ch) {
#ifndef MFS_STATIC_BLOCK_SIZE
case 'B':
break;
(void)sfx; /* shut up warnings about unused variable...*/
#endif
+ case 'I':
+ fs_offset_bytes = strtoul(optarg, (char **) NULL, 0);
+ insertmode = 1;
+ break;
case 'b':
blocks = bblocks = strtoul(optarg, (char **) NULL, 0);
break;
*/
zero = alloc_block();
+ fs_offset_blocks = roundup(fs_offset_bytes, block_size) / block_size;
+
/* Determine the size of the device if not specified as -b or proto. */
maxblocks = sizeup(argv[optind]);
- if (bblocks != 0 && bblocks > maxblocks){
+ if (bblocks != 0 && bblocks + fs_offset_blocks > maxblocks && !insertmode) {
errx(4, "Given size -b %d exeeds device capacity(%d)\n", bblocks, maxblocks);
}
*/
if (argc - optind != 2 && (argc - optind != 1 || blocks == 0)) usage();
- if (maxblocks && blocks > maxblocks) {
+ if (maxblocks && blocks > maxblocks && !insertmode) {
errx(1, "%s: number of blocks too large for device.", argv[optind]);
}
blocks += blocks*extra_space_percent/100;
inodes += inodes*extra_space_percent/100;
/* XXX is it OK to write on stdout? Use warn() instead? Also consider using verbose */
- printf("dynamically sized filesystem: %u blocks, %u inodes\n",
+ fprintf(stderr, "dynamically sized filesystem: %u blocks, %u inodes\n",
(unsigned int) blocks, (unsigned int) inodes);
}
} else {
(unsigned)umap_array_elements);
/* Open special. */
- special(argv[--optind]);
+ special(argv[--optind], insertmode);
if (!donttest) {
uint16_t *testb;
testb = alloc_block();
/* Try writing the last block of partition or diskette. */
- if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) {
- err(1, "couldn't seek to last block to test size (1)");
- }
+ mkfs_seek(mul64u(blocks - 1, block_size), SEEK_SET);
testb[0] = 0x3245;
testb[1] = 0x11FF;
testb[block_size/2-1] = 0x1F2F;
- if ((w=write(fd, testb, block_size)) != block_size)
- err(1, "File system is too big for minor device (write1 %d/%u)",
- w, block_size);
+ w=mkfs_write(testb, block_size);
sync(); /* flush write, so if error next read fails */
- if(lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL) < 0) {
- err(1, "couldn't seek to last block to test size (2)");
- }
+ mkfs_seek(mul64u(blocks - 1, block_size), SEEK_SET);
testb[0] = 0;
testb[1] = 0;
testb[block_size/2-1] = 0;
testb[0], testb[1], testb[block_size-1]);
errx(1, "File system is too big for minor device (read)");
}
- lseek64(fd, mul64u(blocks - 1, block_size), SEEK_SET, NULL);
+ mkfs_seek(mul64u(blocks - 1, block_size), SEEK_SET);
testb[0] = 0;
testb[1] = 0;
testb[block_size/2-1] = 0;
- if (write(fd, testb, block_size) != block_size)
- err(1, "File system is too big for minor device (write2)");
- lseek(fd, 0L, SEEK_SET);
+ mkfs_write(testb, block_size);
+ mkfs_seek(0L, SEEK_SET);
free(testb);
}
(int)next_inode-1, next_zone);
}
+ if(insertmode) printf("%ld\n", written_fs_size);
+
return(0);
/* NOTREACHED */
progname, (unsigned long)d);
}
#else
- size = lseek(fd, 0, SEEK_END);
- if (size == (off_t) -1)
- err(1, "cannot get device size fd=%d: %s", fd, device);
+ size = mkfs_seek(0, SEEK_END);
/* Assume block_t is unsigned */
if (size / block_size > (block_t)(-1ul)) {
d = (block_t)(-1ul);
#endif
}
- if (lseek(fd, (off_t) SUPER_BLOCK_BYTES, SEEK_SET) == (off_t) -1)
- err(1, "super() couldn't seek");
- if (write(fd, buf, SUPER_BLOCK_BYTES) != SUPER_BLOCK_BYTES)
- err(1, "super() couldn't write");
+ mkfs_seek((off_t) SUPER_BLOCK_BYTES, SEEK_SET);
+ mkfs_write(buf, SUPER_BLOCK_BYTES);
/* Clear maps and inodes. */
for (i = START_BLOCK; i < initblks; i++) put_block((block_t) i, zero);
__dead void
usage(void)
{
- fprintf(stderr, "Usage: %s [-dltv] [-b blocks] [-i inodes] [-z zone_shift]\n"
- "\t[-x extra] [-B blocksize] special [proto]\n",
+ fprintf(stderr, "Usage: %s [-dltv] [-b blocks] [-i inodes]\n"
+ "\t[-z zone_shift] [-I offset] [-x extra] [-B blocksize] special [proto]\n",
progname);
exit(4);
}
void
-special(char * string)
+special(char * string, int insertmode)
{
- fd = creat(string, 0777);
- close(fd);
- fd = open(string, O_RDWR);
+ int openmode = O_RDWR;
+ if(!insertmode) openmode |= O_TRUNC;
+ fd = open(string, O_RDWR | O_CREAT, 0644);
if (fd < 0) err(1, "Can't open special file %s", string);
+ mkfs_seek(0, SEEK_SET);
}
memcpy(buf, zero, block_size);
return;
}
- if (lseek64(fd, mul64u(n, block_size), SEEK_SET, NULL) == (off_t)(-1))
- pexit("get_block couldn't seek");
+ mkfs_seek(mul64u(n, block_size), SEEK_SET);
k = read(fd, buf, block_size);
if (k != block_size)
pexit("get_block couldn't read block #%u", (unsigned)n);
{
ssize_t k;
- if(lseek(fd, (off_t) SUPER_BLOCK_BYTES, SEEK_SET) == (off_t) -1)
- err(1, "seek for superblock failed");
+ mkfs_seek((off_t) SUPER_BLOCK_BYTES, SEEK_SET);
k = read(fd, buf, SUPER_BLOCK_BYTES);
if (k != SUPER_BLOCK_BYTES)
err(1, "get_super_block couldn't read super block");
(void) read_and_set(n);
- if (lseek64(fd, mul64u(n, block_size), SEEK_SET, NULL) == (off_t) -1)
- pexit("put_block couldn't seek");
- if (write(fd, buf, block_size)!= block_size)
- pexit("put_block couldn't write block #%u", (unsigned)n);
+ mkfs_seek(mul64u(n, block_size), SEEK_SET);
+ mkfs_write(buf, block_size);
+}
+
+static ssize_t
+mkfs_write(void * buf, size_t count)
+{
+ uint64_t fssize;
+ ssize_t w;
+
+ /* Perform & check write */
+ w = write(fd, buf, count);
+ if(w < 0)
+ err(1, "mkfs_write: write failed");
+ if(w != count)
+ errx(1, "mkfs_write: short write: %ld != %ld", w, count);
+
+ /* Check if this has made the FS any bigger; count bytes after offset */
+ fssize = mkfs_seek(0, SEEK_CUR);
+
+ assert(fssize >= fs_offset_bytes);
+ fssize -= fs_offset_bytes;
+ fssize = roundup(fssize, block_size);
+ if(fssize > written_fs_size)
+ written_fs_size = fssize;
+
+ return w;
+}
+
+/* Seek to position in FS we're creating. */
+static uint64_t
+mkfs_seek(uint64_t pos, int whence)
+{
+ if(whence == SEEK_SET) pos += fs_offset_bytes;
+#ifdef __minix
+ uint64_t newpos;
+ if((lseek64(fd, pos, whence, &newpos)) < 0)
+ err(1, "mkfs_seek: lseek64 failed");
+ return newpos;
+#else
+ off_t newpos;
+ if((newpos=lseek(fd, pos, whence)) == (off_t) -1)
+ err(1, "mkfs_seek: lseek failed");
+ return newpos;
+#endif
}