summaryrefslogtreecommitdiff
path: root/bootblocks
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1998-07-01 01:00:00 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:40:31 +0200
commitec5f28e3f1400b5dacb88eda2d9db472a20b4349 (patch)
treeb3215b2306709d0412fd7845c78ca63ccaa2e29b /bootblocks
parent2f828530e36a02c5b4c534e42ab812370c2bf7d9 (diff)
downloaddev86-ec5f28e3f1400b5dacb88eda2d9db472a20b4349.tar.gz
Import Dev86src-0.14.3.tar.gzv0.14.3
Diffstat (limited to 'bootblocks')
-rw-r--r--bootblocks/Makefile18
-rw-r--r--bootblocks/README199
-rw-r--r--bootblocks/bootelks.c194
-rw-r--r--bootblocks/bzimage.c141
-rw-r--r--bootblocks/crc.c216
-rw-r--r--bootblocks/fs.c4
-rw-r--r--bootblocks/fs_tar.c190
-rw-r--r--bootblocks/i86_funcs.c1
-rw-r--r--bootblocks/makeboot.c76
-rw-r--r--bootblocks/mbr.s63
-rw-r--r--bootblocks/minix.c231
-rw-r--r--bootblocks/minix_elks.c152
-rw-r--r--bootblocks/monitor.c12
-rw-r--r--bootblocks/msdos.s22
-rw-r--r--bootblocks/trk_buf.c14
-rw-r--r--bootblocks/unix.c11
-rw-r--r--bootblocks/zimage.s73
17 files changed, 1071 insertions, 546 deletions
diff --git a/bootblocks/Makefile b/bootblocks/Makefile
index a55adc5..c37f35c 100644
--- a/bootblocks/Makefile
+++ b/bootblocks/Makefile
@@ -5,14 +5,15 @@ BCC=bcc
CC=$(BCC)
CFLAGS=-ansi -Ms -Oi -O -s
+# CFLAGS=-ansi -Ms
ASFLAGS=-0 -w
MDEFS=-DDOTS
# LST=-l $*.lst
# CLST=-A-l -A$*.lst
-default: makeboot makeboot.com monitor.out
+default: makeboot makeboot.com monitor.out minix_elks.bin
-all: default tgz bin
+all: default tgz bin minix_elks.bin
CSRC=minix.c
SSRC=sysboot.s \
@@ -28,9 +29,10 @@ MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c trk_buf.c unix.c \
fs.c fs_tar.c fs_min.c fs_dos.c
MINC=i86_funcs.h readfs.h
-BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v tarboot.v minix.v minixhd.v
+BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v tarboot.v minix.v minixhd.v mbr.v
-EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s bootelks.c
+EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s \
+ zimage.s minix_elks.c crc.c
install:
@@ -45,12 +47,14 @@ monitor: $(MSRC) $(MINC)
mv monitor.out monitor
@rm -f $(MOBJ)
-bootelks.out: bootelks.o relocate.o
- $(CC) $(CFLAGS) -i- bootelks.o relocate.o -o bootelks.out
+bzimage.o: bzimage.c zimage.v
minix.s: minix.c Makefile
$(BCC) -Mf -O -DTRY_FLOPPY $(MDEFS) -S minix.c
+minix_elks.s: minix_elks.c Makefile minix.v
+ $(BCC) -Mf -O $(MDEFS) -S minix_elks.c
+
minixhd.s: minix.c Makefile
$(BCC) -Mf -O -DHARDDISK $(MDEFS) -S minix.c -o minixhd.s
@@ -66,7 +70,7 @@ version.h:
clean realclean:
rm -f monitor makeboot bootblocks.tar.gz
- rm -f minix.s minixhd.s version.h
+ rm -f minix.s minixhd.s minix_elks.s version.h
rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp
tgz: minix.bin monitor.out makeboot.com makeboot
diff --git a/bootblocks/README b/bootblocks/README
index e78097d..ab115e3 100644
--- a/bootblocks/README
+++ b/bootblocks/README
@@ -1,114 +1,165 @@
-To install the tarfile bootsector
----------------------------------
+Contents
- Create the makeboot program:
+1.0 ) Boot sectors
+1.1 ) Master boot sector
+1.2 ) Dosfs boot sector
+1.3 ) Minixfs boot block
+1.4 ) Tar boot sector
+1.5 ) Skip boot sector
+1.6 ) Panic boot sector
-$ make makeboot
+2.1 ) Booting i86 standalone executable
+2.2 ) Booting Elks kernel
+2.3 ) Booting Linux-i386 [b]zImage
-Create the tarfile
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-$ tar cvfV /dev/fd0 ENIAC monitor.out item2 item3
+1.0 ) Boot sectors
-Make it bootable
+ These boot sectors are mostly designed for floppy use, the exceptions
+ being the MinixFS and Master boot sectors.
-$ makeboot tar /dev/fd0
+ The makeboot program makes them very easy to install just format the
+ disk add the correct filesystem then run a command like ...
-Note, the distribution tar file is made using this procedure and can be booted
-if uncompressed and copied onto a raw floppy.
+ $ makeboot minix /dev/fd0
-To install the dosfs boot sector
---------------------------------
+ As far as I know all boot sectors and programs are 8086 clean, with
+ the exception that, obviously, the Linux-i386 loader needs access to
+ extended memory.
-$ make makeboot
-$ makeboot dosfs /dev/fd0
+1.1 ) Master boot sector
-or
-$ make makeboot.com
-C:\> makeboot dos a:
+ This MBR is a very simple one with no frills, being less that 254 bytes
+ long is can be used as an MBR for a disk with old style 'Disk manager'
+ partitions. All 16 partitions are bootable.
- Place a Linux-8086 executable in the root directory of the floppy.
+1.2 ) Dosfs boot sector
-$ make monitor.out
-$ mcopy monitor.out a:BOOTFILE.SYS
+ Install with makeboot, the boot sector requires the floppy to be double
+ sided and makeboot checks for this. This boot sector loads and executes
+ a binary BOOTFILE.SYS from the root directory of the floppy. The file
+ can be any length and is loaded at $07C00. Because of the load address
+ this boot sector can be configured to load another boot sector, for
+ example LILO can be succesfully used in this way.
-or
-C:\> copy monitor.out a:\bootfile.sys
+ In fact LILO can be succesfully used in this way on a 2M disk, but
+ you must create the floppy with the real dos 2M package as superformat
+ does not create correct bootable 2M disks. Also beware that mounting
+ a 2M floppy can ... be interesting ...
- This works on my 3 1/5 floppy and my 5 1/4, and it _should_ work on
- any double sided drive. (It does work on a 3.5/720k floppy too)
- For single sided floppies you need to alter msdos.s (the heads var)
- and remove the check in makeboot.c
+ Note this boot sector loads the executable 1 sector at a time, as far
+ as my testing has gone this is only significant on 8086 machines, all
+ others (286 8Mhz +) are fast enough to keep up at a 1-1 interleve.
-To install the minixfs boot sector
-----------------------------------
+1.3 ) Minixfs boot block
- Make a minix filesystem on the floppy:
+ This boot block has varients for floppy and harddisk and works similarly
+ for both. For the hard disk it must be installed in the partition boot
+ block with a normal MBR in sector zero of the disk. This boot sector can
+ be installed with makeboot or simply by copying the 1k file to the start
+ of the partition (or floppy) to be booted.
-$ mkfs -t minix /dev/fd0 1440
-or
-$ mkfs -t minix /dev/fd0 1200
+ The sector looks for a file or directory called 'boot' if it's a
+ directory it loads that and does the search again. When it finds a
+ file it loads it at location $10000 and executes it, beware this
+ is limited to a file size of 519k.
- Make the bootblock program.
+ There is also support for a helper boot which mean this is the only
+ boot sector able to load an ELKS image (almost) directly.
-$ make minix.bin
+1.4 ) Tar boot sector -- Cool Man!!
- Install it
+ This boot sector converts a tar file with a GNU Volume lable into a
+ bootable floppy image. The boot sector loads and executes the first
+ item in the tar file after the lable:
-$ cp minix.bin /dev/fd0
+ $ tar cvfV the_file.tar ENIAC monitor.out item2 item3
+ $ makeboot tar the_file.tar
+ $ cp the_file.tar /dev/fd0
- Place a Linux-8086 executable in the root directory.
+ This sequence makes a bootable floppy that tar sees as a normal labeled
+ tar file but when booted from will load and execute 'monitor.out' at
+ location $00800 (Yes thats 2k!)
-$ make monitor.out
-$ mount -t minix /dev/fd0 /mnt
-$ cp monitor.out /mnt/linux
-$ umount /dev/fd0
+1.5 ) Skip boot sector
- This works on my 3 1/4 floppy, and it _should_ work on any double sided
- drive. Be sure to make the filesystem the full size of the floppy.
+ This bootsector displays a message then loads and executes the hard disk
+ MBR at location $07C00
+1.6 ) Panic boot sector
-Booting a Linux-386 bzImage
----------------------------
+ Displays the message 'PANIC! NO OS Found!' and freezes.
-NOTE: This only works with bzImage files NOT zImage files.
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-Take 1 msdos floppy.
+2.1 ) Booting i86 standalone executable
-$ makeboot dos /dev/fd0
-$ mount -t msdos /dev/fd0 /mnt
-$ cp monitor.out /mnt/bootfile.sys
+ All the boot sectors (dos, minix, tar) check for a ELKS-i86 magic number
+ at the start of the file they load and will correctly set the segment
+ registers before calling. The executable should be a 'standalone'
+ executable compiled with 'bcc -Ms ...' or similar.
-$ cp /usr/src/linux/arch/i386/boot/bzImage /mnt/vmlinuz
-$ echo 'root=/dev/ram ramdisk_file=ramdisk.gz mem=80M' > /mnt/vmlinuz.cmd
-$ cp /archive/ramdisk.gz /mnt/ramdisk.gz
-$ umount /dev/fd0
+2.2 ) Booting Elks kernel
-The stuff about ramdisk is only if you want an init ramdisk. You can also use:
+ Only the minix boot sector can directly boot an elks kernel and even that
+ needs a helper function because of the complexity. The helper is called
+ 'minix_elks.bin' and needs to be copied onto the disk as '/boot/boot'
+ with the ELKS image copied on as '/boot/linux'. This works, with the
+ correct boot block, on either floppy or harddisk.
-vmlinuz.app: Arguments prepended to the Linux command line.
-vmlinuz.cmd: Arguments appended to the Linux command line.
-vmlinux.dfl: Arguments appended to the Linux command line.
+2.3 ) Booting Linux-i386 [b]zImage
-If there's a *.cmd file you won't be asked anything. If there's a *.dfl or
-neither you'll be asked:
+ None of the boot blocks can _directly_ boot a Linux-i386 kernel the
+ program 'monitor.out' must loaded by the boot sector and this can
+ load a zimage or bzimage from an MSDOS or Tar floppy.
-vmlinuz:
+ This example is for and MSDOS floppy, Tar is very similer except that
+ 'monitor.out' must be the first file in the tar and can have any name.
-where you can type a command line to override the *.dfl file. If there's
-a *.cmd file the *.dfl file is ignored, the *.app file is placed at the
-start of the line whichever you do.
+ Note also for a tar file the 'ramdisk.gz' file must start on the first
+ disk but can extend across as many floppies as is needed.
-If the file isn't called 'vmlinuz' you can still boot it by typing "=linux"
-at the prompt '>' where 'linux' is the name of the bzImage file.
+ $ mformat a:
+ $ makeboot dos /dev/fd0
+ $ mount -t msdos /dev/fd0 /mnt
+ $ cp monitor.out /mnt/bootfile.sys
-Escape or ^C will interrupt the boot and drop you to the '>' prompt.
-Esacpe or ^C at the '>' prompt will reboot
- (This may be a little sensitive :-)
+ $ cp /usr/src/linux/arch/i386/boot/zImage /mnt/vmlinuz
+ $ echo 'root=/dev/ram ramdisk_file=ramdisk.gz mem=80M' > /mnt/vmlinuz.cmd
+ $ cp /archive/ramdisk.gz /mnt/ramdisk.gz
+ $ umount /dev/fd0
-A file called 'help.txt' will be displayed upto the first line that starts
-with a '%', chunks after that (seperated by '%'s) will be displayed when
-the user presses a function key, home, page up or page down. (Note it's
-best if you try to ensure 'help.txt' is completely contained on one track
-so the file is entirely in the track buffer)
+ The stuff about ramdisk is only if you want an init ramdisk, if the ramdisk
+ name begins with a '+' the program will ask for another disk first.
+ You can also use:
+
+ vmlinuz.app: Arguments prepended to the Linux command line.
+ vmlinuz.cmd: Arguments appended to the Linux command line.
+ vmlinux.dfl: Arguments appended to the Linux command line.
+
+ If there's a *.cmd file you won't be asked anything. If there's a *.dfl or
+ neither you'll be asked:
+
+ vmlinuz:
+
+ where you can type a command line to override the *.dfl file. If there's
+ a *.cmd file the *.dfl file is ignored, the *.app file is placed at the
+ start of the line whichever you do.
+
+ If the file isn't called 'vmlinuz' you can still boot it by typing "=linux"
+ at the prompt '>' where 'linux' is the name of the bzImage file.
+
+ Escape or ^C will interrupt the boot and drop you to the '>' prompt.
+ Esacpe or ^C at the '>' prompt will reboot
+ (This may be a little sensitive :-)
+
+ A file called 'help.txt' will be displayed upto the first line that starts
+ with a '%', chunks after that (seperated by '%'s) will be displayed when
+ the user presses a function key, home, page up or page down.
+
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+Robert de Bath <rdebath@poboxes.com> 22 Mar 1998
diff --git a/bootblocks/bootelks.c b/bootblocks/bootelks.c
deleted file mode 100644
index a236e6f..0000000
--- a/bootblocks/bootelks.c
+++ /dev/null
@@ -1,194 +0,0 @@
-
-#include <dos.h>
-#include "minix.h"
-
-extern union REGS __argr;
-int x86_test = 0;
-unsigned int boot_mem_top = 0;
-
-void mem_check();
-
-int boot_drive = 0;
-long boot_offset = 0;
-int boot_spt = 0;
-
-char dirname[16] = "boot";
-char imagename[16] = "linux";
-
-char lbuf[80];
-
-int serr();
-int (*read_sector)() = serr;
-
-struct super_block b_super;
-d_inode b_inode[INODES_PER_BLOCK];
-zone_nr b_zone[NR_INDIRECTS];
-/* dir_struct directory[]; */
-
-main()
-{
- writes("Booting Elks....");
-
- mem_check();
-
- writes("\nSystem has ");
- writes(itoa(boot_mem_top/64));
- writes("k of low memory\n");
-
- boot_drive = __argr.h.dl;
- boot_offset = __argr.x.cx;
- boot_offset += ((long)__argr.h.dh << 16);
- boot_spt = __argr.x.si;
-
- relocator(-1);
-
- writes("Relocated code to ");
- writes(itoa(__get_cs()/64));
- writes("k.\n");
-
- writes("Booting from ");
- if( boot_drive & 0x80 ) writes("hard");
- else writes("floppy");
- writes(" drive ");
- writes(itoa(boot_drive&0x7F));
- if( boot_offset )
- {
- writes(" offset ");
- writes(ltoa(boot_offset));
- writes(" sectors");
- }
- writes("\n");
-
- if( boot_drive & 0x80 ) init_hd(boot_drive);
- else init_fd(boot_drive);
-
- if( load_dir(0) >= 0 && load_dir(dirname) >= 0 && load_file(imagename) >= 0 )
- run_elks();
- else if( load_dir(0) >= 0 && load_file(imagename) >= 0 )
- run_elks();
- else
- {
- writes("Cannot find kernel image file\n");
- read(0, lbuf, 1); exit(1);
- }
-
- read(0, lbuf, sizeof(lbuf));
-}
-
-init_fd(drive) { }
-init_hd(drive) { }
-load_dir(name) { return -1; }
-load_file(name) { return -1; }
-run_elks() { }
-
-/****************************************************************************/
-
-writes(str)
-char * str;
-{
- write(1, str, strlen(str));
-}
-
-void mem_check()
-{
-#asm
- int 0x12 ! Amount of boot memory
- mov cl,#6
- sal ax,cl ! In segments
- mov [_boot_mem_top],ax
-#endasm
-}
-
-serr()
-{
- writes("Cannot read sector, drive not initilised\n");
- return -1;
-}
-
-/****************************************************************************/
-
-load_blocks()
-{
- if( b_super.s_magic != SUPER_MAGIC ) return -1;
-
-try_again:;
-#ifdef zone_shift
- if( zone_shift != b_super.s_log_zone_size) return -1;
-#else
- zone_shift = b_super.s_log_zone_size;
-#endif
-
- inode--;
- load_block(seg_of(b_inode), inode/INODES_PER_BLOCK
- + b_super.s_imap_blocks
- + b_super.s_zmap_blocks
- + 2);
- get_now();
-
- ldaddr = LOADSEG; /* Load at 64k mark */
-
- {
- register d_inode * i_ptr;
- i_ptr = b_inode + inode%INODES_PER_BLOCK;
- next_zone = i_ptr->i_zone;
- flength = i_ptr->i_size;
- if( (i_ptr->i_mode & I_TYPE) == I_DIRECTORY )
- {
- ldaddr = seg_of(directory);
- inode = 0; /* Mark - we've no _file_ inode yet */
- }
- }
-
- end_zone = next_zone+NR_DZONE_NUM;
- load_zone(seg_of(b_zone), (indirect = next_zone[NR_DZONE_NUM]));
- get_now();
-
- for(;;)
- {
- if( next_zone >= end_zone )
- {
- if( indirect != 0 )
- {
- next_zone = b_zone;
- end_zone = next_zone + NR_INDIRECTS;
- indirect = 0;
- continue;
- }
- break;
- }
- load_zone(ldaddr, *next_zone);
- next_zone++;
- ldaddr += (seg_at(1) << zone_shift);
- }
- get_now();
-
- if(!inode)
- {
- dirptr = directory;
- while(flength > 0)
- {
-register char * s = bootfile;
-register char * p = dirptr->d_name;
-
- if( dirptr->d_inum )
- {
- for(;;)
- {
- if( *s == '\0')
- {
- if(*p == '\0')
- {
- inode = dirptr->d_inum;
- goto try_again;
- }
- break;
- }
- if( *s++ != *p++ ) break;
- }
- }
- flength -= 16;
- dirptr++;
- }
- nogood();
- }
-}
diff --git a/bootblocks/bzimage.c b/bootblocks/bzimage.c
index baf027b..afb6dde 100644
--- a/bootblocks/bzimage.c
+++ b/bootblocks/bzimage.c
@@ -12,6 +12,8 @@ int auto_flag = 1;
char * append_line = 0; /* A preset append line value */
static char * initrd_name = 0; /* Name of init_ramdisk to load */
+static long initrd_start = 0;
+static long initrd_length = 0;
static int vga_mode = -1; /* SVGA_MODE = normal */
static int is_zimage = 0;
@@ -21,10 +23,12 @@ static long image_size; /* Length of image file in bytes */
static char * read_cmdfile();
static char * input_cmd();
-#define ZIMAGE_LOAD_SEG 0x1000 /* Segment that zImage data is loaded */
+#define ZIMAGE_LOAD_SEG 0x10000 /* Segment that zImage data is loaded */
#define COMMAND_LINE_POS 0x4000 /* Offset in segment 0x9000 of command line */
+#define CALC_CRC
int has_command_line = 0;
+int load_crc = 0;
cmd_bzimage(ptr)
char * ptr;
@@ -58,6 +62,11 @@ char * command_line;
char * ptr;
int low_sects;
unsigned int address;
+
+ initrd_name = 0;
+ initrd_start = initrd_length = 0;
+ vga_mode = -1;
+ is_zimage = 0;
if( open_file(fname) < 0 )
{
@@ -101,6 +110,17 @@ char * command_line;
address = 0x900;
#ifndef __ELKS__
+#if ZIMAGE_LOAD_SEG == 0x10000
+ if( is_zimage )
+ {
+ if( image_length > 0x7FF0/32 )
+ {
+ printf("This zImage file is too large, maximum is %ld bytes\n",
+ (0x7FF0/32 + low_sects)*512L );
+ return -1;
+ }
+ }
+#else
if( is_zimage )
{
relocator(8); /* Need space in low memory */
@@ -113,10 +133,13 @@ char * command_line;
}
}
#endif
+#endif
/* load the blocks */
rewind_file();
+#ifdef CALC_CRC
reset_crc();
+#endif
for(len = file_length(); len>0; len-=1024)
{
int v;
@@ -137,7 +160,9 @@ char * command_line;
return -1;
}
+#ifdef CALC_CRC
if( len > 1024 ) addcrc(buffer, 1024); else addcrc(buffer, (int)len);
+#endif
for(v=0; v<1024; v+=512)
{
if( putsect(buffer+v, address) < 0 )
@@ -150,13 +175,22 @@ char * command_line;
low_sects--;
if( low_sects == 0 )
{
+#if ZIMAGE_LOAD_SEG != 0x10000
if( is_zimage ) address = ZIMAGE_LOAD_SEG/16;
- else address = 0x1000;
+ else
+#endif
+ address = 0x1000;
}
}
}
}
- display_crc();
+#ifdef CALC_CRC
+ load_crc = display_crc(0);
+#endif
+
+#ifdef CALC_CRC
+ if( check_crc() < 0 && !keep_going() ) return -1;
+#endif
/* Yesss, loaded! */
printf("Loaded, "); fflush(stdout);
@@ -169,13 +203,9 @@ char * command_line;
if( load_initrd(address) < 0 )
return -1;
- check_crc();
-
- if( is_zimage )
- {
- printf("Sorry, zImage's don't seem to be working at the moment.\n");
- if( !keep_going() ) return -1;
- }
+#ifdef CALC_CRC
+ if( check_crc() < 0 && !keep_going() ) return -1;
+#endif
printf("Starting ...\n");
@@ -212,12 +242,13 @@ char * command_line;
__doke_es(0x0022, COMMAND_LINE_POS);
}
+#if ZIMAGE_LOAD_SEG != 0x10000
#if ZIMAGE_LOAD_SEG != 0x1000
if( is_zimage )
{
#if ZIMAGE_LOAD_SEG != 0x100
/* Tell setup that we've loaded the kernel somewhere */
- __poke_es(0x20C, ZIMAGE_LOAD_SEG);
+ __doke_es(0x20C, ZIMAGE_LOAD_SEG);
#else
/* Tell setup it's a bzImage _even_ tho it's a _zImage_ because we have
* actually loaded it where it's supposed to end up!
@@ -228,8 +259,22 @@ char * command_line;
#endif
}
#endif
+#endif
+
+ /* Tell the kernel where it is */
+ if( initrd_name )
+ {
+ __set_es(0x9000);
+
+ __doke_es(0x218, (unsigned) initrd_start);
+ __doke_es(0x21A, (unsigned)(initrd_start>>16));
+
+ __doke_es(0x21C, (unsigned) initrd_length);
+ __doke_es(0x21E, (unsigned)(initrd_length>>16));
+ }
+
- if( !is_zimage )
+ if( !is_zimage || initrd_name )
__poke_es(0x210, 0xFF); /* Patch setup to deactivate safety switch */
/* Set SVGA_MODE if not 'normal' */
@@ -238,6 +283,13 @@ char * command_line;
/* Default boot drive is auto-detected floppy */
if( __peek_es(508) == 0 ) __poke_es(508, 0x200);
+#if ZIMAGE_LOAD_SEG == 0x10000
+ if( is_zimage )
+ /* Copy 512k from high memory then start */
+ start_zimage();
+ else
+#endif
+
/* Finally do the deed */
{
#asm
@@ -247,8 +299,8 @@ char * command_line;
outb
! Setup required registers and go ...
- mov ax,$9000
- mov bx,$4000-12 ! Fix this to use boot_mem_top
+ mov ax,#$9000
+ mov bx,#$4000-12 ! Fix this to use boot_mem_top
mov es,ax
mov fs,ax
mov gs,ax
@@ -313,7 +365,7 @@ unsigned int address;
retry:
tc--;
-#if 1
+#if 0
if( x86_emu )
return 0; /* In an EMU we can't write to high mem but
we'll pretend we can for debuggering */
@@ -539,7 +591,7 @@ static char * image_str = "BOOT_IMAGE=";
#ifdef __ELKS__
fprintf(stderr, "Command line: '%s'\n", ptr+1);
#else
-/*
+/* Commented to allow for CRC check.
__set_es(0x9000);
__doke_es(0x0020, 0xA33F);
__doke_es(0x0022, COMMAND_LINE_POS);
@@ -637,29 +689,20 @@ unsigned int k_top;
}
printf("Loaded, ");
- /* Tell the kernel where it is */
- {
- long tmp = ((long)rd_start << 8);
-
- __set_es(0x9000);
- __doke_es(0x218, (unsigned) tmp);
- __doke_es(0x21A, (unsigned)(tmp>>16));
-
- __doke_es(0x21C, (unsigned) file_len);
- __doke_es(0x21E, (unsigned)(file_len>>16));
- }
+ initrd_start = ((long) rd_start <<8);
+ initrd_length = file_len;
return 0;
}
+#ifdef CALC_CRC
check_crc()
{
char buffer[512];
int low_sects;
unsigned int address = 0x900;
long len;
-
- if( !is_zimage ) return;
+ int re_crc;
reset_crc();
@@ -668,8 +711,16 @@ check_crc()
for(len=image_size; len>0; len-=512)
{
- if( address >= 0xA00 ) return;
- __movedata(address*16, 0, __get_ds(), buffer, 512);
+ if( address >= 0xA00 )
+ {
+ if( ext_get(address, buffer, 512) != 0 )
+ {
+ printf("Unable to read back for CRC check\n");
+ return;
+ }
+ }
+ else
+ __movedata(address*16, 0, __get_ds(), buffer, 512);
if( len > 512 ) addcrc(buffer, 512); else addcrc(buffer, (int)len);
@@ -679,10 +730,34 @@ check_crc()
low_sects--;
if( low_sects == 0 )
{
+#if ZIMAGE_LOAD_SEG != 0x10000
if( is_zimage ) address = ZIMAGE_LOAD_SEG/16;
- else address = 0x1000;
+ else
+#endif
+ address = 0x1000;
}
}
}
- display_crc();
+ re_crc = display_crc("Images CRC check value =");
+
+ if( re_crc != load_crc )
+ {
+ printf("Error: CRC doesn't match value written to memory!\n");
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+#if ZIMAGE_LOAD_SEG == 0x10000
+start_zimage()
+{
+#include "zimage.v"
+ __movedata(__get_ds(), zimage_data, 0, zimage_start, zimage_size);
+ {
+#asm
+ callf zimage_start,0
+#endasm
+ }
}
+#endif
diff --git a/bootblocks/crc.c b/bootblocks/crc.c
new file mode 100644
index 0000000..88c43a5
--- /dev/null
+++ b/bootblocks/crc.c
@@ -0,0 +1,216 @@
+
+#include <stdio.h>
+
+/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
+static unsigned short crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
+ * NOTE: First srgument must be in range 0 to 255.
+ * Second argument is referenced twice.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ */
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+/*
+ * Copyright (C) 1986 Gary S. Brown. You may use this program, or
+ * code or tables extracted from it, as desired without restriction.
+ */
+
+/* First, the polynomial itself and its table of feedback terms. The */
+/* polynomial is */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in */
+/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
+/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
+/* the MSB being 1. */
+
+/* Note that the usual hardware shift register implementation, which */
+/* is what we're using (we're merely optimizing it by doing eight-bit */
+/* chunks at a time) shifts bits into the lowest-order term. In our */
+/* implementation, that means shifting towards the right. Why do we */
+/* do it this way? Because the calculated CRC must be transmitted in */
+/* order from highest-order term to lowest-order term. UARTs transmit */
+/* characters in order from LSB to MSB. By storing the CRC this way, */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part. Reception works similarly. */
+
+/* The feedback terms table consists of 256, 32-bit entries. Notes: */
+/* */
+/* The table can be generated at runtime if desired; code to do so */
+/* is shown later. It might not be obvious, but the feedback */
+/* terms simply represent the results of eight shift/xor opera- */
+/* tions for all combinations of data and CRC register values. */
+/* */
+/* The values must be right-shifted by eight bits by the "updcrc" */
+/* logic; the shift must be unsigned (bring in zeroes). On some */
+/* hardware you could probably optimize the shift in assembler by */
+/* using byte-swap instructions. */
+
+static long cr3tab[] = { /* CRC polynomial 0xedb88320 */
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
+
+int skip = 0;
+int do_16 = 0;
+int do_hex = 0;
+
+main(argc, argv)
+int argc;
+char ** argv;
+{
+ int ar;
+ int done = 0;
+ for(ar=1; ar<argc; ar++) if( argv[ar][0] == '-' )
+ {
+ switch(argv[ar][1])
+ {
+ case 's': do_16 = 1; break;
+ case 't': do_16 = 0; break;
+ case 'h': do_hex = 1; break;
+ default:
+ fprintf(stderr, "Usage: %s -sth +skip files\n", argv[0]);
+ exit(1);
+ }
+ }
+ else if( argv[ar][0] == '+' )
+ {
+ skip = atoi(argv[ar]+1);
+ }
+ else
+ {
+ do_crc(argv[ar]);
+ done++;
+ }
+ if( done == 0 )
+ {
+ fprintf(stderr, "Usage: %s -sth +skip files\n", argv[0]);
+ exit(1);
+ }
+ exit(0);
+}
+
+do_crc(fname)
+char * fname;
+{
+ FILE * fd;
+ unsigned short crc = 0;
+ long crc32 = -1;
+ int ch;
+ long count = 0;
+
+ fd = fopen(fname, "r");
+ if( fd == 0 )
+ {
+ printf("%s:\tCannot open\n", fname);
+ exit(1);
+ }
+
+ while((ch=getc(fd)) != EOF)
+ {
+ if( count >= skip )
+ {
+ crc = updcrc(ch, crc);
+ crc32 = UPDC32(ch, crc32);
+ }
+ count++;
+ }
+ fclose(fd);
+ crc32 ^= 0xFFFFFFFF;
+
+ printf("%-14s: %6ld CRC32=0x%08lx (%10lu)", fname, count, crc32, crc32);
+ printf(" CRC16=0x%04lx (%5u)\n", crc, crc);
+
+/*
+ if(do_hex)
+ {
+ if(do_16)
+ printf("%-14s:\t%6ld %04x\n", fname, count, crc);
+ else
+ printf("%-14s:\t%6ld %08lx\n", fname, count, crc32);
+ }
+ else
+ {
+ if(do_16)
+ printf("%-14s:\t%6ld %5u\n", fname, count, crc);
+ else
+ printf("%-14s:\t%6ld %10lu\n", fname, count, crc32);
+ }
+*/
+ fflush(stdout);
+}
+
diff --git a/bootblocks/fs.c b/bootblocks/fs.c
index 64a3783..ee81c55 100644
--- a/bootblocks/fs.c
+++ b/bootblocks/fs.c
@@ -36,7 +36,7 @@ rewind_file()
close_file()
{
- int rv;
+ int rv = -1;
#ifdef __ELKS__
fprintf(stderr, "Close file (%d)\n", fs_type);
#endif
@@ -47,7 +47,7 @@ close_file()
case 3: rv = dos_close_file(); break;
}
fs_type = 0;
- return -1;
+ return rv;
}
long
diff --git a/bootblocks/fs_tar.c b/bootblocks/fs_tar.c
index 278c8c1..2a30ee2 100644
--- a/bootblocks/fs_tar.c
+++ b/bootblocks/fs_tar.c
@@ -1,8 +1,5 @@
-#ifdef __ELKS__
#include <stdio.h>
-#endif
-
#include <dos.h>
#include "readfs.h"
@@ -22,17 +19,44 @@ typedef union {
char m_checksum[8];
char m_linked;
char m_link[NAME_SIZE];
+ char m_ustar[8];
+ char m_uname[32];
+ char m_gname[32];
+
+ char m_major[8]; /* GNU fields */
+ char m_minor[8];
+ char m_atime[12];
+ char m_ctime[12];
+ char m_offset[12];
+ /* An so forth */
} member;
} HEADER;
+long tar_convert();
+int valid_tar_checksum();
+void tar_set_drive();
+
+static int disk_size = 0;
+
#ifdef __STANDALONE__
extern union REGS __argr;
#endif
+struct tx {
+ char name[NAME_SIZE];
+ int first_sectno;
+ int cur_sectno;
+ int sectcount;
+ int diskoffset;
+ long file_length;
+} tar_status;
+
tar_open_file(fname)
char * fname;
{
HEADER * sptr;
+ int dodir = 0;
+ int sectno;
#ifdef __STANDALONE__
if( disk_drive != __argr.h.dl ) return -1; /* Only the one booted off */
@@ -41,43 +65,154 @@ char * fname;
sptr = read_sector(0);
- /* Boot sector a volume label ? */
- if( sptr->member.m_linked != 'V' ) return -1;
+ /* Is it a tar disk ? */
if( !valid_tar_checksum(sptr) ) return -1;
-#ifdef __STANDALONE__
- disk_spt = __argr.x.si;
-#else
- disk_spt = 18; /* Testing only */
-#endif
+ tar_set_drive();
-#ifdef __ELKS__
- fprintf(stderr, "Got vaild tar header\n");
-#endif
+ if( strcmp(fname, ".") == 0 )
+ dodir=1;
+ else
+ {
+ if( tar_status.diskoffset == 0 && strcmp(fname, tar_status.name) == 0 )
+ return tar_rewind_file();
+ }
+
+ tar_close_file();
+
+ for(sectno=0;;)
+ {
+ long fl, v;
+
+ if(sectno) sptr = read_sector(sectno);
+ if(!sptr || !*sptr->member.m_name) break;
+
+ if( !valid_tar_checksum(sptr) )
+ {
+ printf("Checksum error on tar header\n");
+ return -1;
+ }
+
+ fl = tar_convert(sptr->member.m_size, 12);
+ v = (fl+511)/512 + 1;
+
+ if( sptr->member.m_linked != 0 && sptr->member.m_linked != '0' )
+ ;
+ else if( dodir )
+ printf("%s %d tape blocks\n", sptr->member.m_name, (int)v-1);
+ else if( strcmp(fname, sptr->member.m_name, NAME_SIZE) == 0 )
+ {
+ strncpy(tar_status.name, sptr->member.m_name, NAME_SIZE);
+ tar_status.first_sectno = sectno+1;
+ tar_status.cur_sectno = sectno+1;
+ tar_status.file_length = fl;
+ tar_status.sectcount = v-1;
+ tar_status.diskoffset = 0;
+ return 0;
+ }
+
+ if( v < 1 || (sectno += v) > disk_size ) break;
+ }
return -1;
}
tar_rewind_file()
{
- return -1;
+ if( tar_status.name[0] == '\0' || tar_status.diskoffset != 0 )
+ {
+ tar_close_file();
+ return -1;
+ }
+
+ tar_status.cur_sectno = tar_status.first_sectno;
+ return 0;
}
tar_close_file()
{
- return -1;
+ tar_status.name[0] = 0;
+ tar_status.first_sectno = -1;
+ tar_status.cur_sectno = -1;
+ tar_status.file_length = -1;
+ tar_status.diskoffset = -1;
+
+ return 0;
}
long
tar_file_length()
{
- return -1;
+ if( tar_status.name[0] == '\0' ) return -1;
+
+ return tar_status.file_length;
}
tar_read_block(buffer)
char * buffer;
{
- return -1;
+ char * ptr;
+ HEADER * sptr;
+ int i;
+ if( tar_status.name[0] == '\0' ) return -1;
+
+ for(i=0; i<2; i++)
+ {
+ if( tar_status.cur_sectno - tar_status.first_sectno >= tar_status.sectcount )
+ {
+ memset(buffer, '\0', 512);
+ }
+ else
+ {
+ if( tar_status.cur_sectno >= tar_status.diskoffset+disk_size )
+ {
+ int k;
+ tar_status.diskoffset += disk_size-2;
+
+ for(;;)
+ {
+ printf("Please insert next disk and press return:");
+ fflush(stdout);
+ while( (k=(bios_getc() & 0x7F)) != '\r' && k != '\n')
+ if( k == 27 || k == 3 )
+ {
+ printf("... Aborting\n");
+ return -1;
+ }
+ printf("\n");
+
+ sptr = read_sector(0);
+ if( !valid_tar_checksum(sptr) )
+ {
+ printf("Checksum failed reading volume label\n");
+ continue;
+ }
+ tar_set_drive();
+ sptr = read_sector(1);
+ if( !valid_tar_checksum(sptr)
+ || sptr->member.m_linked != 'M'
+ || 512*(long)(tar_status.cur_sectno-tar_status.first_sectno)
+ != tar_convert(sptr->member.m_offset, 12)
+ )
+ {
+ printf("Wrong disk inserted, ");
+ continue;
+ }
+ break;
+ }
+ ptr = read_sector(tar_status.cur_sectno-tar_status.diskoffset);
+ }
+ else
+ ptr = read_sector(tar_status.cur_sectno-tar_status.diskoffset);
+ if( ptr == 0 ) return -1;
+
+ memcpy(buffer, ptr, 512);
+ }
+ buffer+=512;
+ tar_status.cur_sectno++;
+ }
+
+ return 0;
}
long
@@ -117,6 +252,27 @@ HEADER * sptr;
return ac == 0;
}
+void
+tar_set_drive()
+{
+#ifdef __STANDALONE__
+ disk_spt = __argr.x.si;
+
+ /* Choose some formats, note Boot block only sees a few SPT.
+ * 9x40=360k, 15x80=1200k, 18x80=1440k, 21x82=1722k, 36x80=2880k
+ */
+ if( disk_spt <= 9 ) disk_cyls = 40;
+ if( disk_spt == 21 || disk_spt > 36 ) disk_cyls = 82;
+ else disk_cyls = 80;
+#else
+ disk_spt = 18; /* Testing only */
+ disk_cyls= 80;
+#endif
+ disk_heads=2;
+
+ disk_size = disk_spt*disk_cyls*disk_heads;
+}
+
#if 0
#asm
diff --git a/bootblocks/i86_funcs.c b/bootblocks/i86_funcs.c
index b9ea180..90fbbbc 100644
--- a/bootblocks/i86_funcs.c
+++ b/bootblocks/i86_funcs.c
@@ -151,6 +151,7 @@ static struct {
unsigned short dst_len;
long dst_seg;
unsigned short dpad;
+ char gdt4[8];
char gdt5[8];
} GDT = {
"","",
diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c
index b844ba8..53b5a82 100644
--- a/bootblocks/makeboot.c
+++ b/bootblocks/makeboot.c
@@ -10,8 +10,9 @@
#include "tarboot.v"
#include "minix.v"
#include "minixhd.v"
+#include "mbr.v"
-char buffer[1024];
+unsigned char buffer[1024];
#define FS_NONE 0 /* Bootsector is complete */
#define FS_ADOS 1 /* Bootsector needs 'normal' DOS FS */
@@ -19,6 +20,7 @@ char buffer[1024];
#define FS_TAR 3 /* Bootsector needs GNU-tar volume label */
#define FS_STAT 4 /* DOS bootsector is checked */
#define FS_ZERO 5 /* Boot sector must be Zapped */
+#define FS_MBR 6 /* Boot sector is an MBR */
struct bblist {
char * name;
@@ -33,6 +35,7 @@ struct bblist {
{ "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},
@@ -99,6 +102,9 @@ char ** argv;
case FS_ZERO:
check_zapped();
break;
+ case FS_MBR:
+ check_mbr();
+ break;
default:
fprintf(stderr, "Program error, unknown filesystem requirement\n");
@@ -125,6 +131,10 @@ char ** argv;
copy_tarblock();
break;
+ case FS_MBR:
+ copy_mbr(ptr->data);
+ break;
+
case FS_NONE:
if( ptr->data )
memcpy(buffer, ptr->data, 512);
@@ -158,9 +168,9 @@ Usage()
progname = "makeboot";
#ifdef __MSDOS__
- fprintf(stderr, "Usage: %s bootname a:\n", progname);
+ fprintf(stderr, "Usage: %s [-f] bootname a:\n", progname);
#else
- fprintf(stderr, "Usage: %s bootname /dev/fd0\n", progname);
+ fprintf(stderr, "Usage: %s [-f] bootname /dev/fd0\n", progname);
#endif
fprintf(stderr, "Blocks\n");
for(;ptr->name; ptr++)
@@ -386,7 +396,8 @@ char *s;
check_tar()
{
- char vbuf[100], *p;
+ char vbuf[100];
+ unsigned char *p;
unsigned int csum = 0;
long osum = -1;
@@ -429,7 +440,7 @@ not_zapped:
copy_tarblock()
{
char lbuf[20];
- char * p;
+ unsigned char * p;
unsigned int csum = 0;
int i;
@@ -687,6 +698,41 @@ check_simpledos()
if(!force) exit(2);
}
+check_mbr()
+{
+ int i = 0;
+
+ if( buffer[510] == 0x55 && buffer[511] == 0xAA )
+ i = 512;
+
+ for(; i<512; i++)
+ if( buffer[i] )
+ break;
+
+ if( i != 512 )
+ {
+ if(force)
+ fprintf(stderr, "That doesn't look like an MBR zapping\n");
+ else
+ {
+ fprintf(stderr, "That doesn't look like an MBR, -f will zap\n");
+ exit(1);
+ }
+
+ memset(buffer, '\0', 512);
+ }
+}
+
+copy_mbr(mbr_data)
+char * mbr_data;
+{
+ if( buffer[252] != 0xAA || buffer[253] != 0x55 )
+ memcpy(buffer, mbr_data, 446);
+ else
+ memcpy(buffer, mbr_data, 254);
+ memcpy(buffer+510, mbr_data+510, 2);
+}
+
/**************************************************************************/
char boot_sector_2m_23_82[] = {
@@ -926,15 +972,27 @@ char program_2m_vsn_20[] = {
do_2m_write()
{
int i;
- if( !force && ( disk_trck != 82 || disk_sect != 22 ))
- {
- fprintf(stderr, "A bootable 2M disk must be 22 sectors 82 tracks\n");
+
+ if( read_sector(bs_offset+1, buffer+512) != 0 )
exit(1);
+
+ if( memcmp(buffer+512, program_2m_vsn_20, 16) == 0 )
+ {
+ /* Seems to be properly formatted already */
+
+ write_sector(bs_offset, buffer);
+ return;
+ }
+ else if( disk_trck != 82 || disk_sect != 22 )
+ {
+ fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with 2m20.\n");
+ if( !force ) exit(1);
+ fprintf(stderr, "But I'll try it\n");
}
write_sector(bs_offset, buffer);
/* This needs to be altered to allow for the disk format description to
- be cpied from the old boot sector */
+ be copied from the old boot sector */
for(i=0; i<sysboot_dosfs_stat; i++)
buffer[i] = boot_sector_2m_22_82[i];
diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s
index ddd406f..c0fa542 100644
--- a/bootblocks/mbr.s
+++ b/bootblocks/mbr.s
@@ -5,10 +5,16 @@
! In addition it has the facility to load and execute a small program
! (of 8 extents) before the boot blocks are checked.
!
+! Or
+!
+! Space for 12 extra partitions in a form that Linux _does_ understand.
+!
! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why?
ORGADDR=$0500
-preboot=0 ! Include the pre-boot loader ?
+preboot=0 ! Include the pre-boot loader.
+diskman=1 ! Disk manager partitions, allows 16 partitions but
+ ! don't overwrite this with a LILO BB.
! Include standard layout
org ORGADDR
@@ -19,11 +25,15 @@ public partition_2
public partition_3
public partition_4
+ if diskman=0
org ORGADDR+$3
.ascii "ELKS MBR Copyright 1996, Robert de Bath"
! Start after dos fsstat data, not strictly required.
org codestart
+ else
+org ORGADDR
+ endif
cli ! Assume _nothing_!
cld
mov bx,#$7C00 ! Pointer to start of BB.
@@ -80,6 +90,21 @@ bad_boot:
cmp si,#bootblock_magic
jnz check_active
+ # Check for Disk manager partitions (12 more!)
+ if diskman
+ cmp word ptr diskman_magic,#$55AA
+ jnz no_diskman
+ mov si,#partition_1
+check_next:
+ sub si,#partition_2-partition_1
+ cmp byte [si],#$80 ! Flag for activated partition
+ jz found_active
+ cmp si,#low_partition
+ jnz check_next
+
+no_diskman:
+ endif
+
mov si,#no_bootpart ! Message & boot
jmp no_boot
@@ -154,6 +179,42 @@ pre_boot_table:
.word 0
endif
+ if diskman
+ if *>ORGADDR+0xfc
+ fail! Disk manager partition overlap
+ endif
+
+ org ORGADDR+0xFC
+public diskman_magic
+diskman_magic:
+ .word $55AA
+low_partition:
+public partition_16
+partition_16 = low_partition+0x00
+public partition_15
+partition_15 = low_partition+0x10
+public partition_14
+partition_14 = low_partition+0x20
+public partition_13
+partition_13 = low_partition+0x30
+public partition_12
+partition_12 = low_partition+0x40
+public partition_11
+partition_11 = low_partition+0x50
+public partition_10
+partition_10 = low_partition+0x60
+public partition_9
+partition_9 = low_partition+0x70
+public partition_8
+partition_8 = low_partition+0x80
+public partition_7
+partition_7 = low_partition+0x90
+public partition_6
+partition_6 = low_partition+0xA0
+public partition_5
+partition_5 = low_partition+0xB0
+ endif
+
! Now make sure this isn't to big!
if *>partition_1
fail! Partition overlap
diff --git a/bootblocks/minix.c b/bootblocks/minix.c
index b254ab0..22795ef 100644
--- a/bootblocks/minix.c
+++ b/bootblocks/minix.c
@@ -2,7 +2,7 @@
* This bootblock loads the linux-8086 executable in the file 'boot'
* from the root directory of a minix filesystem.
*
- * Copyright (C) 1990-1997 Robert de Bath, distributed under the GPL Version 2
+ * Copyright (C) 1990-1998 Robert de Bath, distributed under the GPL Version 2
* Based on minix filesystem definitions.
*/
@@ -13,41 +13,14 @@
/* #define HARDDISK /* Define for hard disk version */
/* #define TRY_FLOPPY /* To do trial reads to find floppy size */
-/* These two are just too big! */
-/* Also they have the problem that they can't load an odd number of
- sectors into the setup area.
- */
-/* #define ELKS_SETUP /* Assume first SETUPSIZE bytes for SETUPSEG */
-/* #define IMAGE_MAGIC /* Check for elks Image magic nos. */
-
-#ifdef IMAGE_MAGIC
-#define MIN_SPACE
-#endif
+/* #define MIN_SPACE */
-#define zone_shift 0 /* for any < 32M (non-zero not supported yet) */
+#define zone_shift 0 /* for any < 32M (!= 0 not supported yet, if ever) */
#define seg_at(k) ((k)*64)
#define seg_of(p) ((unsigned int)p >>4)
#define BOOTSEG (0x07c0)
#define LOADSEG (0x1000)
-
-#ifdef ELKS_SETUP
-/* Can't do this .. SETUPSEGSIZE isn't in there! */
-/*
- * #include <linuxmt/config.h>
- * #define SETUPSEG (DEF_SETUPSEG)
- * #define SETUPSIZE (DEF_SETUPSIZE)
- * #define ORGADDR (SETUPSEG*16+SETUPSEGSIZE)
- */
-#define SETUPSEG (0x0120)
-#define SETUPSIZE (4*512)
-#define ORGADDR (0x0500)
-#else
#define ORGADDR (0x0500)
-#endif
-
-#ifdef IMAGE_MAGIC
-#define SETUPSEG (0x0120)
-#endif
#ifdef HARDDISK
#define get_now()
@@ -78,12 +51,37 @@ start:
#ifndef MIN_SPACE
include sysboot.s
+org start ! The lowest available address, again.
+ j skip_vars
+
org dos_sysid
.ascii "MINIXFS BOOT (C) 1990-1997, Robert de Bath"
org codestart
#endif
+! A few variables we need to know the positions of for patching, so export
+! them and as86_encaps will make some variables. Put them here at the start
+! so they're in the same place for both Floppy and harddisk versions as they
+! will be used by helper programs.
+
+export inode ! Inode to search
+inode:
+_inode: .word 1 ! ROOT_INODE
+
+#ifndef MIN_SPACE
+export dinode ! Inode of directory file was found in.
+dinode:
+_dinode: .word 1 ! ROOT_INODE
+#endif
+
+export bootfile ! File to boot, make this whatever you like,
+bootfile: ! 'boot' is good too.
+_bootfile:
+ .ascii "boot"
+ .byte 0,0,0,0,0,0,0,0,0,0
+
+skip_vars:
#ifdef HARDDISK
mov bx,[si+8] ! Fetch the linear address of part from DS:SI
mov dh,[si+10] ! DL is drive number
@@ -136,6 +134,7 @@ loopy:
/* The name of the file and inode to start */
extern char bootfile[];
extern inode_nr inode;
+extern inode_nr dinode;
/* For multi-sector reads */
extern sect_nr lastsect;
@@ -160,12 +159,6 @@ extern unsigned flength;
extern unsigned n_sectors;
#endif
-#ifdef IMAGE_MAGIC
-extern unsigned checkflg;
-extern unsigned aout_flg;
-extern unsigned segend;
-#endif
-
extern struct super_block b_super;
extern d_inode b_inode[INODES_PER_BLOCK];
extern zone_nr b_zone[NR_INDIRECTS];
@@ -177,18 +170,7 @@ extern dir_struct directory[];
/****************************************************************************/
#asm
-! A few variables we need to know the positions of for patching, so export
-! them and as86_encaps will make some variables.
.text
-export inode ! Inode to search
-inode:
-_inode: .word 1 ! ROOT_INODE
-
-export bootfile ! File to boot, make this whatever you like,
-bootfile: ! 'boot' is good too.
-_bootfile:
- .ascii "boot"
- .byte 0,0,0,0,0,0,0,0,0,0
#ifdef HARDDISK
bootpart: .long 0
@@ -201,8 +183,17 @@ _lastsect: .word 0
block start+0x400
_b_super: .blkb 1024
+
+#ifndef MIN_SPACE
+export helper
+helper: .blkb 1024
+export helper_end
+helper_end:
+#endif
+
_b_inode: .blkb 1024
_b_zone: .blkb 1024
+
#ifdef MIN_SPACE
temp_space: .blkb 512
#endif
@@ -239,7 +230,7 @@ min_eos: ! Wait for a key then reboot
fail_fs:
.byte 13,10
-#if defined(HARDDISK) && !defined(IMAGE_MAGIC)
+#if defined(HARDDISK)
.asciz "Initial boot failed, press return to reboot\r\n"
#else
.asciz "Boot failed:"
@@ -605,13 +596,20 @@ zero_block(address)
_load_block:
push bp
mov bp,sp
+#if __FIRST_ARG_IN_AX__
+ ! Fetch load location
+ mov es,ax
+ ! Test for block zero
+ mov ax,4[bp]
+#else
! Fetch load location
mov ax,[bp+4]
mov es,ax
! Test for block zero
mov ax,6[bp]
+#endif
test ax,ax
jne real_block
@@ -631,7 +629,9 @@ func_exit:
real_block:
#ifdef DOTS
+ push ax
call _prt_dot
+ pop ax
#endif
! Load a real block.
@@ -660,47 +660,6 @@ code:
#endasm
/****************************************************************************/
-/* Section prog_magic */
-/****************************************************************************/
-
-#ifdef IMAGE_MAGIC
-#asm
-; mfetch(0) != 0x301 && mfetch(486) == 'E'+'L'*256 && mfetch(488) == 'K'+'S'*256 )
-.text
-export _mcheck
-_mcheck:
- mov ax,#LOADSEG
- mov es,ax
- xor ax,ax
- mov bx,ax
- cmp [bx],#0x301
- jz doret
- cmp [bx+486],#'E+'L*256
- jnz doret
- cmp [bx+488],#'K+'S*256
- jnz doret
- inc ax
-doret:
- ret
-
-.text
-export _mfetch
-_mfetch:
-#if __FIRST_ARG_IN_AX__
- mov bx,ax
-#else
- mov bx,sp
- mov bx,2[bx]
-#endif
- mov ax,#LOADSEG
- mov es,ax
- seg es
- mov ax,[bx]
- ret
-#endasm
-#endif
-
-/****************************************************************************/
/* Section prt_dots */
/****************************************************************************/
#ifdef DOTS
@@ -721,34 +680,6 @@ outch:
#endif
/****************************************************************************/
-/* Section bbcopy */
-/****************************************************************************/
-#ifdef IMAGE_MAGIC
-bbcopy()
-{
-#asm
- push ds
-
- mov ax,_ldaddr
- sub ax,#512/16
- mov es,ax
-
- mov ax,#LOADSEG
- mov ds,ax
-
- xor di,di
- xor si,si
- mov cx,#$100
-
- rep
- movsw
-
- pop ds
-#endasm
-}
-#endif
-
-/****************************************************************************/
/* Section end_1 */
/****************************************************************************/
#if defined(HARDDISK) || !defined(MIN_SPACE)
@@ -769,13 +700,19 @@ end_of_part1:
/* Section prog_load */
/****************************************************************************/
-static
loadprog()
{
#ifdef DOTS
prt_dot();
#endif
if( b_super.s_magic != SUPER_MAGIC ) nogood();
+
+#ifdef zone_shift
+ if( zone_shift != b_super.s_log_zone_size) nogood();
+#else
+ zone_shift = b_super.s_log_zone_size;
+#endif
+
#ifndef HARDDISK
#ifdef TRY_FLOPPY
probe_sectors();
@@ -787,12 +724,6 @@ loadprog()
#endif
try_again:;
-#ifdef zone_shift
- if( zone_shift != b_super.s_log_zone_size) nogood();
-#else
- zone_shift = b_super.s_log_zone_size;
-#endif
-
inode--;
load_block(seg_of(b_inode), inode/INODES_PER_BLOCK
+ b_super.s_imap_blocks
@@ -800,14 +731,7 @@ try_again:;
+ 2);
get_now();
-#ifndef ELKS_SETUP
ldaddr = LOADSEG; /* Load at 64k mark */
-#else
- ldaddr = SETUPSEG; /* Load where ELKS setup expects to be */
-#endif
-#ifdef IMAGE_MAGIC
- aout_flg = checkflg = 1;
-#endif
{
register d_inode * i_ptr;
@@ -817,6 +741,9 @@ try_again:;
if( (i_ptr->i_mode & I_TYPE) == I_DIRECTORY )
{
ldaddr = seg_of(directory);
+#ifndef MIN_SPACE
+ dinode = inode+1; /* Remember current directory */
+#endif
inode = 0; /* Mark - we've no _file_ inode yet */
}
}
@@ -841,24 +768,6 @@ try_again:;
load_zone(ldaddr, *next_zone);
next_zone++;
ldaddr += (seg_at(1) << zone_shift);
-#ifdef ELKS_SETUP
- /* finished with setup segment? */
- if (ldaddr == (SETUPSEG+seg_of(SETUPSIZE))) ldaddr = LOADSEG;
-#endif
-#ifdef IMAGE_MAGIC
- if (inode && checkflg)
- {
- get_now();
- checkflg=0;
- if( mcheck() )
- {
- segend = (ldaddr = mfetch(495)) + mfetch(497)*(512/16);
- aout_flg = 0;
- bbcopy();
- }
- }
- if (ldaddr == segend) ldaddr = LOADSEG;
-#endif
}
get_now();
@@ -867,9 +776,6 @@ try_again:;
#endif
if(!inode)
{
-#ifdef DOTS
- prt_dot();
-#endif
dirptr = directory;
while(flength > 0)
{
@@ -921,21 +827,6 @@ runprog()
mov si,[_n_sectors] ! Save for monitor.out
#endif
-#ifdef ELKS_SETUP
- mov bx,#SETUPSEG
- mov ds,bx ! DS = execute address
- xor di,di
-#else
-#ifdef IMAGE_MAGIC
- mov ax,[_aout_flg]
- test ax,ax
- jnz load_aout
- mov ds,bx ! DS = execute address
- xor di,di
- j binfile
- mov bx,#SETUPSEG
-load_aout:
-#endif
mov bx,#LOADSEG
mov ds,bx ! DS = loadaddress
xor di,di ! Zero
@@ -957,7 +848,6 @@ impure:
mov sp,[di+24] ! Chmem value
mov ds,ax
binfile:
-#endif
push bx
push di ! jmpi 0,#LOADSEG+2
@@ -1007,11 +897,6 @@ _indirect: .blkw 1
_ldaddr: .blkw 1
_dirptr: .blkw 1
_flength: .blkw 1
-#ifdef IMAGE_MAGIC
-_checkflg: .blkw 1
-_aout_flg: .blkw 1
-_segend: .blkw 1
-#endif
varend:
#ifdef MIN_SPACE
endb
diff --git a/bootblocks/minix_elks.c b/bootblocks/minix_elks.c
new file mode 100644
index 0000000..8cce8e5
--- /dev/null
+++ b/bootblocks/minix_elks.c
@@ -0,0 +1,152 @@
+
+#define __ASSEMBLY__
+
+#asm
+#include "minix.v"
+
+! Must match minix.c ...
+#define LOADSEG (0x1000)
+
+! Must match ELKS
+#define ELKS_INITSEG (0x0100)
+#define ELKS_SYSSEG (0x1000)
+
+org minix_helper
+
+ push cs
+ pop ds
+ xor ax,ax
+ mov es,ax
+ mov ss,ax
+ mov sp,ax
+
+ mov cx,#$200 ! Move 512 words
+ mov si,ax ! Current load address.
+ mov di,#minix_helper ! To the correct address.
+ rep
+ movsw
+
+ mov ds,ax
+ jmpi code,0
+
+msg_p2:
+ .asciz "\r\nLoading ELKS kernel\r\n"
+
+msg_p3:
+ .asciz "Starting ...\r\n"
+
+aint_elks:
+ .asciz "Not an ELKS image!"
+
+elks_name:
+ .asciz "linux"
+ .byte 0,0,0,0,0,0,0,0,0
+
+dispmsg: ! SI now has pointer to a message
+ lodsb
+ cmp al,#0
+ jz EOS
+ mov bx,#7
+ mov ah,#$E ! Can't use $13 cause that's AT+ only!
+ int $10
+ jmp dispmsg
+EOS:
+ ret
+
+code:
+ mov si,#msg_p2
+ call dispmsg
+
+ mov ax,minix_dinode ! In the same directory.
+ mov minix_inode,ax
+
+ mov cx,#14
+ mov si,#elks_name
+ mov di,#minix_bootfile
+ rep
+ movsb
+
+ call minix__loadprog
+ ! Ok, now loaded "boot/linux" (or so)
+ mov si,#msg_p3
+ call dispmsg
+
+ call kill_motor ! For kernels without a floppy driver.
+!
+ mov ax,#LOADSEG
+ mov ds,ax
+
+ mov ax,$1E6 ! Check for ELKS magic number
+ cmp ax,#$4C45
+ jnz not_elks
+ mov ax,$1E8
+ cmp ax,#$534B
+ jz boot_it
+not_elks:
+ xor ax,ax
+ mov ds,ax
+ mov si,#aint_elks
+ call dispmsg
+ xor ax,ax
+ int $16
+ jmpi $0,$FFFF
+
+boot_it:
+ mov ax,#ELKS_INITSEG
+ mov es,ax
+
+ mov bl,497 ! Fetch number of setup sects.
+ xor bh,bh
+ inc bx
+ mov ax,500 ! Fetch system size
+ mov cl,#5
+ add ax,#31
+ shr ax,cl
+ mov dx,ax
+
+looping: ! Put the setup where it belongs
+ call copy_sect
+ dec bx
+ jnz looping
+
+ mov ax,#ELKS_SYSSEG
+ mov es,ax
+
+looping2: ! Put the body code in the right place.
+ call copy_sect
+ dec dx
+ jnz looping2
+
+ ! Ok, everything should be where it belongs call it.
+ mov ax,#ELKS_INITSEG
+ mov ds,ax
+ mov es,ax
+ mov ss,ax
+ mov sp,#0x4000-12
+ jmpi 0,ELKS_INITSEG+$20
+
+copy_sect:
+ mov cx,#256
+ xor si,si
+ xor di,di
+ rep
+ movsw
+
+ mov ax,ds
+ add ax,#32
+ mov ds,ax
+ mov ax,es
+ add ax,#32
+ mov es,ax
+ ret
+
+kill_motor:
+ push dx
+ mov dx,#0x3f2
+ xor al, al
+ outb
+ pop dx
+ ret
+
+#endasm
+
diff --git a/bootblocks/monitor.c b/bootblocks/monitor.c
index 084f301..4b7b75c 100644
--- a/bootblocks/monitor.c
+++ b/bootblocks/monitor.c
@@ -55,7 +55,7 @@ static char minibuf[2] = " ";
relocator(-1);
relocator(1);
if( __get_ds() > 0x1000 ) relocator(2);
- printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
+ printf("Relocated to CS=$%04x DS=$%04x\n", __get_cs(), __get_ds());
}
#ifdef __STANDALONE__
@@ -66,8 +66,10 @@ static char minibuf[2] = " ";
if( x86 > 2 && !x86_emu ) /* Check some basics */
cmd_bzimage((void*)0);
+#if 0
else
printf("System is not an 80386 compatible in real mode, load aborted.\nUse 'bzimage' command to attempt load.\n");
+#endif
}
for (;;)
@@ -319,7 +321,7 @@ char * ptr;
{
printf("%04x:%04x:", es, current_address);
for(j=0; j<16; j++)
- printf(" %02x", rmem(j));
+ printf(" %s%02x", (j==8)?" ":"", rmem(j));
printf(" ");
for(j=0; j<16; j++)
if( rmem(j) >= ' ' && rmem(j) <= '~' )
@@ -383,9 +385,9 @@ char * ptr;
relocator(nseg);
if( __get_cs() == cs )
- printf("Didn't relocate; CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
+ printf("Didn't relocate; CS=$%04x DS=$%04x\n", __get_cs(), __get_ds());
else
- printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
+ printf("Relocated to CS=$%04x DS=$%04x\n", __get_cs(), __get_ds());
}
int cmd_dir(ptr)
@@ -465,6 +467,7 @@ struct t_cmd_list cmd_list[] =
{"#", cmd_nop},
{"help", cmd_help}, /* Display from help.txt */
{"?", cmd_help}, /* Display from help.txt */
+ {"zimage", cmd_bzimage}, /* Load and run 386 zimage file */
{"bzimage",cmd_bzimage}, /* Load and run 386 bzimage file */
{"=", cmd_bzimage}, /* Load and run 386 bzimage file */
{"dir", cmd_dir}, /* Display directory */
@@ -495,7 +498,6 @@ struct t_cmd_list cmd_list[] =
{"load", cmd_load}, Load file of inode
{"stat", cmd_stat}, Stat info of inode
- {"zimage", cmd_zimage}, Load and run 386 zimage file
{"image", cmd_image}, Load and run 8086 image file
{"read", cmd_read}, Read sector
diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s
index a48718c..72e2a11 100644
--- a/bootblocks/msdos.s
+++ b/bootblocks/msdos.s
@@ -68,28 +68,6 @@ cont:
! DONT Need to fix BPB for fd0 to correct sectors (Like linux bootblock does)
! as we only ever read one sector at a time.
-! mov di,#bios_disk
-! mov bp,#0x78
-!! 0:bx is parameter table address
-! push ds
-! lds si,[bp]
-!
-!! ds:si is source
-!
-! mov cx,#6
-!! copy 12 bytes
-! push di
-! rep
-! movsw
-! pop di
-! pop ds
-!
-!! New BPB is 0:di
-! mov [bp],di
-! mov 2[bp],ax
-!
-! mov al,[dos_spt] ! Finally, correct spt.
-! mov 4[di],al
! For each sector in root dir
! For each dir entry
diff --git a/bootblocks/trk_buf.c b/bootblocks/trk_buf.c
index 3039169..7fbb4c9 100644
--- a/bootblocks/trk_buf.c
+++ b/bootblocks/trk_buf.c
@@ -27,6 +27,7 @@ void reset_disk()
if( data_buf2 ) free(data_buf2);
data_buf1 = data_buf2 = 0;
last_drive = disk_drive;
+ bad_track = -1;
if( !(disk_drive & 0x80 ) )
{
@@ -71,7 +72,7 @@ long sectno;
int phy_h = 0;
int phy_c = 0;
- if( disk_drive != last_drive ) reset_disk();
+ if( disk_drive != last_drive || sectno == 0 ) reset_disk();
if( disk_spt < 0 || disk_spt > 63 || disk_heads < 1 )
{
@@ -115,10 +116,10 @@ long sectno;
{
rv = phy_read(disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
tries--;
- if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
- disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
}
while(rv && tries > 0);
+ if( rv ) printf("Disk error 0x%02x %d:%d:%d:%d[%2d] -> 0x%04x[]\n",
+ rv, disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
if(rv) return 0; else return data_buf1;
}
@@ -132,7 +133,7 @@ int phy_c, phy_h, phy_s;
int rv, nlen;
/* Big tracks get us short of memory so limit it. */
- nlen = (disk_spt-1)/22;
+ nlen = (disk_spt-1)/24;
nlen = (disk_spt+nlen)/(nlen+1);
trk_no = (long)phy_c*disk_heads*4+phy_h*4+phy_s/nlen+1;
@@ -176,7 +177,6 @@ int phy_c, phy_h, phy_s;
data_buf1 = data_buf2; data_buf2 = 0; data_trk2 = -1;
}
- bad_track = -1;
data_trk1 = -1;
/* Not enough memory for track read. */
@@ -187,10 +187,10 @@ int phy_c, phy_h, phy_s;
rv = phy_read(disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len,
data_buf1);
tries--;
- if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
- disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, data_buf1);
}
while(rv && tries > 0);
+ if( rv ) printf("Disk error 0x%02x %d:%d:%d:%d[%2d] -> 0x%04x[]\n",
+ rv, disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, data_buf1);
/* Disk error, it'll try one at a time, _very_ slowly! */
if(rv)
diff --git a/bootblocks/unix.c b/bootblocks/unix.c
index ec8ee89..e6eb41e 100644
--- a/bootblocks/unix.c
+++ b/bootblocks/unix.c
@@ -17,7 +17,10 @@ static open_fd()
{
phy_fd = open("/dev/fd0", 0);
if( phy_fd < 0 )
+ {
fprintf(stderr, "Cannot open /dev/fd0\n");
+ phy_fd= -2;
+ }
}
phy_read(drive, cyl, head, sect, len, buffer)
@@ -30,6 +33,7 @@ extern long lseek();
int i;
if( phy_fd == -1 ) open_fd();
+ if( phy_fd < 0 ) return -1;
offset = (((cyl*2 + head)*18L + sect-1)*512L);
@@ -130,8 +134,11 @@ int len;
}
}
-display_crc()
+display_crc(str)
+char * str;
{
- printf("Image CRC value = %u\n", crc);
+ if( str )
+ printf("%s 0x%04x\n", str, crc);
+ return crc;
}
diff --git a/bootblocks/zimage.s b/bootblocks/zimage.s
new file mode 100644
index 0000000..a58df57
--- /dev/null
+++ b/bootblocks/zimage.s
@@ -0,0 +1,73 @@
+!
+! This is a short helper to copy a zImage from high memory to low memory
+! then call it.
+!
+
+ org $1000
+Start:
+ xor ax,ax
+ mov ds,ax
+ mov es,ax
+ mov ss,ax
+ mov sp,#Start
+
+ mov di,#8
+nextpg:
+ mov cx,#$8000
+ mov ah,#$87
+ mov si,#GDT
+ int $15
+ jnc no_err
+
+ ! If there's an error reset.
+ jmpi $0000,$FFFF
+
+no_err:
+ inc srcaddr
+ inc destaddr
+ dec di
+ jnz nextpg
+
+ ! Call the Image (same as bzImage)
+go:
+
+ ! Kill the floppy motor, needed in case the kernel has no floppy driver.
+ mov dx,#0x3f2
+ xor al, al
+ outb
+
+ ! Setup required registers and go ...
+ mov ax,#$9000
+ mov bx,#$4000-12 ! Fix this to use boot_mem_top
+ mov es,ax
+ mov fs,ax
+ mov gs,ax
+ mov ds,ax
+ mov ss,ax
+ mov sp,bx
+
+ jmpi 0,$9020 ! Note SETUPSEG NOT INITSEG
+
+! The global descriptor table.
+
+GDT:
+.word $0000,$0000
+.word $0000,$0000
+
+.word $0000,$0000
+.word $0000,$0000
+
+.word $FFFF,$0000
+srcaddr:
+.word $9310,$0000
+
+.word $FFFF,$0000
+destaddr:
+.word $9301,$0000
+
+.word $0000,$0000
+.word $0000,$0000
+
+.word $0000,$0000
+.word $0000,$0000
+