diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-06-10 06:37:17 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-06-10 06:37:17 +0000 |
commit | 672b6272b68664323e61a94849b7cba009cfa663 (patch) | |
tree | 30bda9f43b7785f885167e9e3aa861524164c481 /sbin/newfs_msdos | |
parent | 4e3779893f81b3793ff10ee98d705bf5353ad646 (diff) |
add newfs_msdos (from freebsd); does not know how to make non-floppy filesystems yet
Diffstat (limited to 'sbin/newfs_msdos')
-rw-r--r-- | sbin/newfs_msdos/Makefile | 58 | ||||
-rw-r--r-- | sbin/newfs_msdos/bootcode.asm | 102 | ||||
-rw-r--r-- | sbin/newfs_msdos/bootcode.h | 54 | ||||
-rw-r--r-- | sbin/newfs_msdos/dosfs.h | 133 | ||||
-rw-r--r-- | sbin/newfs_msdos/newfs_msdos.8 | 135 | ||||
-rw-r--r-- | sbin/newfs_msdos/newfs_msdos.c | 299 |
6 files changed, 781 insertions, 0 deletions
diff --git a/sbin/newfs_msdos/Makefile b/sbin/newfs_msdos/Makefile new file mode 100644 index 00000000000..4b06e5b97fa --- /dev/null +++ b/sbin/newfs_msdos/Makefile @@ -0,0 +1,58 @@ +# $OpenBSD: Makefile,v 1.1 1996/06/10 06:37:11 deraadt Exp $ + +PROG= newfs_msdos +MAN= newfs_msdos.8 + +################################################################### +# +# Everything below is solely intented for maintenance. +# As you can see, it requires as86/ld86 from the ``bcc'' package. +# +# For this reason, the bootcode.h target puts the result into +# ${.CURDIR} + +AS86= as86 +LD86= ld86 +AS86FLAGS= -0 +LD86FLAGS= -0 -s + +CLEANFILES+= *.obj *.bin *.com +.SUFFIXES: .asm .obj .bin .com + +.asm.obj: + ${AS86} ${AS86FLAGS} -o ${.TARGET} ${.IMPSRC} + +.obj.bin: + ${LD86} ${LD86FLAGS} -T 0x7c00 -o ${.PREFIX}.tmp ${.IMPSRC} + dd bs=32 skip=1 of=${.TARGET} if=${.PREFIX}.tmp + rm -f ${.PREFIX}.tmp + +# .com file is just for testing +.obj.com: + ${LD86} ${LD86FLAGS} -T 0x100 -o ${.PREFIX}.tmp ${.IMPSRC} + dd bs=32 skip=1 of=${.TARGET} if=${.PREFIX}.tmp + rm -f ${.PREFIX}.tmp + +## Do NOT depend this on bootcode.bin unless you've installed the +## bcc package! +bootcode.h: ## bootcode.bin + @echo converting bootcode.bin into bootcode.h... + @perl -e 'if(read(STDIN,$$buf,512)<512) { \ + die "Read error on .bin file\n"; \ + } \ + @arr = unpack("C*",$$buf); \ + print "#ifndef BOOTCODE_H\n"; \ + print "#define BOOTCODE_H 1\n\n"; \ + print "/*\n * This file has been generated\n"; \ + print " * automatically. Do not edit.\n */\n\n"; \ + print "static unsigned char bootcode[512] = {\n"; \ + for($$i=0; $$i<512; $$i++) { \ + printf "0x%02x, ",$$arr[$$i]; \ + if($$i % 12 == 11) {print "\n";} \ + } \ + print "};\n\n"; \ + print "#endif /* BOOTCODE_H */\n";' \ + < bootcode.bin > ${.CURDIR}/bootcode.h + +.include <bsd.prog.mk> + diff --git a/sbin/newfs_msdos/bootcode.asm b/sbin/newfs_msdos/bootcode.asm new file mode 100644 index 00000000000..2451e0fe990 --- /dev/null +++ b/sbin/newfs_msdos/bootcode.asm @@ -0,0 +1,102 @@ +;;; Hello emacs, this looks like -*- asm -*- code, doesn't it? +;;; +;;; This forms a simple dummy boot program for use with a tool to +;;; format DOS floppies. All it does is displaying a message, and +;;; recover gracefully by re-initializing the CPU. +;;; +;;; Written by Joerg Wunsch, Dresden. Placed in the public domain. +;;; This software is provided as is, neither kind of warranty applies. +;;; Use at your own risk. +;;; +;;; (This is written in as86 syntax. as86 is part of Bruce Evans' +;;; bcc package.) +;;; +;;; $Id: bootcode.asm,v 1.1 1996/06/10 06:37:12 deraadt Exp $ +;;; +;;; This code must be linked to address 0x7c00 in order to function +;;; correctly (the BIOS boot address). +;;; +;;; It's 16-bit code, and we don't care for a data segment. + use16 + .text + + entry _begin +_begin: jmp init ; jump to boot prog + nop ; historical baggage ;-) +;;; +;;; Reserve space for the "BIOS parameter block". +;;; This will be overwritten by the actual formatting routine. +;;; +bpb: .ascii "BSD 4.4" ; "OEM" name + .word 512 ; sector size + .byte 2 ; cluster size + .word 1 ; reserved sectors (just the boot sector) + .byte 2 ; FAT count + .word 112 ; # of entries in root dir + .word 1440 ; total number of sectors, MSDOS 3.3 or below + .byte 0xf9 ; "media descriptor" + .word 3 ; FAT size (sectors) + .word 9 ; sectors per track + .word 2 ; heads per cylinder + .word 0 ; hidden sectors + ;; MSDOS 4.0++ -- only valid iff total number of sectors == 0 + .word 0 ; unused + .long 0 ; total number of sectors + .short 0 ; physical drive (0, 1, ..., 0x80) %-) + .byte 0 ; "extented boot signature" + .long 0 ; volume serial number (i.e., garbage :) + .ascii " " ; label -- same as vol label in root dir + .ascii "FAT12 " ; file system ID +;;; +;;; Executable code starts here. +;;; +init: + ;; First, display our message. + mov si, *message +lp1: seg cs + movb al, [si] + inc si + testb al, al + jz lp2 ; null-terminated string + movb bl, *7 ; display with regular attribute + movb ah, *0x0e ; int 0x10, fnc 0x0e -- emulate tty + int 0x10 + jmp lp1 +lp2: xorb ah, ah ; int 0x16, fnc 0x00 -- wait for keystroke + int 0x16 + mov ax, *0x40 ; write 0x1234 to address 0x472 -- + push ax ; tell the BIOS that this is a warm boot + pop dx + mov 0x72, *0x1234 + jmpf 0xfff0,0xf000 ; jump to CPU initialization code + +message: + .byte 7 + .byte 0xc9 + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xbb, 13, 10, 0xba + .ascii " Sorry, this disc does actually not contain " + .byte 0xba, 13, 10, 0xba + .ascii " a bootable system. " + .byte 0xba, 13, 10, 0xba + .ascii " Press any key to reboot. " + .byte 0xba, 13, 10, 0xc8 + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xcd,0xcd,0xcd,0xcd,0xcd,0xcd + .byte 0xbc, 13,10 + .byte 0 + + ;; Adjust the value below after changing the length of + ;; the code above! + .space 0x1fe-0x161 ; pad to 512 bytes + + .byte 0x55, 0xaa ; yes, we are bootable (cheating :) + end +
\ No newline at end of file diff --git a/sbin/newfs_msdos/bootcode.h b/sbin/newfs_msdos/bootcode.h new file mode 100644 index 00000000000..7b3f325f456 --- /dev/null +++ b/sbin/newfs_msdos/bootcode.h @@ -0,0 +1,54 @@ +#ifndef BOOTCODE_H +#define BOOTCODE_H 1 + +/* + * This file has been generated + * automatically. Do not edit. + */ + +static unsigned char bootcode[512] = { +0xeb, 0x3c, 0x90, 0x42, 0x53, 0x44, 0x20, 0x20, 0x34, 0x2e, 0x34, 0x00, +0x02, 0x02, 0x01, 0x00, 0x02, 0x70, 0x00, 0xa0, 0x05, 0xf9, 0x03, 0x00, +0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, +0x20, 0x20, 0xbe, 0x65, 0x7c, 0x2e, 0x8a, 0x04, 0x46, 0x84, 0xc0, 0x74, +0x08, 0xb3, 0x07, 0xb4, 0x0e, 0xcd, 0x10, 0xeb, 0xf0, 0x30, 0xe4, 0xcd, +0x16, 0xb8, 0x40, 0x00, 0x50, 0x5a, 0xc7, 0x06, 0x72, 0x00, 0x34, 0x12, +0xea, 0xf0, 0xff, 0x00, 0xf0, 0x07, 0xc9, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xbb, 0x0d, 0x0a, 0xba, 0x20, 0x20, 0x53, +0x6f, 0x72, 0x72, 0x79, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x64, +0x69, 0x73, 0x63, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x61, 0x63, 0x74, +0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, +0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x20, 0xba, 0x0d, 0x0a, 0xba, 0x20, +0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, +0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xba, 0x0d, 0x0a, +0xba, 0x20, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, +0x20, 0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x62, 0x6f, +0x6f, 0x74, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xba, +0x0d, 0x0a, 0xc8, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, +0xcd, 0xbc, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, }; + +#endif /* BOOTCODE_H */ diff --git a/sbin/newfs_msdos/dosfs.h b/sbin/newfs_msdos/dosfs.h new file mode 100644 index 00000000000..f783718651c --- /dev/null +++ b/sbin/newfs_msdos/dosfs.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1995 Joerg Wunsch + * + * All rights reserved. + * + * This program is free software. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * MS-DOS (FAT) file system structure definitions. + * + * $Id: dosfs.h,v 1.1 1996/06/10 06:37:14 deraadt Exp $ + */ + +#ifndef DOSFS_H +#define DOSFS_H 1 + +typedef u_int8_t Long[4]; +typedef u_int8_t Short[2]; + +union bootsector { + u_char raw[512]; + struct bsec { + u_char jump_boot[3]; /* jump code to boot-up partition */ + char oem_name[8]; /* OEM company name & version */ + Short sectsiz;/* bytes per sector */ + u_char clustsiz; /* sectors per cluster */ + Short ressecs;/* reserved sectors [before 1st FAT] */ + u_char fatcnt; /* # of FAT's */ + Short rootsiz;/* number of root dir entries */ + Short totsecs;/* total # of sectors */ + u_char media; /* media descriptor */ + Short fatsize;/* # of sectors per FAT */ + Short trksecs;/* sectors per track (cylinder) */ + Short headcnt;/* # of r/w heads */ + Short hidnsec;/* hidden sectors */ + union { + /* case totsecs != 0: */ + /* This is a partition of MS-DOS 3.3 format (< 32 MB) */ + u_char bootprogram[480]; + + /* case totsecs == 0: */ + /* partition of MS-DOS 4.0+ format, or > 32 MB */ + struct { + Short unused; + Long totsecs; /* total # of sectors, + * as a 32-bit */ + Short physdrv; /* physical drive # + * [0x80...] */ + u_char extboot; /* extended boot + * signature??? */ + Long serial; /* volume serial number */ + char label[11]; /* same as volume label + * in root dir */ + char fsysid[8]; /* some like `FAT16' */ + u_char bootprogram[448]; + } extended; + } variable_part; + u_char signature[2]; /* always {0x55, 0xaa} */ + } bsec; +}; + +struct fat { + u_char media; /* the media descriptor again */ + u_char padded; /* alway 0xff */ + u_char contents[1]; /* the `1' is a placeholder only */ +}; +/* DOS file attributes */ +#define FA_RONLY 1 /* read/only */ +#define FA_HIDDEN 2 /* hidden */ +#define FA_SYSTEM 4 /* system */ +#define FA_VOLLABEL 8 /* this is the volume label */ +#define FA_SUBDIR 0x10 /* sub-directory */ +#define FA_ARCH 0x20 /* archive - file hasn't been backed up */ + +struct dosftime { + u_char time[2]; /* [0] & 0x1f - seconds div 2 ([1] & 7) * 8 + + * ([0] >> 5) - minutes [1] >> 3 - hours */ + u_char date[2]; /* [0] & 0x1f - day ([1] & 1) * 8 + ([0] >> 5) + * - month [1] >> 1 - year - 1980 */ +}; +#define dosft_hour(dft) ((dft).time[1] >> 3) +#define dosft_minute(dft) (((dft).time[1] & 7) * 8 + ((dft).time[0] >> 5)) +#define dosft_second(dft) (((dft).time[0] & 0x1f) * 2) +#define dosft_year(dft) (((dft).date[1] >> 1) + 1980) +#define dosft_month(dft) (((dft).date[1] & 1) * 8 + ((dft).date[0] >> 5)) +#define dosft_day(dft) ((dft).date[0] & 0x1f) + + +struct direntry { + char name[8]; /* file name portion */ + char ext[3]; /* file extension */ + u_char attr; /* file attribute as above */ + char reserved[10]; + struct dosftime fdate; /* time created/last modified */ + Short startclstr; /* starting cluster number */ + Long filesiz; /* file size in bytes */ +}; + +#define s_to_little_s(dst, src) do { \ + u_int16_t tmp = htons(src); \ + dst[0] = (tmp&0xff00)>>8; \ + dst[1] = (tmp&0x00ff); \ + } while (0); +#define l_to_little_l(dst, src) do { \ + u_int32_t tmp = htonl(src); \ + dst[0] = (tmp&0xff000000)>>24; \ + dst[1] = (tmp&0x00ff0000)>>16; \ + dst[2] = (tmp&0x0000ff00)>>8; \ + dst[3] = (tmp&0x000000ff); \ + } while (0); + +#endif /* DOSFS_H */ diff --git a/sbin/newfs_msdos/newfs_msdos.8 b/sbin/newfs_msdos/newfs_msdos.8 new file mode 100644 index 00000000000..30ea85b145d --- /dev/null +++ b/sbin/newfs_msdos/newfs_msdos.8 @@ -0,0 +1,135 @@ +.\" +.\" Copyright (c) 1995, 1996 Joerg Wunsch +.\" +.\" All rights reserved. +.\" +.\" This program is free software. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $Id: newfs_msdos.8,v 1.1 1996/06/10 06:37:15 deraadt Exp $ +.\" +.Dd November 5, 1995 +.Os +.Dt MKDOSFS 1 +.Sh NAME +.Nm mkdosfs +.Nd create an MS-DOS (FAT) file system +.Sh SYNOPSIS +.Nm mkdosfs +.Bq Fl f Ar capacity +.Bq Fl L Ar vollabel +.Ar device +.Sh DESCRIPTION +.Nm Mkdosfs +establishes a file system structure on +.Ar device +that is understood by +.Xr mount_msdos +and some ancient program loader. +.Ar Device +will typically be the character device node for a floppy disk drive, +.Pq e.\ g. Pa /dev/rfd0 , +although any existing writable file or device is acceptable. In case +of a regular file it is treated as a dumped image of an MS-DOS file +system; only the file system structure will be written to it, and it +won't be truncated. +.Pp +The options are as follows: +.Bl -tag -width 10n -offset indent +.It Fl f Ar capacity +Use defaults for a typical file system with +.Ar capacity +kilobytes. Currently, the values 360, 720, 1200, and 1440 are +recognized. +.Pp +If this option is not specified, +.Nm +attempts to determine the size of the +.Ar device . +This is not reliably possible in all cases, but is believed to work +for the more common situations. +.It Fl L Ar vollabel +Use +.Ar vollabel +to describe the file system, instead of the default +.Ql 4.4BSD . +.El +.Pp +The file system structure consists of three major areas: +.Bl -tag -width 10n -offset indent +.It Em The bootsector +This is the very first (512-byte) sector. It contains executable +code that normally would bootstrap an operating system when loaded. +Since it's beyond the scope of +.Nm +to install an operating system on the medium, this boot code will only +print a message that the disk does not contain a bootable system. +Inside the +.Em bootsector +is the +.Em BIOS parameter block (BPB) , +where several statistical parameters of the file system are being +held. +.It Em The file allocation table(s) (FAT) +Sectors next to the +.Em bootsector +hold the FAT, which is used to register file system allocation, +as well as keeping pointer chains for the chunks constituting +one file. There are usually two identical copies of the FAT. +.It Em The root directory +The final structure is the root directory for this medium. It is +merely a space reservation, padded with 0's, and unfortunately fixed +in its size. +.Nm mkdosfs +initializes it to empty, and enters a volume label record into the +very first directory slot. +.Sh DIAGNOSTICS +An exit status of 0 is returned upon successful operation. Exit status +1 is returned on any errors during file system creation, and an exit status +of 2 reflects invalid arguments given to the program (along with an +appropriate information written to diagnostic output). +.Sh SEE ALSO +.Xr fdformat 1 , +.Xr mount_msdos 8 , +.Xr newfs 8 . +.Sh BUGS +There is currently no way to specify obscure file system parameters. +Thus, only media with one of the supported capacity values can be +formatted. For the same reason, it's not possible to handle hard disk +partitions. More options should be added to allow this. More entries +should be added to the table of known formats, too. +.Pp +No attempt is made to handle media defects. However, this is beyond +the scope of +.Nm mkdosfs +and should better be handled by the (nonexistent) +.Xr dosfsck 1 +utility. +.Sh HISTORY +.Nm Mkdosfs +appeared in +.Em FreeBSD 2.2 . +.Sh AUTHOR +The program has been contributed by +.if n Joerg Wunsch, +.if t J\(:org Wunsch, +Dresden. diff --git a/sbin/newfs_msdos/newfs_msdos.c b/sbin/newfs_msdos/newfs_msdos.c new file mode 100644 index 00000000000..af667433705 --- /dev/null +++ b/sbin/newfs_msdos/newfs_msdos.c @@ -0,0 +1,299 @@ +/* $OpenBSD: newfs_msdos.c,v 1.1 1996/06/10 06:37:16 deraadt Exp $ */ + +/* + * Copyright (c) 1995, 1996 Joerg Wunsch + * + * All rights reserved. + * + * This program is free software. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Create an MS-DOS (FAT) file system. + * + * from: FreeBSD Id: mkdosfs.c,v 1.2 1996/01/30 02:35:08 joerg Exp + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <memory.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> + +#include "bootcode.h" +#include "dosfs.h" + +struct descrip { + /* our database key */ + u_int32_t kilobytes; + + /* MSDOS 3.3 BPB fields */ + u_int16_t sectsiz; + u_int8_t clustsiz; + u_int16_t ressecs; + u_int8_t fatcnt; + u_int16_t rootsiz; + u_int16_t totsecs; + u_int8_t media; + u_int16_t fatsize; + u_int16_t trksecs; + u_int16_t headcnt; + u_int16_t hidnsec; + + /* MSDOS 4 BPB extensions */ + u_int32_t ext_totsecs; + u_int16_t ext_physdrv; + u_int8_t ext_extboot; + int8_t ext_label[11]; + int8_t ext_fsysid[8]; +}; + +static struct descrip table[] = { + /* NB: must be sorted, starting with the largest format! */ + /* + * kilobytes + * sec cls res fat rot tot med fsz spt hds hid + * tot phs ebt label fsysid + */ + {1440, 512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2, 0, + 0, 0, 0, "4.4BSD ", "FAT12 "}, + {1200, 512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2, 0, + 0, 0, 0, "4.4BSD ", "FAT12 "}, + {720, 512, 2, 1, 2, 112, 1440, 0xf9, 3, 9, 2, 0, + 0, 0, 0, "4.4BSD ", "FAT12 "}, + {360, 512, 2, 1, 2, 112, 720, 0xfd, 2, 9, 2, 0, + 0, 0, 0, "4.4BSD ", "FAT12 "}, +}; + +void +usage(void) +{ + fprintf(stderr, "usage: "); + errx(2, "[-s kbytes] [-L label] device"); +} + +unsigned +findformat(fd) + int fd; +{ + struct stat sb; + + /* + * This is a bit tricky. If the argument is a regular file, we can + * lseek() to its end and get the size reported. If it's a device + * however, lseeking doesn't report us any useful number. Instead, + * we try to seek just to the end of the device and try reading a + * block there. In the case where we've hit exactly the device + * boundary, we get a zero read, and thus have found the size. + * Since our knowledge of distinct formats is limited anyway, this + * is not a big deal at all. + */ + + if (fstat(fd, &sb) == -1) + err(1, "Huh? Cannot fstat()"); /* Cannot happen */ + if (S_ISREG(sb.st_mode)) { + off_t o; + if (lseek(fd, (off_t) 0, SEEK_END) == -1 || + (o = lseek(fd, (off_t) 0, SEEK_CUR)) == -1) + /* Hmm, hmm. Hard luck. */ + return 0; + return (int) (o / 1024); + } else if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { + char b[512]; + int i, rv; + struct descrip *dp; + + for (i = 0, dp = table; + i < sizeof table / sizeof(struct descrip); + i++, dp++) { + if (lseek(fd, (off_t) (dp->kilobytes * 1024), + SEEK_SET) == 1) + /* Uh-oh, lseek() is not supposed to + * fail. */ + return 0; + if ((rv = read(fd, b, 512)) == 0) + break; + /* XXX The ENOSPC is for the bogus fd(4) + * driver return value. */ + if (rv == -1 && errno != EINVAL && errno != ENOSPC) + return 0; + /* else: continue */ + } + if (i == sizeof table / sizeof(struct descrip)) + return 0; + (void) lseek(fd, (off_t) 0, SEEK_SET); + return dp->kilobytes; + } + return 0; +} + + +void +setup_boot_sector_from_template(bs, dp) + union bootsector *bs; + struct descrip *dp; +{ + memcpy((void *)bs->raw, (void *)bootcode, 512); + + /* historical part of BPB */ + s_to_little_s(bs->bsec.sectsiz, dp->sectsiz); + bs->bsec.clustsiz = dp->clustsiz; + s_to_little_s(bs->bsec.ressecs, dp->ressecs); + bs->bsec.fatcnt = dp->fatcnt; + s_to_little_s(bs->bsec.rootsiz, dp->rootsiz); + s_to_little_s(bs->bsec.totsecs, dp->totsecs); + bs->bsec.media = dp->media; + s_to_little_s(bs->bsec.fatsize, dp->fatsize); + s_to_little_s(bs->bsec.trksecs, dp->trksecs); + s_to_little_s(bs->bsec.headcnt, dp->headcnt); + s_to_little_s(bs->bsec.hidnsec, dp->hidnsec); + + /* MSDOS 4 extensions */ + l_to_little_l(bs->bsec.variable_part.extended.totsecs, dp->ext_totsecs); + s_to_little_s(bs->bsec.variable_part.extended.physdrv, dp->ext_physdrv); + bs->bsec.variable_part.extended.extboot = dp->ext_extboot; + + /* assign a "serial number" :) */ + srandom((unsigned) time((time_t) 0)); + l_to_little_l(bs->bsec.variable_part.extended.serial, random()); + + memcpy((void *) bs->bsec.variable_part.extended.label, + (void *) dp->ext_label, 11); + memcpy((void *) bs->bsec.variable_part.extended.fsysid, + (void *) dp->ext_fsysid, 8); +} +#define roundup(dst, limit) dst = (((dst) | ((limit) - 1)) & ~(limit)) + 1 + +int +main(argc, argv) + int argc; + char *argv[]; +{ + union bootsector bs; + struct descrip *dp; + struct fat *fat; + struct direntry *rootdir; + const char *label = 0; + struct tm *tp; + time_t now; + int c, i, fd, format = 0, rootdirsize; + + while ((c = getopt(argc, argv, "s:L:")) != EOF) + switch (c) { + case 's': + format = atoi(optarg); + break; + case 'L': + label = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + if ((fd = open(argv[0], O_RDWR | O_EXCL, 0)) == -1) + err(1, "open(%s)", argv[0]); + + if (format == 0) { + /* + * No format specified, try to figure it out. + */ + if ((format = findformat(fd)) == 0) + errx(1, "cannot determine size, must use -s format"); + } + for (i = 0, dp = table; i < sizeof table / sizeof(struct descrip); i++, dp++) + if (dp->kilobytes == format) + break; + if (i == sizeof table / sizeof(struct descrip)) + errx(1, "cannot find format description for %d KB", format); + + /* prepare and write the boot sector */ + setup_boot_sector_from_template(&bs, dp); + + /* if we've got an explicit label, use it */ + if (label) + strncpy(bs.bsec.variable_part.extended.label, label, 11); + + if (write(fd, (char *) bs.raw, sizeof bs) != sizeof bs) + err(1, "boot sector write()"); + + /* now, go on with the FATs */ + if ((fat = (struct fat *) malloc(dp->sectsiz * dp->fatsize)) == 0) + abort(); + memset((void *) fat, 0, dp->sectsiz * dp->fatsize); + + fat->media = dp->media; + fat->padded = 0xff; + fat->contents[0] = 0xff; + if (dp->totsecs > 20740 || (dp->totsecs == 0 && dp->ext_totsecs > 20740)) + /* 16-bit FAT */ + fat->contents[1] = 0xff; + + for (i = 0; i < dp->fatcnt; i++) + if (write(fd, (char *) fat, dp->sectsiz * dp->fatsize) + != dp->sectsiz * dp->fatsize) + err(1, "FAT write()"); + + free((void *) fat); + + /* finally, build the root dir */ + rootdirsize = dp->rootsiz * sizeof(struct direntry); + roundup(rootdirsize, dp->clustsiz * dp->sectsiz); + + if ((rootdir = (struct direntry *) malloc(rootdirsize)) == 0) + abort(); + memset((void *) fat, 0, rootdirsize); + + /* set up a volume label inside the root dir :) */ + if (label) + strncpy(rootdir[0].name, label, 11); + else + memcpy(rootdir[0].name, dp->ext_label, 11); + rootdir[0].attr = FA_VOLLABEL; + now = time((time_t) 0); + tp = localtime(&now); + rootdir[0].fdate.time[0] = tp->tm_sec / 2; + rootdir[0].fdate.time[0] |= (tp->tm_min & 7) << 5; + rootdir[0].fdate.time[1] = ((tp->tm_min >> 3) & 7); + rootdir[0].fdate.time[1] |= tp->tm_hour << 3; + rootdir[0].fdate.date[0] = tp->tm_mday; + rootdir[0].fdate.date[0] |= ((tp->tm_mon + 1) & 7) << 5; + rootdir[0].fdate.date[1] = ((tp->tm_mon + 1) >> 3) & 1; + rootdir[0].fdate.date[1] |= (tp->tm_year - 80) << 1; + + if (write(fd, (char *) rootdir, rootdirsize) != rootdirsize) + err(1, "root dir write()"); + + (void) close(fd); + return 0; +} |