set backup boot sector on FAT32, add update option, fix oemboot to work with msdos 7+

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1125 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Kenneth J Davis 2005-05-28 12:10:29 +00:00
parent ed11301d84
commit 726b3f5af1
4 changed files with 181 additions and 62 deletions

View File

@ -5,17 +5,20 @@
; Copyright (c) 200?, <add name here> ; Copyright (c) 200?, <add name here>
; Description: ; Description:
; OEM boot sector for FreeDOS compatible with IBM's (R) PC-DOS, ; OEM boot sector for FreeDOS compatible with IBM's (R) PC-DOS,
; and Microsoft's (R) PC-DOS. It may work with OpenDOS/DR-DOS, ; and Microsoft's (R) MS-DOS. It may work with older OpenDOS/DR-DOS,
; although the standard FreeDOS boot sector works with later ; although the standard FreeDOS boot sector is needed with ver 7+
; releases. May work with other versions of DOS that use ; releases. May work with other versions of DOS that use
; IBMBIO.COM/IBMDOS.COM pair. This boot sector loads only up ; IBMBIO.COM/IBMDOS.COM pair. This boot sector loads only up
; to 58 sectors (29KB) of the kernel (IBMBIO.COM) to 0x70:0 then ; to 58 sectors (29KB) of the kernel (IBMBIO.COM) to 0x70:0 then
; jumps to it. As best I can tell, PC-DOS (and assuming MS-DOS ; jumps to it. As best I can tell, PC-DOS (and MS-DOS up to version
; behaves similar) expects on entry for: ; 6.xx behaves similar) expects on entry for:
; ch = media id byte in the boot sector ; ch = media id byte in the boot sector
; dl = BIOS drive booted from (0x00=A:, 0x80=C:, ...) ; dl = BIOS drive booted from (0x00=A:, 0x80=C:, ...)
; ax:bx = the LBA sector of 1st data sector 0x0000:0021 for FAT12 ; ax:bx = the starting (LBA) sector of cluster 2 (ie the 1st
; ?or? 1st sector of IBMBIO.COM (which is normally 1st data sector) ; data sector, which is 0x0000:0021 for FAT12)
; ?note? IBMBIO.COM/IO.SYS may use ax:bx and cluster # stored
; elsewhere (perhaps dir entry still at 0x50:0) to determine
; starting sector for full loading of kernel file.
; it also expects the boot sector (in particular the BPB) ; it also expects the boot sector (in particular the BPB)
; to still be at 0x0:7C00, the directory entry for IBMBIO.COM ; to still be at 0x0:7C00, the directory entry for IBMBIO.COM
; (generally first entry of first sector of the root directory) ; (generally first entry of first sector of the root directory)
@ -24,6 +27,26 @@
; may fail for any systems where the changes (???) are needed. ; may fail for any systems where the changes (???) are needed.
; If the above conditions are not met, then IBMBIO.COM will ; If the above conditions are not met, then IBMBIO.COM will
; print the not a bootable disk error message. ; print the not a bootable disk error message.
;
; For MS-DOS >= 7 (ie Win9x DOS) the following conditions
; must be met:
; bp = 0x7C00, ie offset boot sector loaded at
; [bp-4] = the starting (LBA) sector of cluster 2 (ie the 1st
; data sector [this is the same as ax:bx for earlier versions
; and dx:ax in Win9x boot sector]
; The starting cluster of the kernel file is stored in
; di for FAT 12/16 (where si is a don't care) and si:di
; for FAT 32.
; The values for ax,bx,cx,dx,ds and the stack do not
; seem to be important (used by IO.SYS) and so may be any value
; (though dx:ax=[data_start], cx=0, bx=0x0f00 on FAT12 or
; 0x0700 on FAT32, ds=0, ss:sp=0:7b??)
; the boot time stack may store the original int1E floppy
; parameter table, otherwise nothing else important seems
; stored there and I am unsure if even this value is used
; beyond boot sector code.
; ;
; This boot sector only supports FAT12/FAT16 as PC-DOS ; This boot sector only supports FAT12/FAT16 as PC-DOS
; does not support FAT32 and newer FAT32 capable DOSes ; does not support FAT32 and newer FAT32 capable DOSes
@ -78,29 +101,39 @@
; |BOOT SEC| contains BPB ; |BOOT SEC| contains BPB
; |ORIGIN | ; |ORIGIN |
; |--------| 0000:7C00 (0:BP) ; |--------| 0000:7C00 (0:BP)
; |VARS | only known is 1st data sector (start of cluster 2)
; |--------| 0000:7BFC (DS:[BP-4])
; |STACK | minimal 256 bytes (1/2 sector) ; |STACK | minimal 256 bytes (1/2 sector)
; |- - - - | ; |- - - - |
; |KERNEL | kernel loaded here (max 58 sectors, 29KB) ; |KERNEL | kernel loaded here (max 58 sectors, 29KB)
; |LOADED | also used as FAT buffer ; |LOADED | also used as FAT buffer
; |--------| 0070:0000 (0:0700) ; |--------| 0070:0000 (0:0700)
; |DOS DA/ | DOS Data Area, ; |DOS DA/ | DOS Data Area,
; |ROOT DIR| during boot the 1st sector of root directory ; |ROOT DIR| during boot contains directory entries
; |--------| 0000:0500 ; |--------| 0000:0500
; |BDA | BIOS Data Area ; |BDA | BIOS Data Area
; +--------+ 0000:0400 ; +--------+ 0000:0400
; |IVT | Interrupt Vector Table ; |IVT | Interrupt Vector Table
; +--------+ 0000:0000 ; +--------+ 0000:0000
CPU 8086 ; enable assembler warnings to limit instruction set
;%define ISFAT12 1 ; only 1 of these should be set, ;%define ISFAT12 1 ; only 1 of these should be set,
;%define ISFAT16 1 ; defines which FAT is supported ;%define ISFAT16 1 ; defines which FAT is supported
%define TRYLBAREAD 1 ; undefine to use only CHS int 13h %define TRYLBAREAD 1 ; undefine to use only CHS int 13h
;%define LOOPONERR 1 ; if defined on error simply loop forever %define SETROOTDIR 1 ; if defined dir entry copied to 0:500
;%define SETROOTDIR 1 ; if defined dir entry copied to 0:500 %define LOOPONERR 1 ; if defined on error simply loop forever
;%define RETRYALWAYS 1 ; if defined retries read forever ;%define RETRYALWAYS 1 ; if defined retries read forever
;%define WINBOOT 1 ; use win9x kernel calling conventions (name & jmp addr)
;%define MSCOMPAT 1 ; sets default filename to MSDOS IO.SYS ;%define MSCOMPAT 1 ; sets default filename to MSDOS IO.SYS
%ifdef WINBOOT ; if set also change from PC-DOS to
%ifndef MSCOMPAT ; kernel name to MS-DOS kernel name
%define MSCOMPAT
%endif
%endif
segment .text segment .text
%define BASE 0x7c00 ; boot sector originally at 0x0:BASE %define BASE 0x7c00 ; boot sector originally at 0x0:BASE
@ -133,7 +166,8 @@ segment .text
;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses ;%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses
%define fat_start PARAMS+0x2 ; first FAT sector %define fat_start PARAMS+0x2 ; first FAT sector
;%define root_dir_start PARAMS+0x6 ; first root directory sector ;%define root_dir_start PARAMS+0x6 ; first root directory sector
%define data_start PARAMS+0x0a ; first data sector %define first_cluster PARAMS+0x0a ; starting cluster of kernel file
%define data_start bp-4 ; first data sector (win9x expects here)
;----------------------------------------------------------------------- ;-----------------------------------------------------------------------
@ -203,20 +237,33 @@ real_start:
mov es, ax mov es, ax
mov ss, ax mov ss, ax
mov bp, BASE mov bp, BASE
lea sp, [bp-2] lea sp, [bp-4] ; for DOS <7 this may be [bp]
; a reset should not be needed here
; int 0x13 ; reset drive
; For compatibility, diskette parameter vector updated. ; For compatibility, diskette parameter vector updated.
; lea di [bp+0x3E] ; just use bp for DR-DOS? ; lea di [bp+0x3E] ; use 7c3e([bp+3e]) for PC-DOS,
; ;lea di [bp] ; but 7c00([bp]) for DR-DOS 7 bug
; mov bx, 4 * 1eh ; stored at int 1E's vector ; mov bx, 4 * 1eh ; stored at int 1E's vector
; lds si, [bx] ; fetch current int 1eh pointer ; lds si, [bx] ; fetch current int 1eh pointer
; push ds ; store original 1eh pointer at stack top
; push si ; so can restore later if needed
;
; Copy table to new location
; mov cl, 11 ; the parameter table is 11 bytes ; mov cl, 11 ; the parameter table is 11 bytes
; rep movsb ; and copy the parameter block ; rep movsb ; and copy the parameter block
; mov ds, ax ; restore DS ; mov ds, ax ; restore DS
;
; Note: make desired changes to table here
;
; Update int1E to new location
; mov [bx+2], 0 ; set to 0:bp or 0:bp+3e as appropriate
; mov word [bx], 0x7c3e ; (use 0x7c00 for DR-DOS)
sti ; enable interrupts sti ; enable interrupts
; If updated floppy parameter table then must notify BIOS
; Otherwise a reset should not be needed here.
; int 0x13 ; reset drive (AX=0)
; ;
; Note: some BIOS implementations may not correctly pass drive number ; Note: some BIOS implementations may not correctly pass drive number
; in DL, however we work around this in SYS.COM by NOP'ing out the use of DL ; in DL, however we work around this in SYS.COM by NOP'ing out the use of DL
@ -290,22 +337,21 @@ next_entry: mov cx, 11
je ffDone je ffDone
add si, byte 0x20 ; go to next directory entry add si, byte 0x20 ; go to next directory entry
jc near boot_error ; fail if not found and si wraps jc boot_error ; fail if not found and si wraps
cmp byte [si], 0 ; if the first byte of the name is 0, cmp byte [si], 0 ; if the first byte of the name is 0,
jnz next_entry ; there are no more files in the directory jnz next_entry ; there are no more files in the directory
ffDone: ffDone:
push ax ; store first cluster number mov [first_cluster], ax ; store first cluster number
%ifdef SETROOTDIR %ifdef SETROOTDIR
; copy over this portion of root dir to 0x0:500 for PC-DOS ; copy over this portion of root dir to 0x0:500 for PC-DOS
; (this may allow IBMBIO.COM to start in any directory entry) ; (this may allow IBMBIO.COM to start in any directory entry)
lea di, [ROOTDIR] ; es:di = 0:0500 lea di, [ROOTDIR] ; es:di = 0:0500
mov cx, 0x100 mov cx, 32 ; limit to this 1 entry (rest don't matter)
rep movsw rep movsw
%endif %endif
; GETFATCHAIN: ; GETFATCHAIN:
; ;
; Reads the FAT chain and stores it in a temporary buffer in the first ; Reads the FAT chain and stores it in a temporary buffer in the first
@ -334,7 +380,7 @@ ffDone:
mov ax, LOADSEG mov ax, LOADSEG
mov ds, ax ; ds:0 = 0x70:0 = 0:FATBUF mov ds, ax ; ds:0 = 0x70:0 = 0:FATBUF
pop ax ; restore first cluster number mov ax, [first_cluster] ; restore first cluster number
push ds ; store LOADSEG push ds ; store LOADSEG
next_clust: stosw ; store cluster number next_clust: stosw ; store cluster number
@ -403,7 +449,30 @@ cluster_next: lodsw ; AX = next cluster to read
mov ch, [bsMedia] ; ch set to media id mov ch, [bsMedia] ; ch set to media id
mov ax, [data_start+2] ; ax:bx set to 1st data sector mov ax, [data_start+2] ; ax:bx set to 1st data sector
mov bx, [data_start] ; mov bx, [data_start] ;
mov di, [first_cluster] ; set di (si:di on FAT32) to starting cluster #
%ifdef WINBOOT
jmp LOADSEG:0x0200 ; yes, pass control to kernel
%else
jmp LOADSEG:0000 ; yes, pass control to kernel jmp LOADSEG:0000 ; yes, pass control to kernel
%endif
; failed to boot
boot_error:
call show
; db "Error! Hit a key to reboot."
db "):."
%ifdef LOOPONERR
jmp $
%else
; Note: should restore floppy paramater table address at int 0x1E
xor ah,ah
int 0x13 ; reset floppy
int 0x16 ; wait for a key
int 0x19 ; reboot the machine
%endif
load_next: dec ax ; cluster numbers start with 2 load_next: dec ax ; cluster numbers start with 2
dec ax dec ax
@ -428,22 +497,6 @@ show: pop si
jne show ; until done jne show ; until done
ret ret
; failed to boot
boot_error:
%ifdef LOOPONERR
jmp boot_error
%else
call show
; db "Error! Hit a key to reboot."
db "Err."
xor ah,ah
int 0x13 ; reset floppy
int 0x16 ; wait for a key
int 0x19 ; reboot the machine
%endif
; readDisk: Reads a number of sectors into memory. ; readDisk: Reads a number of sectors into memory.
; ;
@ -564,7 +617,8 @@ read_next_chained:
read_ok: read_ok:
mov ax, word [bsBytesPerSec] mov ax, word [bsBytesPerSec]
shr ax, 4 ; adjust segment pointer by increasing mov cl, 4 ; adjust segment pointer by increasing
shr ax, cl
add word [LBA_SEG], ax ; by paragraphs read in (per sector) add word [LBA_SEG], ax ; by paragraphs read in (per sector)
add LBA_SECTOR_0, byte 1 add LBA_SECTOR_0, byte 1

View File

@ -1,5 +1,5 @@
<html> <html>
<title>sys</title> <title>sys - FreeDOS system file installer</title>
<body> <body>
<h1>sys</h1> <h1>sys</h1>
Copy system files and make a floppy disk or hard disk bootable. Copy system files and make a floppy disk or hard disk bootable.
@ -32,6 +32,16 @@ Switches (FreeDOS specific):
but the kernel and <a href="command.htm">command.com</a> will but the kernel and <a href="command.htm">command.com</a> will
not be copied to the destination. not be copied to the destination.
<b>/UPDATE</b>
This option is for updating (or changing) your kernel while
leaving your shell alone. Updates the boot sector and copies
the kernel file(s) to the destination. [Allows installing
latest kernel and boot sector without making a copy of your
current COMMAND.COM or other shell first.] Note: for FreeDOS
kernel, an upgrade can also be performed by simply copying
KERNEL.SYS over an existing bootable one (though making a
backup of your current kernel is encouraged).
<b>/K <i>filename</i></b> <b>/K <i>filename</i></b>
Gives the <i>filename</i> of the kernel file to be copied. This option Gives the <i>filename</i> of the kernel file to be copied. This option
is only required when the kernel is not called "kernel.sys" is only required when the kernel is not called "kernel.sys"

View File

@ -1,4 +1,4 @@
FreeDOS SYS 3.5 FreeDOS SYS 3.6
documentation by: documentation by:
Jeremy Davis Jeremy Davis
Bart Oldeman Bart Oldeman
@ -22,6 +22,7 @@ SYS [source] dest: [bootsect] [{option}]
{option} is one or more of the following: {option} is one or more of the following:
/BOTH : write to *both* the real boot sector and the image file /BOTH : write to *both* the real boot sector and the image file
/BOOTONLY: do *not* copy kernel / shell, only update boot sector or image /BOOTONLY: do *not* copy kernel / shell, only update boot sector or image
/UPDATE : copy kernel and update boot sector (do *not* copy shell)
/OEM : indicates boot sector, filenames, and load segment to use /OEM : indicates boot sector, filenames, and load segment to use
/OEM:FD use FreeDOS compatible settings /OEM:FD use FreeDOS compatible settings
/OEM:DR use DR DOS 7+ compatible settings (same as /OEM) /OEM:DR use DR DOS 7+ compatible settings (same as /OEM)

100
sys/sys.c
View File

@ -32,7 +32,7 @@
#define FDCONFIG /* include support to configure FD kernel */ #define FDCONFIG /* include support to configure FD kernel */
/* #define DRSYS */ /* SYS for Enhanced DR-DOS (OpenDOS enhancement Project) */ /* #define DRSYS */ /* SYS for Enhanced DR-DOS (OpenDOS enhancement Project) */
#define SYS_VERSION "v3.5b" #define SYS_VERSION "v3.6"
#define SYS_NAME "FreeDOS System Installer " #define SYS_NAME "FreeDOS System Installer "
@ -293,25 +293,26 @@ int FDKrnConfigMain(int argc, char **argv);
typedef struct DOSBootFiles { typedef struct DOSBootFiles {
const char * kernel; /* filename boot sector loads and chains to */ const char * kernel; /* filename boot sector loads and chains to */
const char * dos; /* optional secondary file for OS */ const char * dos; /* optional secondary file for OS */
WORD loadseg; /* segment kernel file expects to start at */ WORD loadaddr; /* segment kernel file expects to start at for stdbs */
/* or offset to jump into kernel for oem compat bs */
BOOL stdbs; /* use FD boot sector (T) or oem compat one (F) */ BOOL stdbs; /* use FD boot sector (T) or oem compat one (F) */
LONG minsize; /* smallest dos file can be and be valid, 0=existance optional */ LONG minsize; /* smallest dos file can be and be valid, 0=existance optional */
} DOSBootFiles; } DOSBootFiles;
#define FREEDOS_FILES { "KERNEL.SYS", NULL, 0x60, 1, 0 }, #define FREEDOS_FILES { "KERNEL.SYS", NULL, 0x60/*:0*/, 1, 0 },
DOSBootFiles bootFiles[] = { DOSBootFiles bootFiles[] = {
/* Note: This order is the order OEM:AUTO uses to determine DOS flavor. */ /* Note: This order is the order OEM:AUTO uses to determine DOS flavor. */
#ifndef DRSYS #ifndef DRSYS
/* FreeDOS */ FREEDOS_FILES /* FreeDOS */ FREEDOS_FILES
#endif #endif
/* DR-DOS */ { "DRBIO.SYS", "DRDOS.SYS", 0x70, 1, 1 }, /* DR-DOS */ { "DRBIO.SYS", "DRDOS.SYS", 0x70/*:0*/, 1, 1 },
/* DR-DOS */ { "IBMBIO.COM", "IBMDOS.COM", 0x70, 1, 1 }, /* DR-DOS */ { "IBMBIO.COM", "IBMDOS.COM", 0x70/*:0*/, 1, 1 },
#ifdef DRSYS #ifdef DRSYS
/* FreeDOS */ FREEDOS_FILES /* FreeDOS */ FREEDOS_FILES
#endif #endif
#ifdef WITHOEMCOMPATBS #ifdef WITHOEMCOMPATBS
/* PC-DOS */ { "IBMBIO.COM", "IBMDOS.COM", 0x70, 0, 6138 }, /* pre v7 DR ??? */ /* PC-DOS */ { "IBMBIO.COM", "IBMDOS.COM", /*0x70:*/0x0, 0, 6138 }, /* pre v7 DR ??? */
/* MS-DOS */ { "IO.SYS", "MSDOS.SYS", 0x70, 0, 10240 }, /* MS-DOS */ { "IO.SYS", "MSDOS.SYS", /*0x70:*/0x0, 0, 10240 },
/* W9x-DOS */ { "IO.SYS", "MSDOS.SYS", 0x70, 0, 0}, /* W9x-DOS */ { "IO.SYS", "MSDOS.SYS", /*0x70:*/0x0200, 0, 0 },
#endif #endif
}; };
#define DOSFLAVORS (sizeof(bootFiles) / sizeof(*bootFiles)) #define DOSFLAVORS (sizeof(bootFiles) / sizeof(*bootFiles))
@ -356,7 +357,8 @@ typedef struct SYSOptions {
DOSBootFiles kernel; /* file name(s) and relevant data for kernel */ DOSBootFiles kernel; /* file name(s) and relevant data for kernel */
BYTE defBootDrive; /* value stored in boot sector for drive, eg 0x0=A, 0x80=C */ BYTE defBootDrive; /* value stored in boot sector for drive, eg 0x0=A, 0x80=C */
BOOL ignoreBIOS; /* true to NOP out boot sector code to get drive# from BIOS */ BOOL ignoreBIOS; /* true to NOP out boot sector code to get drive# from BIOS */
BOOL copyFiles; /* true to copy kernel files and command interpreter */ BOOL copyKernel; /* true to copy kernel files */
BOOL copyShell; /* true to copy command interpreter */
BOOL writeBS; /* true to write boot sector to drive/partition LBA 0 */ BOOL writeBS; /* true to write boot sector to drive/partition LBA 0 */
BYTE *bsFile; /* file name & path to save bs to when saving to file */ BYTE *bsFile; /* file name & path to save bs to when saving to file */
BYTE *bsFileOrig; /* file name & path to save original bs when backing up */ BYTE *bsFileOrig; /* file name & path to save original bs when backing up */
@ -382,6 +384,7 @@ void showHelpAndExit(void)
" {option} is one or more of the following:\n" " {option} is one or more of the following:\n"
" /BOTH : write to *both* the real boot sector and the image file\n" " /BOTH : write to *both* the real boot sector and the image file\n"
" /BOOTONLY: do *not* copy kernel / shell, only update boot sector or image\n" " /BOOTONLY: do *not* copy kernel / shell, only update boot sector or image\n"
" /UPDATE : copy kernel and update boot sector (do *not* copy shell)\n"
" /OEM : indicates boot sector, filenames, and load segment to use\n" " /OEM : indicates boot sector, filenames, and load segment to use\n"
" /OEM:FD use FreeDOS compatible settings\n" " /OEM:FD use FreeDOS compatible settings\n"
" /OEM:EDR use Enhanced DR DOS 7+ compatible settings\n" " /OEM:EDR use Enhanced DR DOS 7+ compatible settings\n"
@ -400,7 +403,7 @@ void showHelpAndExit(void)
"%s CONFIG /help\n" "%s CONFIG /help\n"
#endif #endif
/*SYS, KERNEL.SYS/DRBIO.SYS 0x60/0x70*/ /*SYS, KERNEL.SYS/DRBIO.SYS 0x60/0x70*/
, pgm, bootFiles[0].kernel, bootFiles[0].loadseg , pgm, bootFiles[0].kernel, bootFiles[0].loadaddr
#ifdef FDCONFIG #ifdef FDCONFIG
, pgm , pgm
#endif #endif
@ -422,7 +425,8 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
memset(opts, 0, sizeof(SYSOptions)); memset(opts, 0, sizeof(SYSOptions));
/* set srcDrive and dstDrive after processing args */ /* set srcDrive and dstDrive after processing args */
opts->flavor = OEM_AUTO; /* attempt to detect DOS user wants to boot */ opts->flavor = OEM_AUTO; /* attempt to detect DOS user wants to boot */
opts->copyFiles = 1; /* actually copy the kernel and cmd interpreter to dstDrive */ opts->copyKernel = 1; /* actually copy the kernel and cmd interpreter to dstDrive */
opts->copyShell = 1;
/* cycle through processing cmd line arguments */ /* cycle through processing cmd line arguments */
for(argno = 1; argno < argc; argno++) for(argno = 1; argno < argc; argno++)
@ -446,7 +450,14 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
/* do *not* copy kernel / shell, only update boot sector or image */ /* do *not* copy kernel / shell, only update boot sector or image */
else if (memicmp(argp, "BOOTONLY", 8) == 0) else if (memicmp(argp, "BOOTONLY", 8) == 0)
{ {
opts->copyFiles = 0; opts->copyKernel = 0;
opts->copyShell = 0;
}
/* copy kernel and update boot sector (do *not* copy shell) */
else if (memicmp(argp, "UPDATE", 8) == 0)
{
opts->copyKernel = 1;
opts->copyShell = 0;
} }
/* indicates compatibility mode, fs, filenames, and load segment to use */ /* indicates compatibility mode, fs, filenames, and load segment to use */
else if (memicmp(argp, "OEM", 3) == 0) else if (memicmp(argp, "OEM", 3) == 0)
@ -499,7 +510,7 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
} }
else if (toupper(*argp) == 'L') /* set Load segment */ else if (toupper(*argp) == 'L') /* set Load segment */
{ {
opts->kernel.loadseg = (WORD)strtol(argv[argno], NULL, 16); opts->kernel.loadaddr = (WORD)strtol(argv[argno], NULL, 16);
} }
else if (memicmp(argp, "B", 2) == 0) /* set boot drive # */ else if (memicmp(argp, "B", 2) == 0) /* set boot drive # */
{ {
@ -673,7 +684,7 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
/* set compatibility settings not explicitly set */ /* set compatibility settings not explicitly set */
if (!opts->kernel.kernel) opts->kernel.kernel = bootFiles[opts->flavor].kernel; if (!opts->kernel.kernel) opts->kernel.kernel = bootFiles[opts->flavor].kernel;
if (!opts->kernel.dos) opts->kernel.dos = bootFiles[opts->flavor].dos; if (!opts->kernel.dos) opts->kernel.dos = bootFiles[opts->flavor].dos;
if (!opts->kernel.loadseg) opts->kernel.loadseg = bootFiles[opts->flavor].loadseg; if (!opts->kernel.loadaddr) opts->kernel.loadaddr = bootFiles[opts->flavor].loadaddr;
opts->kernel.stdbs = bootFiles[opts->flavor].stdbs; opts->kernel.stdbs = bootFiles[opts->flavor].stdbs;
opts->kernel.minsize = bootFiles[opts->flavor].minsize; opts->kernel.minsize = bootFiles[opts->flavor].minsize;
@ -688,7 +699,7 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
/* unless we are only setting boot sector, verify kernel file exists */ /* unless we are only setting boot sector, verify kernel file exists */
if (opts->copyFiles) if (opts->copyKernel)
{ {
/* check kernel (primary file) 1st */ /* check kernel (primary file) 1st */
sprintf(srcFile, "%s%s", opts->srcDrive, (opts->fnKernel)?opts->fnKernel:opts->kernel.kernel); sprintf(srcFile, "%s%s", opts->srcDrive, (opts->fnKernel)?opts->fnKernel:opts->kernel.kernel);
@ -720,7 +731,11 @@ void initOptions(int argc, char *argv[], SYSOptions *opts)
exit(1); exit(1);
} }
} }
}
/* if updating or only setting bootsector then skip this check */
if (opts->copyShell)
{
/* lastly check for command interpreter */ /* lastly check for command interpreter */
sprintf(srcFile, "%s%s", opts->srcDrive, (opts->fnCmd)?opts->fnCmd:"COMMAND.COM"); sprintf(srcFile, "%s%s", opts->srcDrive, (opts->fnCmd)?opts->fnCmd:"COMMAND.COM");
if (stat(srcFile, &fstatbuf)) /* if !exists() */ if (stat(srcFile, &fstatbuf)) /* if !exists() */
@ -754,7 +769,7 @@ int main(int argc, char **argv)
printf("Processing boot sector...\n"); printf("Processing boot sector...\n");
put_boot(&opts); put_boot(&opts);
if (opts.copyFiles) if (opts.copyKernel)
{ {
printf("Now copying system files...\n"); printf("Now copying system files...\n");
@ -774,7 +789,12 @@ int main(int argc, char **argv)
exit(1); exit(1);
} /* copy secondary file (DOS) */ } /* copy secondary file (DOS) */
} }
}
if (opts.copyShell)
{
printf("Copying shell (command interpreter)...\n");
/* copy command.com, 1st try source path, then try %COMSPEC% */ /* copy command.com, 1st try source path, then try %COMSPEC% */
sprintf(srcFile, "%s%s", opts.srcDrive, (opts.fnCmd)?opts.fnCmd:"COMMAND.COM"); sprintf(srcFile, "%s%s", opts.srcDrive, (opts.fnCmd)?opts.fnCmd:"COMMAND.COM");
if (!copy(srcFile, opts.dstDrive, "COMMAND.COM")) if (!copy(srcFile, opts.dstDrive, "COMMAND.COM"))
@ -1337,6 +1357,7 @@ void put_boot(SYSOptions *opts)
if (fs == FAT32) if (fs == FAT32)
{ {
bs32 = (struct bootsectortype32 *)&newboot; bs32 = (struct bootsectortype32 *)&newboot;
if (!bs32->bsBackupBoot) bs32->bsBackupBoot = 0x6; /* ensure set, 6 is MS defined bs size */
bs32->bsDriveNumber = opts->defBootDrive; bs32->bsDriveNumber = opts->defBootDrive;
/* the location of the "0060" segment portion of the far pointer /* the location of the "0060" segment portion of the far pointer
@ -1350,7 +1371,7 @@ void put_boot(SYSOptions *opts)
*/ */
if (opts->kernel.stdbs) if (opts->kernel.stdbs)
{ {
((int *)newboot)[0x78/sizeof(int)] = opts->kernel.loadseg; ((int *)newboot)[0x78/sizeof(int)] = opts->kernel.loadaddr;
bsBiosMovOff = 0x82; bsBiosMovOff = 0x82;
} }
else /* compatible bs */ else /* compatible bs */
@ -1374,23 +1395,34 @@ void put_boot(SYSOptions *opts)
/* the location of the "0060" segment portion of the far pointer /* the location of the "0060" segment portion of the far pointer
in the boot sector is just before cont: in boot*.asm. in the boot sector is just before cont: in boot*.asm.
This happens to be offset 0x78 for FAT32 and offset 0x5c for FAT16 This happens to be offset 0x78 for FAT32 and offset 0x5c for FAT16
The oem boot sectors do not have/need this value for patching.
the location of the jmp address (patching from
EA00007000 [jmp 0x0070:0000] to EA00207000 [jmp 0x0070:0200])
0x11b: for fat12 oem boot sector
0x118: for fat16 oem boot sector
The standard boot sectors do not have/need this value patched.
force use of value stored in bs by NOPping out mov [drive], dl force use of value stored in bs by NOPping out mov [drive], dl
0x66: 88h,56h,24h for fat16 and fat12 boot sectors 0x66: 88h,56h,24h for fat16 and fat12 boot sectors
0x4F: 88h,56h,24h for oem compatible fat16 and fat12 boot sectors 0x4F: 88h,56h,24h for oem compatible fat16 and fat12 boot sectors
i.e. BE CAREFUL WHEN YOU CHANGE THE BOOT SECTORS !!! i.e. BE CAREFUL WHEN YOU CHANGE THE BOOT SECTORS !!!
*/ */
if (opts->kernel.stdbs) if (opts->kernel.stdbs)
{ {
((int *)newboot)[0x5c/sizeof(int)] = opts->kernel.loadseg; /* this sets the segment we load the kernel to, default is 0x60:0 */
((int *)newboot)[0x5c/sizeof(int)] = opts->kernel.loadaddr;
bsBiosMovOff = 0x66; bsBiosMovOff = 0x66;
} }
else else
{ {
/* load segment hard coded to 0x70 in oem compatible boot sector */ /* load segment hard coded to 0x70 in oem compatible boot sector, */
if (opts->kernel.loadseg != 0x70) /* this however changes the offset jumped to default 0x70:0 */
printf("%s: Warning! ignoring load segment, compat bs always uses 0x70!\n", pgm); if (fs == FAT12)
((int *)newboot)[0x11c/sizeof(int)] = opts->kernel.loadaddr;
else
((int *)newboot)[0x119/sizeof(int)] = opts->kernel.loadaddr;
bsBiosMovOff = 0x4F; bsBiosMovOff = 0x4F;
} }
} }
@ -1443,7 +1475,10 @@ void put_boot(SYSOptions *opts)
#ifdef DEBUG #ifdef DEBUG
/* there's a zero past the kernel name in all boot sectors */ /* there's a zero past the kernel name in all boot sectors */
printf("Boot sector kernel name set to %s\n", &newboot[0x1f1]); printf("Boot sector kernel name set to %s\n", &newboot[0x1f1]);
printf("Boot sector load segment set to %Xh\n", opts->kernel.loadseg); if (opts->kernel.stdbs)
printf("Boot sector kernel load segment set to %X:0h\n", opts->kernel.loadaddr);
else
printf("Boot sector kernel jmp address set to 70:%Xh\n", opts->kernel.loadaddr);
#endif #endif
#ifdef DDEBUG #ifdef DDEBUG
@ -1463,6 +1498,25 @@ void put_boot(SYSOptions *opts)
printf("Can't write new boot sector to drive %c:\n", opts->dstDrive + 'A'); printf("Can't write new boot sector to drive %c:\n", opts->dstDrive + 'A');
exit(1); exit(1);
} }
/* for FAT32, we need to update the backup copy as well */
/* Note: assuming sectors 1-5 & 7-11 (FSINFO+additional boot code)
are properly setup by prior format and need no modification
[technically freespace, etc. should be updated]
*/
if (fs == FAT32)
{
bs32 = (struct bootsectortype32 *)&newboot;
#ifdef DEBUG
printf("writing backup bootsector to sector %d\n", bs32->bsBackupBoot);
#endif
if (MyAbsReadWrite(opts->dstDrive, 1, bs32->bsBackupBoot, newboot, 1) != 0)
{
printf("Can't write backup boot sector to drive %c:\n", opts->dstDrive + 'A');
exit(1);
}
}
} /* if write boot sector to boot record*/ } /* if write boot sector to boot record*/
if (opts->bsFile != NULL) if (opts->bsFile != NULL)