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
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

View file

@ -1,3 +1,4 @@
#
! Bootblock 1.5 - Minix boot block. Author: Kees J. Bot
! 21 Dec 1991
!
@ -18,15 +19,21 @@
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

View file

@ -46,25 +46,29 @@
.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

View 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;

View 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];
while((chunk=read(bootfd, buf, sizeof(buf))) > 0)
written += Write(fd, buf, chunk);
bap[1].length = bap[1].sector = 0;
if(chunk < 0) {
perror("read boot image");
Read(bootfd, &hdr, A_MINHDR);
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);
}
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));
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");

View file

@ -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