cd boot workaround for bioses that didn't want to boot >4 image sectors.

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.
This commit is contained in:
Ben Gras 2010-04-26 22:07:21 +00:00
parent 94edf4fa12
commit a131085a5b
6 changed files with 164 additions and 49 deletions

View file

@ -11,12 +11,15 @@ LD86 = $(CC86) -.o
BIN = /usr/bin BIN = /usr/bin
MDEC = /usr/mdec 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 dos: boot.com mkfile.com
bootblock: bootblock.s bootblock: bootblock.s
$(LD86) -com -o $@ bootblock.s $(LD86) -com -o $@ bootblock.s
cdbootblock: bootblock.s
$(LD86) -com -o $@ bootblock.s -DCDBOOT
masterboot: masterboot.s masterboot: masterboot.s
$(LD86) -com -o $@ 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 -cmp -s rawfs.o rawfs86.o && ln -f rawfs.o rawfs86.o
boot: boothead.s boot.o bootimage.o rawfs86.o boot: boothead.s boot.o bootimage.o rawfs86.o
$(LD86) -o bootexec \ $(LD86) -o boot boothead.s boot.o bootimage.o rawfs86.o $(LIBS)
boothead.s boot.o bootimage.o rawfs86.o $(LIBS) install -S 22kb boot
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
edparams.o: boot.c edparams.o: boot.c
ln -f boot.c edparams.c ln -f boot.c edparams.c
@ -119,5 +114,5 @@ $(BIN)/edparams: edparams
clean: clean:
rm -f *.bak *.o 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 rm -f dosboot boot.com mkfile mkfile.com

View file

@ -1,3 +1,4 @@
#
! Bootblock 1.5 - Minix boot block. Author: Kees J. Bot ! Bootblock 1.5 - Minix boot block. Author: Kees J. Bot
! 21 Dec 1991 ! 21 Dec 1991
! !
@ -18,15 +19,21 @@
LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
BOOTSEG = 0x1000 ! Secondary boot code segment. BOOTSEG = 0x1000 ! Secondary boot code segment.
#ifdef CDBOOT
BOOTOFF = 0x0050 ! Offset into /boot above header
#else
BOOTOFF = 0x0030 ! Offset into /boot above header BOOTOFF = 0x0030 ! Offset into /boot above header
#endif
BUFFER = 0x0600 ! First free memory BUFFER = 0x0600 ! First free memory
#ifndef CDBOOT /* just constants, but make no sense for CDs */
LOWSEC = 8 ! Offset of logical first sector in partition LOWSEC = 8 ! Offset of logical first sector in partition
! table ! table
! Variables addressed using bp register ! Variables addressed using bp register
device = 0 ! The boot device
lowsec = 2 ! Offset of boot partition within drive lowsec = 2 ! Offset of boot partition within drive
secpcyl = 6 ! Sectors per cylinder = heads * sectors secpcyl = 6 ! Sectors per cylinder = heads * sectors
#endif
device = 0 ! The boot device
.text .text
@ -51,18 +58,21 @@ boot:
mov di, #LOADOFF+sectors ! char *di = sectors; mov di, #LOADOFF+sectors ! char *di = sectors;
#ifndef CDBOOT
testb dl, dl ! Winchester disks if dl >= 0x80 testb dl, dl ! Winchester disks if dl >= 0x80
jge floppy jge floppy
#endif
winchester: winchester:
#ifndef CDBOOT
! Get the offset of the first sector of the boot partition from the partition ! 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. ! table. The table is found at es:si, the lowsec parameter at offset LOWSEC.
eseg eseg
les ax, LOWSEC(si) ! es:ax = LOWSEC+2(si):LOWSEC(si) 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+0(bp), ax ! Low 16 bits of partitions first sector
mov lowsec+2(bp), es ! High 16 bits of partition's 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 ! Get the drive parameters, the number of sectors is bluntly written into the
! floppy disk sectors/track array. ! floppy disk sectors/track array.
@ -72,8 +82,10 @@ winchester:
andb cl, #0x3F ! cl = max sector number (1-origin) andb cl, #0x3F ! cl = max sector number (1-origin)
movb (di), cl ! Number of sectors per track movb (di), cl ! Number of sectors per track
incb dh ! dh = 1 + max head number (0-origin) incb dh ! dh = 1 + max head number (0-origin)
#endif
jmp loadboot jmp loadboot
#ifndef CDBOOT
! Floppy: ! Floppy:
! Execute three read tests to determine the drive type. Test for each 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 ! 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 jc next ! Error, try the next floppy type
success:movb dh, #2 ! Load number of heads for multiply success:movb dh, #2 ! Load number of heads for multiply
#endif
loadboot: loadboot:
! Load /boot from the boot device ! Load /boot from the boot device
#ifndef CDBOOT
movb al, (di) ! al = (di) = sectors per track movb al, (di) ! al = (di) = sectors per track
mulb dh ! dh = heads, ax = heads * sectors mulb dh ! dh = heads, ax = heads * sectors
mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors mov secpcyl(bp), ax ! Sectors per cylinder = heads * sectors
#endif
mov ax, #BOOTSEG ! Segment to load /boot into mov ax, #BOOTSEG ! Segment to load /boot into
mov es, ax mov es, ax
@ -117,6 +132,7 @@ load:
mov ax, 1(si) ! Get next sector number: low 16 bits mov ax, 1(si) ! Get next sector number: low 16 bits
movb dl, 3(si) ! Bits 16-23 for your up to 8GB partition movb dl, 3(si) ! Bits 16-23 for your up to 8GB partition
xorb dh, dh ! dx:ax = sector within partition xorb dh, dh ! dx:ax = sector within partition
#ifndef CDBOOT
add ax, lowsec+0(bp) add ax, lowsec+0(bp)
adc dx, lowsec+2(bp)! dx:ax = sector within drive adc dx, lowsec+2(bp)! dx:ax = sector within drive
cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit? 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) movb al, (di) ! Sectors per track - Sector number (0-origin)
subb al, ah ! = Sectors left on this track subb al, ah ! = Sectors left on this track
cmpb al, (si) ! Compare with # sectors to read 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 movb al, (si) ! (si) < sectors left on this track
read: push ax ! Save al = sectors to read read: push ax ! Save al = sectors to read
movb ah, #0x02 ! Code for disk read (all registers in use now!) movb ah, #0x02 ! Code for disk read (all registers in use now!)
int 0x13 ! Call the BIOS for a read int 0x13 ! Call the BIOS for a read
pop cx ! Restore al in cl pop cx ! Restore al in cl
jmp rdeval jmp rdeval
#endif
bigdisk: bigdisk:
movb cl, (si) ! Number of sectors to read movb cl, (si) ! Number of sectors to read
push si ! Save si push si ! Save si
@ -161,6 +178,14 @@ rdeval:
movb al, cl ! Restore al = sectors read movb al, cl ! Restore al = sectors read
addb bh, al ! bx += 2 * al * 256 (add bytes read) addb bh, al ! bx += 2 * al * 256 (add bytes read)
addb bh, al ! es:bx = where next sector must be 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 add 1(si), ax ! Update address by sectors read
adcb 3(si), ah ! Don't forget bits 16-23 (add ah = 0) adcb 3(si), ah ! Don't forget bits 16-23 (add ah = 0)
subb (si), al ! Decrement sector count by sectors read subb (si), al ! Decrement sector count by sectors read

View file

@ -46,25 +46,29 @@
.text .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 ! Set segment registers and stack pointer using the programs own header!
! (skip short a.out header plus 16 byte preefix) ! The header is either 32 bytes (short form) or 48 bytes (long form). The
jmpf boot, LOADSEG+3 ! bootblock will jump to address 0x10030 in both cases, calling one of the
.space 11 ! 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 jmpf cdboot, LOADSEG+3
.space 11 .space 11
jmpf cdboot, LOADSEG+2
.space 11
cdboot: cdboot:
mov bx, #1 mov bx, #1
jmp commonboot jmp commonboot
boot: boot:
mov bx, #0 mov bx, #0
commonboot: commonboot:
mov ax, #LOADSEG+1 mov ax, #LOADSEG
mov ds, ax ! ds = header mov ds, ax ! ds = header
movb al, a_flags movb al, a_flags
@ -129,7 +133,7 @@ sepID:
mov _daddr+0, ax mov _daddr+0, ax
mov _daddr+2, dx mov _daddr+2, dx
push ds push ds
mov ax, #LOADSEG+1 mov ax, #LOADSEG
mov ds, ax ! Back to the header once more mov ds, ax ! Back to the header once more
mov ax, a_total+0 mov ax, a_total+0
mov dx, a_total+2 ! dx:ax = data + bss + heap + stack mov dx, a_total+2 ! dx:ax = data + bss + heap + stack

View file

@ -495,8 +495,7 @@ void make_bootable(enum howto how, char *device, char *bootblock,
boothdr.a_magic[0]= !A_MAGIC0; boothdr.a_magic[0]= !A_MAGIC0;
} else { } else {
readblock(addr, buf, block_size); readblock(addr, buf, block_size);
/* Must skip 16 bytes of 'boot' as that contains code. */ memcpy(&boothdr, buf, sizeof(struct exec));
memcpy(&boothdr, buf + 16, sizeof(struct exec));
} }
bootf= NULL; bootf= NULL;
dummy.process= boothdr; dummy.process= boothdr;

View file

@ -9,7 +9,9 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <a.out.h>
#include <machine/partition.h> #include <machine/partition.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -38,6 +40,7 @@ typedef unsigned long int u_int32_t;
#define ISO_SECTOR 2048 #define ISO_SECTOR 2048
#define VIRTUAL_SECTOR 512 #define VIRTUAL_SECTOR 512
#define ROUNDUP(v, n) (((v)+(n)-1)/(n))
#define CURRENTDIR "." #define CURRENTDIR "."
#define PARENTDIR ".." #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 */ /* 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)); memset(buf, 0, sizeof(buf));
written += Write(fd, buf, rest); written += Write(fd, buf, rest);
} }
@ -766,23 +769,80 @@ writebootcatalog(int fd, int *currentsector, int imagesector, int imagesectors)
} }
int 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]; static unsigned char buf[1024*64], *addr;
ssize_t chunk, written = 0, rest; ssize_t written = 0, rest;
int virtuals; int virtuals, rem;
struct exec hdr;
struct bap {
off_t sector;
int length;
} bap[2];
while((chunk=read(bootfd, buf, sizeof(buf))) > 0) bap[1].length = bap[1].sector = 0;
written += Write(fd, buf, chunk);
if(chunk < 0) { Read(bootfd, &hdr, A_MINHDR);
perror("read boot image");
if(hdr.a_magic[0] != A_MAGIC0) {
fprintf(stderr, "bad magic in a.out of boot image.\n");
exit(1); exit(1);
} }
virtuals = written / VIRTUAL_SECTOR; if(hdr.a_hdrlen > sizeof(hdr)) {
fprintf(stderr, "surprisingly large header in boot image.\n");
exit(1);
}
if((rest = ISO_SECTOR - (written % 2048))) { /* 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);
virtuals = ROUNDUP(written, VIRTUAL_SECTOR);
assert(virtuals * VIRTUAL_SECTOR >= written);
if((rest = ISO_SECTOR - (written % ISO_SECTOR))) {
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
written += Write(fd, buf, rest); written += Write(fd, buf, rest);
} }
@ -847,6 +907,7 @@ main(int argc, char *argv[])
int pvdsector; int pvdsector;
int bigpath, littlepath, pathbytes = 0, dirsector, filesector, enddir; int bigpath, littlepath, pathbytes = 0, dirsector, filesector, enddir;
int bootvolumesector, bootcatalogsector; int bootvolumesector, bootcatalogsector;
char *appendsectorinfo = NULL;
prog = argv[0]; prog = argv[0];
@ -861,7 +922,7 @@ main(int argc, char *argv[])
return 1; 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) { switch(ch) {
case 's': case 's':
if(optarg[0] != '0' || optarg[1] != 'x') { if(optarg[0] != '0' || optarg[1] != 'x') {
@ -880,6 +941,10 @@ main(int argc, char *argv[])
case 'f': case 'f':
bootmedia= BOOTMEDIA_144M; bootmedia= BOOTMEDIA_144M;
break; break;
case 'a':
if(!(appendsectorinfo = strdup(optarg)))
exit(1);
break;
case 'l': case 'l':
label = optarg; label = optarg;
break; break;
@ -902,7 +967,7 @@ main(int argc, char *argv[])
/* Args check */ /* Args check */
if(argc != 2) { 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); prog);
return 1; return 1;
} }
@ -920,6 +985,14 @@ main(int argc, char *argv[])
return 1; return 1;
} }
if(appendsectorinfo) {
if(!bootimage || bootmedia != BOOTMEDIA_NONE) {
fprintf(stderr, "%s: append sector info where?\n",
prog);
return 1;
}
}
/* create .iso file */ /* create .iso file */
if((fd=open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 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"); fprintf(stderr, " * writing the boot image\n");
imagesector = currentsector; imagesector = currentsector;
imagesectors = writebootimage(bootimage, bootfd, imagesectors = writebootimage(bootimage, bootfd,
fd, &currentsector); fd, &currentsector, NULL, &root);
fprintf(stderr, " * image: %d virtual sectors @ sector 0x%x\n", fprintf(stderr, " * image: %d %d-byte sectors @ cd sector 0x%x\n",
imagesectors, imagesector); imagesectors, VIRTUAL_SECTOR, imagesector);
close(bootfd);
} }
/* write out all the file data */ /* write out all the file data */
@ -1088,6 +1159,16 @@ main(int argc, char *argv[])
fprintf(stderr, " * rewriting the boot rvd\n"); fprintf(stderr, " * rewriting the boot rvd\n");
seeksector(fd, bootvolumesector, &currentsector); seeksector(fd, bootvolumesector, &currentsector);
writebootrecord(fd, &currentsector, bootcatalogsector); 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"); fprintf(stderr, " * all ok\n");

View file

@ -19,6 +19,14 @@ PACKAGESOURCELIST=package_sources.install
secs=`expr 32 '*' 64` secs=`expr 32 '*' 64`
export SHELL=/bin/sh export SHELL=/bin/sh
RELEASERC=$HOME/.releaserc
if [ -f $RELEASERC ]
then . $RELEASERC
fi
set -- $* $RELOPTS
# SVN trunk repo # SVN trunk repo
TRUNK=https://gforge.cs.vu.nl/svn/minix/trunk TRUNK=https://gforge.cs.vu.nl/svn/minix/trunk
@ -107,7 +115,7 @@ usr=/dev/c0d7p0s2
RELEASEDIR=/usr/r RELEASEDIR=/usr/r
RELEASEPACKAGE=${RELEASEDIR}/usr/install/packages RELEASEPACKAGE=${RELEASEDIR}/usr/install/packages
RELEASEPACKAGESOURCES=${RELEASEDIR}/usr/install/package-sources RELEASEPACKAGESOURCES=${RELEASEDIR}/usr/install/package-sources
IMAGE=../boot/boot IMAGE=../boot/cdbootblock
ROOTIMAGE=rootimage ROOTIMAGE=rootimage
CDFILES=/usr/tmp/cdreleasefiles CDFILES=/usr/tmp/cdreleasefiles
sh tell_config OS_RELEASE . OS_VERSION >/tmp/rel.$$ sh tell_config OS_RELEASE . OS_VERSION >/tmp/rel.$$
@ -394,7 +402,8 @@ fi
if [ "$USB" -ne 0 ]; then if [ "$USB" -ne 0 ]; then
mv $bootimage $IMG mv $bootimage $IMG
else 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 ] if [ "$HDEMU" -eq 0 ]
then then
@ -414,6 +423,8 @@ else
# Make sure there is no hole..! Otherwise the ISO format is # Make sure there is no hole..! Otherwise the ISO format is
# unreadable. # unreadable.
partition -m $IMG 0 81:$isosects 81:$ROOTSECTS 81:$USRSECTS partition -m $IMG 0 81:$isosects 81:$ROOTSECTS 81:$USRSECTS
echo "gzipping $IMG"
gzip $IMG
fi fi
fi fi