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
-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
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
+#
! 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
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.
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
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
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?
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
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
.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
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
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;
#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>
#define ISO_SECTOR 2048
#define VIRTUAL_SECTOR 512
+#define ROUNDUP(v, n) (((v)+(n)-1)/(n))
#define CURRENTDIR "."
#define PARENTDIR ".."
/* 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);
}
}
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);
}
int pvdsector;
int bigpath, littlepath, pathbytes = 0, dirsector, filesector, enddir;
int bootvolumesector, bootcatalogsector;
+ char *appendsectorinfo = NULL;
prog = argv[0];
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') {
case 'f':
bootmedia= BOOTMEDIA_144M;
break;
+ case 'a':
+ if(!(appendsectorinfo = strdup(optarg)))
+ exit(1);
+ break;
case 'l':
label = optarg;
break;
/* 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;
}
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) {
fprintf(stderr, " * writing the boot image\n");
imagesector = currentsector;
imagesectors = writebootimage(bootimage, bootfd,
- fd, ¤tsector);
- fprintf(stderr, " * image: %d virtual sectors @ sector 0x%x\n",
- imagesectors, imagesector);
-
- close(bootfd);
+ fd, ¤tsector, NULL, &root);
+ fprintf(stderr, " * image: %d %d-byte sectors @ cd sector 0x%x\n",
+ imagesectors, VIRTUAL_SECTOR, imagesector);
}
/* write out all the file data */
fprintf(stderr, " * rewriting the boot rvd\n");
seeksector(fd, bootvolumesector, ¤tsector);
writebootrecord(fd, ¤tsector, bootcatalogsector);
+
+ if(appendsectorinfo) {
+ Lseek(bootfd, 0, SEEK_SET);
+ fprintf(stderr, " * rewriting boot image\n");
+ seeksector(fd, imagesector, ¤tsector);
+ writebootimage(bootimage, bootfd,
+ fd, ¤tsector, appendsectorinfo, &root);
+
+ close(bootfd);
+ }
}
fprintf(stderr, " * all ok\n");
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
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.$$
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
# 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