]> Zhao Yanbai Git Server - minix.git/commitdiff
cd boot workaround for bioses that didn't want to boot >4 image sectors.
authorBen Gras <ben@minix3.org>
Mon, 26 Apr 2010 22:07:21 +0000 (22:07 +0000)
committerBen Gras <ben@minix3.org>
Mon, 26 Apr 2010 22:07:21 +0000 (22:07 +0000)
boot is a normal binary with a.out again. use 'cdbootblock,' a CDBOOT
variant of bootblock, both from bootblock.s, as the first boot image
that then loads boot, exactly like the bootblock loads boot when booting
from harddisk. the sector numbers (2048 byte iso sectors) are patched in
by writeisofs, like installboot does for bootblock. bootblock unchanged.

boot/Makefile
boot/bootblock.s
boot/boothead.s
boot/installboot.c
commands/simple/writeisofs.c
tools/release.sh

index 9ed47718148f4b59983dd20613ef5a1af89ed053..7c525438ed7cf81b394c505c72727e16ca07af7b 100644 (file)
@@ -11,12 +11,15 @@ LD86        = $(CC86) -.o
 BIN    = /usr/bin
 MDEC   = /usr/mdec
 
-all:   bootblock boot edparams masterboot jumpboot installboot addaout
+all:   bootblock cdbootblock boot edparams masterboot jumpboot installboot addaout
 dos:   boot.com mkfile.com
 
 bootblock:     bootblock.s
        $(LD86) -com -o $@ bootblock.s
 
+cdbootblock:   bootblock.s
+       $(LD86) -com -o $@ bootblock.s -DCDBOOT
+
 masterboot:    masterboot.s
        $(LD86) -com -o $@ masterboot.s
 
@@ -36,16 +39,8 @@ rawfs86.o:   rawfs.c rawfs.o
        -cmp -s rawfs.o rawfs86.o && ln -f rawfs.o rawfs86.o
 
 boot:  boothead.s boot.o bootimage.o rawfs86.o
-       $(LD86) -o bootexec \
-               boothead.s boot.o bootimage.o rawfs86.o $(LIBS)
-       install -S 22kb bootexec
-       # This is code that is executed when used on a bootable
-       # CD, as its entry point is the start of the file then.
-       # It jumps over the a.out header into the part of the
-       # code in boothead.s where the code knows it's booting
-       # from CD if entered there.
-       ( printf '\xeb\x3e              ' ; cat bootexec ) >boot
-       chmod 755 boot
+       $(LD86) -o boot boothead.s boot.o bootimage.o rawfs86.o $(LIBS)
+       install -S 22kb boot
 
 edparams.o:    boot.c
        ln -f boot.c edparams.c
@@ -119,5 +114,5 @@ $(BIN)/edparams:    edparams
 
 clean:
        rm -f *.bak *.o
-       rm -f bootblock addaout installboot boot masterboot jumpboot edparams
+       rm -f cdbootblock bootblock addaout installboot boot masterboot jumpboot edparams
        rm -f dosboot boot.com mkfile mkfile.com
index 77b187073cdad4936cd67aa4baf7bd810298716e..1c2b9edba516d551cf108f08e041ac1036e2c816 100644 (file)
@@ -1,3 +1,4 @@
+#
 !      Bootblock 1.5 - Minix boot block.               Author: Kees J. Bot
 !                                                              21 Dec 1991
 !
 
        LOADOFF    =    0x7C00  ! 0x0000:LOADOFF is where this code is loaded
        BOOTSEG    =    0x1000  ! Secondary boot code segment.
+#ifdef CDBOOT
+       BOOTOFF    =    0x0050  ! Offset into /boot above header
+#else
        BOOTOFF    =    0x0030  ! Offset into /boot above header
+#endif
        BUFFER     =    0x0600  ! First free memory
+#ifndef CDBOOT                 /* just constants, but make no sense for CDs */
        LOWSEC     =         8  ! Offset of logical first sector in partition
                                ! table
 
        ! Variables addressed using bp register
-       device     =         0  ! The boot device
        lowsec     =         2  ! Offset of boot partition within drive
        secpcyl    =         6  ! Sectors per cylinder = heads * sectors
+#endif
+       device     =         0  ! The boot device
 
 .text
 
@@ -51,18 +58,21 @@ boot:
 
        mov     di, #LOADOFF+sectors    ! char *di = sectors;
 
+#ifndef CDBOOT
        testb   dl, dl          ! Winchester disks if dl >= 0x80
        jge     floppy
+#endif
 
 winchester:
 
+#ifndef CDBOOT
 ! Get the offset of the first sector of the boot partition from the partition
 ! table.  The table is found at es:si, the lowsec parameter at offset LOWSEC.
 
        eseg
        les     ax, LOWSEC(si)    ! es:ax = LOWSEC+2(si):LOWSEC(si)
-       mov     lowsec+0(bp), ax  ! Low 16 bits of partition's first sector
-       mov     lowsec+2(bp), es  ! High 16 bits of partition's first sector
+       mov     lowsec+0(bp), ax  ! Low 16 bits of partitions first sector
+       mov     lowsec+2(bp), es  ! High 16 bits of partitions first sector
 
 ! Get the drive parameters, the number of sectors is bluntly written into the
 ! floppy disk sectors/track array.
@@ -72,8 +82,10 @@ winchester:
        andb    cl, #0x3F       ! cl = max sector number (1-origin)
        movb    (di), cl        ! Number of sectors per track
        incb    dh              ! dh = 1 + max head number (0-origin)
+#endif
        jmp     loadboot
 
+#ifndef CDBOOT
 ! Floppy:
 ! Execute three read tests to determine the drive type.  Test for each floppy
 ! type by reading the last sector on the first track.  If it fails, try a type
@@ -101,13 +113,16 @@ floppy:   xorb    ah, ah          ! Reset drive
        jc      next            ! Error, try the next floppy type
 
 success:movb   dh, #2          ! Load number of heads for multiply
+#endif
 
 loadboot:
 ! Load /boot from the boot device
 
+#ifndef CDBOOT
        movb    al, (di)        ! al = (di) = sectors per track
        mulb    dh              ! dh = heads, ax = heads * sectors
        mov     secpcyl(bp), ax ! Sectors per cylinder = heads * sectors
+#endif
 
        mov     ax, #BOOTSEG    ! Segment to load /boot into
        mov     es, ax
@@ -117,6 +132,7 @@ load:
        mov     ax, 1(si)       ! Get next sector number: low 16 bits
        movb    dl, 3(si)       ! Bits 16-23 for your up to 8GB partition
        xorb    dh, dh          ! dx:ax = sector within partition
+#ifndef CDBOOT
        add     ax, lowsec+0(bp)
        adc     dx, lowsec+2(bp)! dx:ax = sector within drive
        cmp     dx, #[1024*255*63-255]>>16  ! Near 8G limit?
@@ -136,13 +152,14 @@ load:
        movb    al, (di)        ! Sectors per track - Sector number (0-origin)
        subb    al, ah          ! = Sectors left on this track
        cmpb    al, (si)        ! Compare with # sectors to read
-       jbe     read            ! Can't read past the end of a cylinder?
+       jbe     read            ! Cant read past the end of a cylinder?
        movb    al, (si)        ! (si) < sectors left on this track
 read:  push    ax              ! Save al = sectors to read
        movb    ah, #0x02       ! Code for disk read (all registers in use now!)
        int     0x13            ! Call the BIOS for a read
        pop     cx              ! Restore al in cl
        jmp     rdeval
+#endif
 bigdisk:
        movb    cl, (si)        ! Number of sectors to read
        push    si              ! Save si
@@ -161,6 +178,14 @@ rdeval:
        movb    al, cl          ! Restore al = sectors read
        addb    bh, al          ! bx += 2 * al * 256 (add bytes read)
        addb    bh, al          ! es:bx = where next sector must be read
+#ifdef CDBOOT
+       addb    bh, al          ! For CDs, a sector is 2048 bytes, so
+       addb    bh, al          ! do this 6 more times to get byte count.
+       addb    bh, al          
+       addb    bh, al          
+       addb    bh, al          
+       addb    bh, al          
+#endif
        add     1(si), ax       ! Update address by sectors read
        adcb    3(si), ah       ! Don't forget bits 16-23 (add ah = 0)
        subb    (si), al        ! Decrement sector count by sectors read
index 8644799ee361a847e86ff82a72a98e34509fab96..03955aee3413f0a96a1c414b1db7c8d830a4f0ee 100644 (file)
 
 .text
 
-! We assume boot is always linked with a short (32 byte) a.out header and has
-! 16 bytes of its own prefix, so 48 bytes to skip. bootblock jumps into us
-! at offset 0x30, cd boot code at 0x40
 
-       ! Set cs right
-       ! (skip short a.out header plus 16 byte preefix)
-       jmpf    boot, LOADSEG+3         
-       .space  11
+! Set segment registers and stack pointer using the programs own header!
+! The header is either 32 bytes (short form) or 48 bytes (long form).  The
+! bootblock will jump to address 0x10030 in both cases, calling one of the
+! two jmpf instructions below.
+!
+! CD bootblock jumps to address 0x10050 in both cases.
 
-       ! entry point when booting from CD
+       jmpf    boot, LOADSEG+3 ! Set cs right (skipping long a.out header)
+       .space  11              ! jmpf + 11 = 16 bytes
+       jmpf    boot, LOADSEG+2 ! Set cs right (skipping short a.out header)
+       .space  11              ! jmpf + 11 = 16 bytes
        jmpf    cdboot, LOADSEG+3
-       .space  11
+       .space  11              
+       jmpf    cdboot, LOADSEG+2
+       .space  11              
 cdboot:
        mov     bx, #1
        jmp     commonboot
 boot:
        mov     bx, #0
 commonboot:
-       mov     ax, #LOADSEG+1
+       mov     ax, #LOADSEG
        mov     ds, ax          ! ds = header
 
        movb    al, a_flags
@@ -129,7 +133,7 @@ sepID:
        mov     _daddr+0, ax
        mov     _daddr+2, dx
        push    ds
-       mov     ax, #LOADSEG+1
+       mov     ax, #LOADSEG
        mov     ds, ax          ! Back to the header once more
        mov     ax, a_total+0
        mov     dx, a_total+2   ! dx:ax = data + bss + heap + stack
index 5b334bf68a89ce75a1fc1d7a064e9a6635459e5a..17dc4f952677f3f4c8c2e6b5bb67401730d86462 100644 (file)
@@ -495,8 +495,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
                        boothdr.a_magic[0]= !A_MAGIC0;
                } else {
                        readblock(addr, buf, block_size);
-                       /* Must skip 16 bytes of 'boot' as that contains code. */
-                       memcpy(&boothdr, buf + 16, sizeof(struct exec));
+                       memcpy(&boothdr, buf, sizeof(struct exec));
                }
                bootf= NULL;
                dummy.process= boothdr;
index 426f57e7ebaa7e2732d210c096fe0f35a1005186..0a66d9d958e54e31a8a21edeaed9dd0643d33812 100644 (file)
@@ -9,7 +9,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <dirent.h>
+#include <assert.h>
 #include <ctype.h>
+#include <a.out.h>
 #include <machine/partition.h>
 
 #include <sys/stat.h>
@@ -38,6 +40,7 @@ typedef unsigned long int u_int32_t;
 
 #define ISO_SECTOR 2048
 #define VIRTUAL_SECTOR 512
+#define ROUNDUP(v, n) (((v)+(n)-1)/(n))
 
 #define CURRENTDIR     "."
 #define PARENTDIR      ".."
@@ -755,7 +758,7 @@ writebootcatalog(int fd, int  *currentsector, int imagesector, int imagesectors)
 
        /* fill out the rest of the sector with 0's */
 
-       if((rest = ISO_SECTOR - (written % 2048))) {
+       if((rest = ISO_SECTOR - (written % ISO_SECTOR))) {
                memset(buf, 0, sizeof(buf));
                written += Write(fd, buf, rest);
        }
@@ -766,23 +769,80 @@ writebootcatalog(int fd, int  *currentsector, int imagesector, int imagesectors)
 }
 
 int
-writebootimage(char *bootimage, int bootfd, int fd, int *currentsector)
+writebootimage(char *bootimage, int bootfd, int fd, int *currentsector,
+       char *appendsectorinfo, struct node *root)
 {
-       static char buf[1024*64];
-       ssize_t chunk, written = 0, rest;
-       int virtuals;
+       static unsigned char buf[1024*64], *addr;
+       ssize_t written = 0, rest;
+       int virtuals, rem;
+       struct exec hdr;
+       struct bap {
+               off_t sector;
+               int length;
+       } bap[2];
+
+       bap[1].length = bap[1].sector = 0;
 
-       while((chunk=read(bootfd, buf, sizeof(buf))) > 0)
-               written += Write(fd, buf, chunk);
+       Read(bootfd, &hdr, A_MINHDR);
 
-       if(chunk < 0) {
-               perror("read boot image");
+       if(hdr.a_magic[0] != A_MAGIC0) {
+               fprintf(stderr, "bad magic in a.out of boot image.\n");
                exit(1);
        }
 
-       virtuals = written / VIRTUAL_SECTOR;
+       if(hdr.a_hdrlen > sizeof(hdr)) {
+               fprintf(stderr, "surprisingly large header in boot image.\n");
+               exit(1);
+       }
+
+       /* read rest of a.out header. */
+       Read(bootfd, (char *) &hdr + A_MINHDR, hdr.a_hdrlen - A_MINHDR);
+
+       /* copy text+data */
+       rem = hdr.a_text + hdr.a_data;
+
+       while(rem > 0) {
+               int want;
+               want = rem < sizeof(buf) ? rem : sizeof(buf);
+               Read(bootfd, buf, want);
+               written += Write(fd, buf, want);
+               rem -= want;
+       }
+
+       if(appendsectorinfo) {
+               struct node *n;
+               for(n = root->firstchild; n; n = n ->nextchild) {
+                       if(!strcasecmp(appendsectorinfo, n->name)) {
+                               bap[0].sector = n->startsector;
+                               bap[0].length = ROUNDUP(n->bytesize, ISO_SECTOR);
+                               break;
+                       }
+               }
+               if(!n) {
+                       fprintf(stderr, "%s not found in root.\n",
+                               appendsectorinfo);
+                       exit(1);
+               }
+
+               fprintf(stderr, " * appended sector info: 0x%lx len 0x%lx\n",
+                       bap[0].sector, bap[0].length);
+       }
+
+       addr = buf;
+       addr[0] = bap[0].length;        assert(addr[0] > 0);
+       addr[1] = (bap[0].sector >>  0) & 0xFF;
+       addr[2] = (bap[0].sector >>  8) & 0xFF;
+       addr[3] = (bap[0].sector >> 16) & 0xFF;
+       addr[4] = 0;
+       addr[5] = 0;
+
+       /* Always save space for sector info after the boot image. */
+       written += Write(fd, addr, 6);
 
-       if((rest = ISO_SECTOR - (written % 2048))) {
+        virtuals = ROUNDUP(written, VIRTUAL_SECTOR);
+        assert(virtuals * VIRTUAL_SECTOR >= written);                           
+
+       if((rest = ISO_SECTOR - (written % ISO_SECTOR))) {
                memset(buf, 0, sizeof(buf));
                written += Write(fd, buf, rest);
        }
@@ -847,6 +907,7 @@ main(int argc, char *argv[])
        int pvdsector;
        int bigpath, littlepath, pathbytes = 0, dirsector, filesector, enddir;
        int bootvolumesector, bootcatalogsector;
+       char *appendsectorinfo = NULL;
 
        prog = argv[0];
 
@@ -861,7 +922,7 @@ main(int argc, char *argv[])
                return 1;
        }
 
-       while ((ch = getopt(argc, argv, "b:s:Rb:hl:nf")) != -1) {
+       while ((ch = getopt(argc, argv, "a:b:s:Rb:hl:nf")) != -1) {
                switch(ch) {
                        case 's':
                                if(optarg[0] != '0' || optarg[1] != 'x') {
@@ -880,6 +941,10 @@ main(int argc, char *argv[])
                        case 'f':
                                bootmedia= BOOTMEDIA_144M;
                                break;
+                       case 'a':
+                               if(!(appendsectorinfo = strdup(optarg)))
+                                       exit(1);
+                               break;
                        case 'l':
                                label = optarg;
                                break;
@@ -902,7 +967,7 @@ main(int argc, char *argv[])
        /* Args check */
 
        if(argc != 2) {
-               fprintf(stderr, "usage: %s [-l <label>] [-b <bootimage> [-n] [-f] [-h] [-s <bootsegment>] ] <dir> <isofile>\n",
+               fprintf(stderr, "usage: %s [-l <label>] [-b <bootimage> [-n] [-f] [-h] [-s <bootsegment>] [ -a <appendfile> ] <dir> <isofile>\n",
                        prog);
                return 1;
        }
@@ -920,6 +985,14 @@ main(int argc, char *argv[])
                return 1;
        }
 
+       if(appendsectorinfo) {
+               if(!bootimage || bootmedia != BOOTMEDIA_NONE) {
+                       fprintf(stderr, "%s: append sector info where?\n",
+                               prog);
+                       return 1;
+               }
+       }
+
        /* create .iso file */
 
        if((fd=open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
@@ -1012,11 +1085,9 @@ main(int argc, char *argv[])
                fprintf(stderr, " * writing the boot image\n");
                imagesector = currentsector;
                imagesectors = writebootimage(bootimage, bootfd,
-                       fd, &currentsector);
-               fprintf(stderr, " * image: %d virtual sectors @ sector 0x%x\n",
-                       imagesectors, imagesector);
-
-               close(bootfd);
+                       fd, &currentsector, NULL, &root);
+               fprintf(stderr, " * image: %d %d-byte sectors @ cd sector 0x%x\n",
+                       imagesectors, VIRTUAL_SECTOR, imagesector);
        }
 
        /* write out all the file data */
@@ -1088,6 +1159,16 @@ main(int argc, char *argv[])
                fprintf(stderr, " * rewriting the boot rvd\n");
                seeksector(fd, bootvolumesector, &currentsector);
                writebootrecord(fd, &currentsector, bootcatalogsector);
+
+               if(appendsectorinfo) {
+                       Lseek(bootfd, 0, SEEK_SET);
+                       fprintf(stderr, " * rewriting boot image\n");
+                       seeksector(fd, imagesector, &currentsector);
+                       writebootimage(bootimage, bootfd,
+                               fd, &currentsector, appendsectorinfo, &root);
+
+                       close(bootfd);
+               }
        }
 
        fprintf(stderr, " * all ok\n");
index 639a8475df8f9be6eb908f695287172374f296ed..339e0baf2d183233cb6bd93b1823b303781aacea 100755 (executable)
@@ -19,6 +19,14 @@ PACKAGESOURCELIST=package_sources.install
 secs=`expr 32 '*' 64`
 export SHELL=/bin/sh
 
+RELEASERC=$HOME/.releaserc
+
+if [ -f $RELEASERC ]
+then   . $RELEASERC
+fi
+
+set -- $* $RELOPTS
+
 # SVN trunk repo
 TRUNK=https://gforge.cs.vu.nl/svn/minix/trunk
 
@@ -107,7 +115,7 @@ usr=/dev/c0d7p0s2
 RELEASEDIR=/usr/r
 RELEASEPACKAGE=${RELEASEDIR}/usr/install/packages
 RELEASEPACKAGESOURCES=${RELEASEDIR}/usr/install/package-sources
-IMAGE=../boot/boot
+IMAGE=../boot/cdbootblock
 ROOTIMAGE=rootimage
 CDFILES=/usr/tmp/cdreleasefiles
 sh tell_config OS_RELEASE . OS_VERSION >/tmp/rel.$$
@@ -394,7 +402,8 @@ fi
 if [ "$USB" -ne 0 ]; then
        mv $bootimage $IMG
 else
-       writeisofs -s0x1000 -l MINIX -b $bootimage $boottype $CDFILES $IMG || exit 1
+       cp ../boot/boot $CDFILES
+       writeisofs -s0x0 -l MINIX -a boot -b $bootimage $boottype $CDFILES $IMG || exit 1
 
        if [ "$HDEMU" -eq 0 ]
        then
@@ -414,6 +423,8 @@ else
                # Make sure there is no hole..! Otherwise the ISO format is
                # unreadable.
                partition -m $IMG 0 81:$isosects 81:$ROOTSECTS 81:$USRSECTS
+               echo "gzipping $IMG"
+               gzip $IMG
        fi
 fi