diff options
author | Robert de Bath <rdebath@poboxes.com> | 1998-07-01 01:00:00 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:40:31 +0200 |
commit | ec5f28e3f1400b5dacb88eda2d9db472a20b4349 (patch) | |
tree | b3215b2306709d0412fd7845c78ca63ccaa2e29b /bootblocks | |
parent | 2f828530e36a02c5b4c534e42ab812370c2bf7d9 (diff) | |
download | dev86-ec5f28e3f1400b5dacb88eda2d9db472a20b4349.tar.gz |
Import Dev86src-0.14.3.tar.gzv0.14.3
Diffstat (limited to 'bootblocks')
-rw-r--r-- | bootblocks/Makefile | 18 | ||||
-rw-r--r-- | bootblocks/README | 199 | ||||
-rw-r--r-- | bootblocks/bootelks.c | 194 | ||||
-rw-r--r-- | bootblocks/bzimage.c | 141 | ||||
-rw-r--r-- | bootblocks/crc.c | 216 | ||||
-rw-r--r-- | bootblocks/fs.c | 4 | ||||
-rw-r--r-- | bootblocks/fs_tar.c | 190 | ||||
-rw-r--r-- | bootblocks/i86_funcs.c | 1 | ||||
-rw-r--r-- | bootblocks/makeboot.c | 76 | ||||
-rw-r--r-- | bootblocks/mbr.s | 63 | ||||
-rw-r--r-- | bootblocks/minix.c | 231 | ||||
-rw-r--r-- | bootblocks/minix_elks.c | 152 | ||||
-rw-r--r-- | bootblocks/monitor.c | 12 | ||||
-rw-r--r-- | bootblocks/msdos.s | 22 | ||||
-rw-r--r-- | bootblocks/trk_buf.c | 14 | ||||
-rw-r--r-- | bootblocks/unix.c | 11 | ||||
-rw-r--r-- | bootblocks/zimage.s | 73 |
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 + |