1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
diff -urN dosfstools-2.10.orig/mkdosfs/ChangeLog dosfstools-2.10/mkdosfs/ChangeLog
--- dosfstools-2.10.orig/mkdosfs/ChangeLog 1997-06-18 03:09:38.000000000 -0700
+++ dosfstools-2.10/mkdosfs/ChangeLog 2004-08-02 20:57:57.734939816 -0700
@@ -1,3 +1,14 @@
+19th June 2003 Sam Bingner (sam@bingner.com)
+
+ Added option to read in bootcode from a file so that if you have
+ for example Windows 2000 boot code, you can have it write that
+ as the bootcode. This is a dump of the behinning of a partition
+ generally 512 bytes, but can be up to reserved sectors*512 bytes.
+ Also writes 0x80 as the BIOS drive number if we are formatting a
+ hard drive, and sets the number of hidden sectors to be the
+ number of sectors in one track. These were required so that DOS
+ could boot using the bootcode.
+
28th January 1995 H. Peter Anvin (hpa@yggdrasil.com)
Better algorithm to select cluster sizes on large filesystems.
diff -urN dosfstools-2.10.orig/mkdosfs/mkdosfs.8 dosfstools-2.10/mkdosfs/mkdosfs.8
--- dosfstools-2.10.orig/mkdosfs/mkdosfs.8 2003-05-15 11:28:28.000000000 -0700
+++ dosfstools-2.10/mkdosfs/mkdosfs.8 2004-08-02 20:57:57.735939664 -0700
@@ -40,6 +40,10 @@
.I message-file
]
[
+.B \-B
+.I bootcode-file
+]
+[
.B \-n
.I volume-name
]
@@ -155,6 +159,18 @@
carriage return-line feed combinations, and tabs have been expanded.
If the filename is a hyphen (-), the text is taken from standard input.
.TP
+.BI \-B " bootcode-file"
+Uses boot machine code from file "file". On any thing other than FAT32,
+this only writes the first 3 bytes, and 480 bytes from offset 3Eh. On
+FAT32, this writes the first 3 bytes, 420 bytes from offset 5Ah to both
+primary and backup boot sectors. Also writes all other reserved sectors
+excluding the sectors following boot sectors (usually sector 2 and 7).
+Does not require that the input file be as large as reserved_sectors*512.
+To make a FAT32 partition bootable, you will need at least the first
+13 sectors (6656 bytes). You can also specify a partition as the argument
+to clone the boot code from that partition.
+i.e mkdosfs -B /dev/sda1 /dev/sda1
+.TP
.BI \-n " volume-name"
Sets the volume name (label) of the filesystem. The volume name can
be up to 11 characters long. The default is no label.
@@ -188,8 +204,9 @@
simply will not support it ;)
.SH AUTHOR
Dave Hudson - <dave@humbug.demon.co.uk>; modified by Peter Anvin
-<hpa@yggdrasil.com>. Fixes and additions by Roman Hodek
-<Roman.Hodek@informatik.uni-erlangen.de> for Debian/GNU Linux.
+<hpa@yggdrasil.com> and Sam Bingner <sam@bingner.com>. Fixes and
+additions by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
+for Debian/GNU Linux.
.SH ACKNOWLEDGEMENTS
.B mkdosfs
is based on code from
diff -urN dosfstools-2.10.orig/mkdosfs/mkdosfs.c dosfstools-2.10/mkdosfs/mkdosfs.c
--- dosfstools-2.10.orig/mkdosfs/mkdosfs.c 2003-06-14 13:07:08.000000000 -0700
+++ dosfstools-2.10/mkdosfs/mkdosfs.c 2004-08-02 20:57:57.736939512 -0700
@@ -24,6 +24,12 @@
- New options -A, -S, -C
- Support for filesystems > 2GB
- FAT32 support
+
+ Fixes/additions June 2003 by Sam Bingner
+ <sam@bingner.com>:
+ - Add -B option to read in bootcode from a file
+ - Write BIOS drive number so that FS can properly boot
+ - Set number of hidden sectors before boot code to be one track
Copying: Copyright 1993, 1994 David Hudson (dave@humbug.demon.co.uk)
@@ -167,6 +173,8 @@
#define FAT_BAD 0x0ffffff7
#define MSDOS_EXT_SIGN 0x29 /* extended boot sector signature */
+#define HD_DRIVE_NUMBER 0x80 /* Boot off first hard drive */
+#define FD_DRIVE_NUMBER 0x00 /* Boot off first floppy drive */
#define MSDOS_FAT12_SIGN "FAT12 " /* FAT12 filesystem signature */
#define MSDOS_FAT16_SIGN "FAT16 " /* FAT16 filesystem signature */
#define MSDOS_FAT32_SIGN "FAT32 " /* FAT32 filesystem signature */
@@ -188,6 +196,8 @@
#define BOOTCODE_SIZE 448
#define BOOTCODE_FAT32_SIZE 420
+#define MAX_RESERVED 0xFFFF
+
/* __attribute__ ((packed)) is used on all structures to make gcc ignore any
* alignments */
@@ -215,7 +225,7 @@
__u16 fat_length; /* sectors/FAT */
__u16 secs_track; /* sectors per track */
__u16 heads; /* number of heads */
- __u32 hidden; /* hidden sectors (unused) */
+ __u32 hidden; /* hidden sectors (one track) */
__u32 total_sect; /* number of sectors (if sectors == 0) */
union {
struct {
@@ -298,6 +308,8 @@
/* Global variables - the root of all evil :-) - see these and weep! */
+static char *template_boot_code; /* Variable to store a full template boot sector in */
+static int use_template = 0;
static char *program_name = "mkdosfs"; /* Name of the program */
static char *device_name = NULL; /* Name of the device on which to create the filesystem */
static int atari_format = 0; /* Use Atari variation of MS-DOS FS format */
@@ -842,6 +854,12 @@
vi->volume_id[2] = (unsigned char) ((volume_id & 0x00ff0000) >> 16);
vi->volume_id[3] = (unsigned char) (volume_id >> 24);
}
+ if (bs.media == 0xf8) {
+ vi->drive_number = HD_DRIVE_NUMBER; /* Set bios drive number to 80h */
+ }
+ else {
+ vi->drive_number = FD_DRIVE_NUMBER; /* Set bios drive number to 00h */
+ }
if (!atari_format) {
memcpy(vi->volume_label, volume_name, 11);
@@ -886,7 +904,7 @@
printf( "Using %d reserved sectors\n", reserved_sectors );
bs.fats = (char) nr_fats;
if (!atari_format || size_fat == 32)
- bs.hidden = CT_LE_L(0);
+ bs.hidden = bs.secs_track;
else
/* In Atari format, hidden is a 16 bit field */
memset( &bs.hidden, 0, 2 );
@@ -1358,6 +1376,32 @@
* dir area on FAT12/16, and the first cluster on FAT32. */
writebuf( (char *) root_dir, size_root_dir, "root directory" );
+ if (use_template == 1) {
+ /* dupe template into reserved sectors */
+ seekto( 0, "Start of partition" );
+ if (size_fat == 32) {
+ writebuf( template_boot_code, 3, "backup jmpBoot" );
+ seekto( 0x5a, "sector 1 boot area" );
+ writebuf( template_boot_code+0x5a, 420, "sector 1 boot area" );
+ seekto( 512*2, "third sector" );
+ if (backup_boot != 0) {
+ writebuf( template_boot_code+512*2, backup_boot*sector_size - 512*2, "data to backup boot" );
+ seekto( backup_boot*sector_size, "backup boot sector" );
+ writebuf( template_boot_code, 3, "backup jmpBoot" );
+ seekto( backup_boot*sector_size+0x5a, "backup boot sector boot area" );
+ writebuf( template_boot_code+0x5a, 420, "backup boot sector boot area" );
+ seekto( (backup_boot+2)*sector_size, "sector following backup code" );
+ writebuf( template_boot_code+(backup_boot+2)*sector_size, (reserved_sectors-backup_boot-2)*512, "remaining data" );
+ } else {
+ writebuf( template_boot_code+512*2, (reserved_sectors-2)*512, "remaining data" );
+ }
+ } else {
+ writebuf( template_boot_code, 3, "jmpBoot" );
+ seekto( 0x3e, "sector 1 boot area" );
+ writebuf( template_boot_code+0x3e, 448, "boot code" );
+ }
+ }
+
if (info_sector) free( info_sector );
free (root_dir); /* Free up the root directory space from setup_tables */
free (fat); /* Free up the fat table space reserved during setup_tables */
@@ -1371,7 +1415,7 @@
{
fatal_error("\
Usage: mkdosfs [-A] [-c] [-C] [-v] [-I] [-l bad-block-file] [-b backup-boot-sector]\n\
- [-m boot-msg-file] [-n volume-name] [-i volume-id]\n\
+ [-m boot-msg-file] [-n volume-name] [-i volume-id] [-B bootcode]\n\
[-s sectors-per-cluster] [-S logical-sector-size] [-f number-of-FATs]\n\
[-F fat-size] [-r root-dir-entries] [-R reserved-sectors]\n\
/dev/name [blocks]\n");
@@ -1433,7 +1477,7 @@
printf ("%s " VERSION " (" VERSION_DATE ")\n",
program_name);
- while ((c = getopt (argc, argv, "AcCf:F:Ii:l:m:n:r:R:s:S:v")) != EOF)
+ while ((c = getopt (argc, argv, "AcCf:F:Ii:l:m:n:r:R:s:S:v:B:b")) != EOF)
/* Scan the command line for options */
switch (c)
{
@@ -1494,6 +1538,51 @@
listfile = optarg;
break;
+ case 'B': /* B : read in bootcode */
+ if ( strcmp(optarg, "-") )
+ {
+ msgfile = fopen(optarg, "r");
+ if ( !msgfile )
+ perror(optarg);
+ }
+ else
+ msgfile = stdin;
+
+ if ( msgfile )
+ {
+ if (!(template_boot_code = malloc( MAX_RESERVED )))
+ die( "Out of memory" );
+ /* The template boot sector including reserved must not be > 65535 */
+ use_template = 1;
+ i = 0;
+ do
+ {
+ ch = getc(msgfile);
+ switch (ch)
+ {
+ case EOF:
+ break;
+
+ default:
+ template_boot_code[i++] = ch; /* Store character */
+ break;
+ }
+ }
+ while ( ch != EOF && i < MAX_RESERVED );
+ ch = getc(msgfile); /* find out if we're at EOF */
+
+ /* Fill up with zeros */
+ while( i < MAX_RESERVED )
+ template_boot_code[i++] = '\0';
+
+ if ( ch != EOF )
+ printf ("Warning: template too long; truncated after %d bytes\n", i);
+
+ if ( msgfile != stdin )
+ fclose(msgfile);
+ }
+ break;
+
case 'm': /* m : Set boot message */
if ( strcmp(optarg, "-") )
{
|