diff --git a/boot/boot.asm b/boot/boot.asm index 8482933..af2c527 100644 --- a/boot/boot.asm +++ b/boot/boot.asm @@ -139,10 +139,8 @@ Entry: jmp short real_start times 0x3E-$+$$ db 0 -%define loadsegoff_60 bp+0x3E - dw 0 -%define loadseg_60 bp+0x40 - dw LOADSEG +%define loadsegoff_60 bp+loadseg_off-Entry +%define loadseg_60 bp+loadseg_seg-Entry ;%define LBA_PACKET bp+0x42 ; db 10h ; size of packet @@ -199,6 +197,9 @@ real_start: rep movsw jmp word 0x1FE0:cont +loadseg_off dw 0 +loadseg_seg dw LOADSEG + cont: mov ds, ax mov ss, ax diff --git a/boot/boot32.asm b/boot/boot32.asm index 06eeae6..8ac4f3c 100644 --- a/boot/boot32.asm +++ b/boot/boot32.asm @@ -65,10 +65,8 @@ Entry: jmp short real_start %define fat_sector bp+0x48 ; last accessed sector of the FAT -%define loadsegoff_60 bp+0x5a ; FAR pointer = 60:0 - dw 0 -%define loadseg_60 bp+0x5c - dw LOADSEG +%define loadsegoff_60 bp+loadseg_off-Entry ; FAR pointer = 60:0 +%define loadseg_60 bp+loadseg_seg-Entry %define fat_start bp+0x5e ; first FAT sector %define data_start bp+0x62 ; first data sector @@ -93,6 +91,9 @@ real_start: cld rep movsw ; move boot code to the 0x1FE0:0x0000 jmp word 0x1FE0:cont +loadseg_off dw 0 +loadseg_seg dw LOADSEG + cont: mov ds, ax mov ss, ax lea sp, [bp-0x20] diff --git a/boot/boot32lb.asm b/boot/boot32lb.asm index 2795f89..aa1631b 100644 --- a/boot/boot32lb.asm +++ b/boot/boot32lb.asm @@ -81,6 +81,7 @@ Entry: jmp short real_start ; +0x32 dw -1 or sector number of boot sector backup ; (+0x34 .. +0x3f reserved) %define drive bp+0x40 ; Drive number +%define loadsegoff_60 bp+loadseg_off-Entry %define LOADSEG 0x0060 @@ -107,24 +108,27 @@ Entry: jmp short real_start ;----------------------------------------------------------------------- real_start: cld + cli sub ax, ax mov ds, ax - lss sp, [mystack] ; initialize stack - int 0x13 ; reset drive + mov bp, 0x7c00 mov ax, 0x1FE0 mov es, ax - mov si, sp - mov di, sp - mov bp, sp ; bp-relative parameter addresses used + mov si, bp + mov di, bp mov cx, 0x0100 rep movsw ; move boot code to the 0x1FE0:0x0000 jmp word 0x1FE0:cont +loadseg_off dw 0, LOADSEG + ; ------------- cont: mov ds, ax mov ss, ax ; stack and BP-relative moves up, too + lea sp, [bp-0x20] + sti mov [drive], dl ; BIOS passes drive number in DL mov si, msg_LoadFreeDOS @@ -177,9 +181,7 @@ ff_next_clust: push eax ; save cluster jc boot_error ; EOC encountered ; EDX is clust/sector, EAX is sector -ff_next_sector: mov bx, LOADSEG - mov es, bx - sub bx, bx ; load to loadseg:0 +ff_next_sector: les bx, [loadsegoff_60] ; load to loadseg:0 call readDisk ;--- push eax ; save sector @@ -233,7 +235,7 @@ rk_walk_fat: pop eax ;----------------------------------------------------------------------- boot_success: mov bl, [drive] - jmp word LOADSEG:0 + jmp far [loadsegoff_60] ;----------------------------------------------------------------------- @@ -389,9 +391,6 @@ no_incr_es: pop di msg_LoadFreeDOS db "Loading FreeDOS ",0 -mystack dw 0x7c00 ; the 0 for SS overlaps into pad bytes! - ; (so we can LSS SP to 0:7c00) - times 0x01ee-$+$$ db 0 msg_BootError db "No " diff --git a/sys/sys.c b/sys/sys.c index a7fa29f..317b1ac 100644 --- a/sys/sys.c +++ b/sys/sys.c @@ -29,7 +29,7 @@ #define DEBUG /* #define DDEBUG */ -#define SYS_VERSION "v2.9" +#define SYS_VERSION "v3.0" #include #include @@ -159,7 +159,7 @@ char *getenv(const char *name) BYTE pgm[] = "SYS"; -void put_boot(int, char *, char *, int); +void put_boot(int, char *, char *, int, int); BOOL check_space(COUNT, ULONG); BOOL copy(COUNT drive, BYTE * srcPath, BYTE * rootPath, BYTE * file); @@ -254,6 +254,7 @@ int main(int argc, char **argv) int bootonly = 0; int both = 0; char *kernel_name = "KERNEL.SYS"; + int load_segment = 0x60; printf("FreeDOS System Installer " SYS_VERSION ", " __DATE__ "\n\n"); @@ -278,6 +279,11 @@ int main(int argc, char **argv) argno++; kernel_name = argv[argno]; } + else if (argp[0] == '/' && toupper(argp[1]) == 'L' && argno + 1 < argc) + { + argno++; + load_segment = (int)strtol(argv[argno], NULL, 16); + } else if (memicmp(argp, "BOOTONLY", 8) == 0 && !bootonly) { bootonly = 1; @@ -303,7 +309,7 @@ int main(int argc, char **argv) if (drivearg == 0) { printf( - "Usage: %s [source] drive: [bootsect [BOTH]] [BOOTONLY] [/K name]\n" + "Usage: %s [source] drive: [bootsect [BOTH]] [BOOTONLY] [/K name] [/L segm]\n" " source = A:,B:,C:\\KERNEL\\BIN\\,etc., or current directory if not given\n" " drive = A,B,etc.\n" " bootsect = name of 512-byte boot sector file image for drive:\n" @@ -311,6 +317,7 @@ int main(int argc, char **argv) " 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" " /K name : name of kernel to use instead of KERNEL.SYS\n" + " /L segm : hex load segment to use instead of 60\n" "%s CONFIG /help\n", pgm, pgm); exit(1); } @@ -362,7 +369,7 @@ int main(int argc, char **argv) sprintf(rootPath, "%c:\\", 'A' + srcDrive); printf("Processing boot sector...\n"); - put_boot(drive, bsFile, kernel_name, both); + put_boot(drive, bsFile, kernel_name, load_segment, both); if (!bootonly) { @@ -662,7 +669,7 @@ BOOL haveLBA(void) } #endif -void put_boot(int drive, char *bsFile, char *kernel_name, int both) +void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both) { #ifdef WITHFAT32 struct bootsectortype32 *bs32; @@ -756,6 +763,12 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int both) bs32 = (struct bootsectortype32 *)&newboot; /* put 0 for A: or B: (force booting from A:), otherwise use DL */ bs32->bsDriveNumber = drive < 2 ? 0 : 0xff; + /* the location of the "0060" segment portion of the far pointer + in the boot sector is just before cont: in boot*.asm. + This happens to be offset 0x78 (=0x3c * 2) for FAT32 and + offset 0x5c (=0x2e * 2) for FAT16 */ + /* i.e. BE CAREFUL WHEN YOU CHANGE THE BOOT SECTORS !!! */ + ((int *)newboot)[0x3C] = load_seg; #ifdef DEBUG printf(" FAT starts at sector %lx + %x\n", bs32->bsHiddenSecs, bs32->bsResSectors); @@ -766,6 +779,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int both) { /* put 0 for A: or B: (force booting from A:), otherwise use DL */ bs->bsDriveNumber = drive < 2 ? 0 : 0xff; + ((int *)newboot)[0x2E] = load_seg; } #ifdef DEBUG /* add an option to display this on user request? */ @@ -801,6 +815,7 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int both) #ifdef DEBUG /* 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 load segment set to %Xh\n", load_seg); #endif #ifdef DDEBUG