summaryrefslogtreecommitdiff
path: root/bootblocks/makeboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootblocks/makeboot.c')
-rw-r--r--bootblocks/makeboot.c212
1 files changed, 173 insertions, 39 deletions
diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c
index 4eda4c6..c749d20 100644
--- a/bootblocks/makeboot.c
+++ b/bootblocks/makeboot.c
@@ -2,10 +2,12 @@
#include <stdio.h>
#include <ctype.h>
#include <time.h>
+#include <string.h>
#include "sysboot.v"
#include "noboot.v"
#include "msdos.v"
+#include "msdos16.v"
#include "skip.v"
#include "tarboot.v"
#include "minix.v"
@@ -31,18 +33,39 @@ struct bblist {
char * desc;
char * data;
int size;
+ int name_type;
+ int boot_name;
int fstype;
+ int fsmod;
} bblocks[] = {
-{ "tar", "Bootable GNU tar volume lable", tarboot_data, tarboot_size, FS_TAR},
-{ "dosfs","Boot file BOOTFILE.SYS from dosfs", msdos_data, msdos_size, FS_ADOS},
-{ "none", "No OS bootblock, just message", noboot_data, noboot_size, FS_DOS},
-{ "skip", "Bypasses floppy boot with message", skip_data, skip_size, FS_DOS},
-{ "minix","Minix floppy FS booter", minix_data, minix_size, FS_ZERO},
-{ "hdmin","Minix Hard disk FS booter", minixhd_data, minixhd_size, FS_ZERO},
-{ "mbr", "Master boot record for HD", mbr_data,mbr_size, FS_MBR},
-{ "stat", "Display dosfs superblock", 0, 0, FS_STAT},
-{ "copy", "Copy boot block to makeboot.sav", 0, 0, FS_STAT},
-{ "Zap", "Clear boot block to NULs", 0, 1024, FS_NONE},
+{ "tar", "Bootable GNU tar volume lable",
+ tarboot_data, tarboot_size, 0, 0, FS_TAR},
+{ "dosfs","Boot file BOOTFILE.SYS from dos floppy",
+ msdos_data, msdos_size,
+ 1, msdos_boot_name-msdos_start, FS_DOS, 12},
+{ "dos16","Boot file BOOTFILE.SYS from 16 bit dos floppy",
+ msdos16_data, msdos16_size,
+ 1, msdos16_boot_name-msdos16_start, FS_DOS, 16},
+{ "none", "No OS bootblock, just message",
+ noboot_data, noboot_size,
+ 2, noboot_boot_message-noboot_start, FS_DOS},
+{ "skip", "Bypasses floppy boot with message",
+ skip_data, skip_size,
+ 2, skip_mesg-skip_start, FS_DOS},
+{ "minix","Minix floppy FS booter",
+ minix_data, minix_size,
+ 2, minix_bootfile-minix_start, FS_ZERO},
+{ "hdmin","Minix Hard disk FS booter",
+ minixhd_data, minixhd_size,
+ 2, minixhd_bootfile-minixhd_start, FS_ZERO},
+{ "mbr", "Master boot record for HD",
+ mbr_data,mbr_size, 0, 0, FS_MBR},
+{ "stat", "Display dosfs superblock",
+ 0, 0, 0, 0, FS_STAT},
+{ "copy", "Copy boot block to makeboot.sav",
+ 0, 0, 0, 0, FS_STAT},
+{ "Zap", "Clear boot block to NULs",
+ 0, 1024, 0, 0, FS_NONE},
0
};
@@ -60,6 +83,8 @@ int write_zero = 1; /* Write sector 0 */
int write_one = 0; /* Write sector 1 */
int bs_offset = 0; /* Offset of _real_ bootsector for 2m floppies */
+char * boot_id = 0;
+
main(argc, argv)
int argc;
char ** argv;
@@ -76,6 +101,10 @@ char ** argv;
}
if( argc != 3 ) Usage();
+ boot_id = strchr(argv[1], '=');
+ if( boot_id )
+ *boot_id++ = '\0';
+
if( (i=strlen(argv[1])) < 2 ) Usage();
for(ptr = bblocks; ptr->name; ptr++)
if( strncmp(argv[1], ptr->name, i) == 0 ) break;
@@ -93,12 +122,10 @@ char ** argv;
{
case FS_NONE: /* override */
break;
- case FS_ADOS:
- check_simpledos();
- break;
case FS_DOS:
case FS_STAT:
check_msdos();
+ if(ptr->fsmod) check_simpledos(ptr->fsmod);
break;
case FS_TAR:
check_tar();
@@ -123,7 +150,6 @@ char ** argv;
save_super(buffer);
close_disk();
exit(0);
- case FS_ADOS:
case FS_DOS:
for(i=0; i<sysboot_dosfs_stat; i++)
buffer[i] = ptr->data[i];
@@ -139,9 +165,10 @@ char ** argv;
copy_mbr(ptr->data);
break;
+ case FS_ZERO:
case FS_NONE:
if( ptr->data )
- memcpy(buffer, ptr->data, 512);
+ memcpy(buffer, ptr->data, ptr->size);
else
{
memset(buffer, '\0', 1024);
@@ -150,6 +177,19 @@ char ** argv;
break;
}
+ if( boot_id ) switch(ptr->name_type)
+ {
+ case 1:
+ set_dosname(ptr->boot_name);
+ break;
+ case 2:
+ set_asciz(ptr->boot_name);
+ break;
+ default:
+ fprintf(stderr, "Cannot specify boot file for this block\n");
+ exit(1);
+ }
+
if( bs_offset )
{
if( write_zero ) do_2m_write();
@@ -172,11 +212,12 @@ Usage()
progname = "makeboot";
#ifdef __MSDOS__
- fprintf(stderr, "Usage: %s [-f] bootname a:\n", progname);
+ fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n", progname);
#else
- fprintf(stderr, "Usage: %s [-f] bootname /dev/fd0\n", progname);
+ fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n", progname);
#endif
- fprintf(stderr, "Blocks\n");
+ fprintf(stderr, "\nThe bootname is a filename to use with the block,\n");
+ fprintf(stderr, "the blocks are:\n");
for(;ptr->name; ptr++)
fprintf(stderr, "\t%s\t%s\n", ptr->name, ptr->desc);
exit(1);
@@ -189,6 +230,9 @@ open_disk(diskname)
char * diskname;
{
#ifdef __MSDOS__
+ /* Freedos fix */
+ if( diskname[2] == '\r' ) diskname[2] = 0;
+
if( strcmp("a:", diskname) == 0 ) { disktype = 1; return 0; }
if( strcmp("b:", diskname) == 0 ) { disktype = 2; return 0; }
if( strcmp("A:", diskname) == 0 ) { disktype = 1; return 0; }
@@ -199,7 +243,7 @@ char * diskname;
if( diskfd == 0 ) diskfd = fopen(diskname, "r");
if( diskfd == 0 )
{
- fprintf(stderr, "Cannot open %s\n", diskname);
+ fprintf(stderr, "Cannot open '%s'\n", diskname);
exit(1);
}
return 0;
@@ -516,7 +560,8 @@ copy_tarblock()
struct bootfields {
int offset;
int length;
- int value;
+ unsigned value;
+ long lvalue;
}
dosflds[] =
{
@@ -606,6 +651,7 @@ char * bootsect;
v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] ));
}
dosflds[i].value = v;
+ dosflds[i].lvalue = v;
}
else
dosflds[i].value = 0;
@@ -616,7 +662,11 @@ save_super(bootsect)
char * bootsect;
{
FILE * fd;
- fd = fopen("makeboot.sav", "wb");
+ char * fname = "makeboot.sav";
+ if( boot_id ) fname = boot_id;
+
+ printf("Copying boot block to '%s'\n", fname);
+ fd = fopen(fname, "wb");
fwrite(bootsect, 1024, 1, fd);
fclose(fd);
}
@@ -675,11 +725,12 @@ check_msdos()
if(!force) exit(2);
}
-check_simpledos()
+check_simpledos(bb_fatbits)
+int bb_fatbits;
{
- int numclust = 0xFFFF;
+ unsigned numclust = 0xFFFF;
char * err = 0;
- check_msdos();
+ int fatbits = 0;
/* Work out how many real clusters there are */
if( dosflds[DOS_MAXSECT].value + 2 > 2 )
@@ -687,29 +738,112 @@ check_simpledos()
- dosflds[DOS_RESV].value
- dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
- ((dosflds[DOS_NROOT].value+15)/16)
- ) / dosflds[DOS_MAXSECT].value + 2;
+ ) / dosflds[DOS_CLUST].value + 2;
+ else
+ numclust = ( dosflds[DOS4_MAXSECT].lvalue
+ - dosflds[DOS_RESV].value
+ - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value
+ - ((dosflds[DOS_NROOT].value+15)/16)
+ ) / dosflds[DOS_CLUST].value + 2;
+
+ if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT12", 5) == 0 )
+ fatbits=12;
+ else if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT16", 5) == 0 )
+ fatbits=16;
+ else
+ fatbits=12+4*(numclust > 0xFF0);
if( dosflds[DOS_NFAT].value > 2 )
err = "Too many fat copies on disk";
- else if( dosflds[DOS_HIDDEN].value != 0 )
- err = "Dubious MSDOS floppy, it's got hidden sectors.";
else if( dosflds[DOS_NROOT].value < 15 )
err = "Root directory has unreasonable size.";
else if( dosflds[DOS_SECT].value != 512 )
err = "Drive sector size isn't 512 bytes sorry no-go.";
- else if( dosflds[DOS_HEADS].value != 2 )
- err = "Drive doesn't have two heads, this is required.";
- else if( numclust > 0xFF0 )
- err = "Filesystem has a 16 bit fat, only 12bits allowed.";
- else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value >
- dosflds[DOS_SPT].value )
- err = "The bootblock needs all of fat1 on the first track.";
- else
- return;
+ else if( fatbits != bb_fatbits )
+ err = "Filesystem has the wrong fat type for this bootblock.";
+ else if( numclust * dosflds[DOS_CLUST].lvalue /
+ dosflds[DOS_SPT].value > 65535 )
+ err = "Maximum of 65535 tracks allowed, sorry";
- fprintf(stderr, "ERROR: %s\n\n", err);
- print_super(buffer);
- if(!force) exit(2);
+ if( !err && bb_fatbits == 12 )
+ {
+ if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value )
+ err = "The FAT is too large to load in the available space.";
+ else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value >
+ dosflds[DOS_SPT].value )
+ err = "The bootblock needs all of fat1 on the first track.";
+ else if( msdos_heads == 2 && dosflds[DOS_HEADS].value != 2 )
+ err = "Drive doesn't have two heads, this is required.";
+ else if( dosflds[DOS_HIDDEN].lvalue != 0 )
+ err = "MSDOS floppies shouldn't have hidden sectors.";
+ }
+
+ if( err )
+ {
+ fprintf(stderr, "ERROR: %s\n\n", err);
+ print_super(buffer);
+ if(!force) exit(2);
+ }
+}
+
+set_dosname(boot_name)
+int boot_name;
+{
+ char dos_name[20];
+ int i,j;
+
+ strcpy(dos_name, " ");
+
+ for(i=0; boot_id[i] && boot_id[i] != '.' && i<16; i++)
+ dos_name[i] = toupper(boot_id[i]);
+
+ if( boot_id[i] == '.' )
+ {
+ for(j=8,i++; boot_id[i] && boot_id[i] != '.' && j<16; i++,j++)
+ dos_name[j] = toupper(boot_id[i]);
+ }
+
+ printf("Bootfile set to '%11.11s'\n", dos_name);
+
+ memcpy(buffer+boot_name, dos_name, 11);
+}
+
+set_asciz(boot_name)
+int boot_name;
+{
+ int i, j;
+
+ for(i=boot_name; buffer[i]; i++) ;
+ for( ; !buffer[i]; i++) ;
+ i = i - boot_name -1;
+
+ if( strlen(boot_id) > i )
+ {
+ fprintf(stderr, "Filename '%s' is too long for bootblock\n");
+ exit(1);
+ }
+ else
+ {
+ for(i=0,j=boot_name; boot_id[i]; i++)
+ {
+ if( boot_id[i] == '\\' && boot_id[i+1] )
+ {
+ i++;
+ switch(boot_id[i])
+ {
+ case 'n': buffer[j++] = '\n'; break;
+ case 'r': buffer[j++] = '\r'; break;
+ case 'b': buffer[j++] = '\b'; break;
+ case 't': buffer[j++] = '\t'; break;
+ case 'a': buffer[j++] = '\007'; break;
+ case 'e': buffer[j++] = '\033'; break;
+ default: buffer[j++] = boot_id[i]; break;
+ }
+ }
+ else buffer[j++] = boot_id[i];
+ }
+ buffer[j] = 0;
+ }
}
check_mbr()