Return to BSD News archive
Newsgroups: comp.unix.bsd Path: sserve!manuel!munnari.oz.au!spool.mu.edu!agate!tfs.com!tfs.com!julian From: julian@tfs.com (Julian Elischer) Subject: Patch for new boot blocks Message-ID: <1992Sep20.080351.9280@tfs.com> Organization: TRW Financial Systems Date: Sun, 20 Sep 1992 08:03:51 GMT Lines: 148 Here is a pair of patches that fix two very stupid bugs in the new boot blocks: Thanks to sim@cory.Berkeley.EDU for spending an afternoon finding these: By the way sim, I was just down the road (5 min walk) hacking on the scsi stuff at the same time. I think I have the cdrom driver for the new scsi stuff breathing. >From reading the old driver I thought cd drives used a 2k logical blocksize but the SONY (SUN) drive i have for the weekend uses a 512 byte logical bs, so I'm a little confused. DOES ANYONE OUT THERE know how to make the ISOFS mount? I include his comments: Hi I have a BusTek 542B and I can't boot using asboot and bootas (and I haven't figured out why...) So I tried your new boot blocks on this controller. It didn't work right, but after playing with it for a whole afternoon, I found a couple of bugs. Now it works fine on my system. So I have made a patch and I'm sending it to you. The first one is not important but the extra space messes up the display after the boot because of the dumb code in pccons.c . I can probably guess that the block size on your filesystem is 4k, right? Mine is 8k, so the boot code failed! First thing, mapbuf[] should be of size MAXBSIZE, the largest possible block size, otherwise the devread() in block_map() blindly reads fs->fs_bsize bytes (8192 in my case :) and overwrites other data. This is the major problem that causes it to fail on my system. Not only this, cnt and bnum are globals -- block_map() can change them when it tries to read the indirect blocks. This screws up the setting of cnt in read(). The patch adds cnt2 and bnum2 to the code. The patch also changes BUFSIZE to MAXBSIZE. This is also not very important but it'll speed up the load. Why? Because the code in read() reads in blocks of blksize() which is the "recommended" io size for the filesystem (8k for my filesystem). If the numbers don't fit (4k < 8k) there will be extra reads of the same blocks and extra bcopy(). In my case, each block is read twice and an extra bcopy occurs. Actually, if you really want to "do it right" :) , may be the use of globals for bnum and cnt should be avoided. The code can also avoid the extra buf[] and use iobuf instead. Thanks... now I can boot from my SCSI drive. PT [ The use of globals came with the s/w from CMU. I think it's silly but hey it works] Julian Here is the patch: diff -c -r i386/boot/boot.c ../i386/boot/boot.c *** i386/boot/boot.c Sat Sep 19 22:04:43 1992 --- ../i386/boot/boot.c Sat Sep 19 22:04:10 1992 *************** *** 257,263 **** /****************************************************************/ /* copy that first page and overwrite any BIOS variables */ /****************************************************************/ ! printf(" entry point=0x%x \n " ,((int)startaddr) & 0xffffff); pcpy(tmpbuf, 0, 4096); startprog(((int)startaddr & 0xffffff),argv); } --- 257,263 ---- /****************************************************************/ /* copy that first page and overwrite any BIOS variables */ /****************************************************************/ ! printf(" entry point=0x%x \n" ,((int)startaddr) & 0xffffff); pcpy(tmpbuf, 0, 4096); startprog(((int)startaddr & 0xffffff),argv); } diff -c -r i386/boot/sys.c ../i386/boot/sys.c *** i386/boot/sys.c Sat Sep 19 22:04:36 1992 --- ../i386/boot/sys.c Sat Sep 19 22:04:10 1992 *************** *** 39,45 **** #include <sys/dir.h> #include <sys/reboot.h> ! #define BUFSIZE 4096 char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE]; --- 39,46 ---- #include <sys/dir.h> #include <sys/reboot.h> ! /* #define BUFSIZE 4096 */ ! #define BUFSIZE MAXBSIZE char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE]; *************** *** 63,74 **** char *buffer; { int logno, off, size; while (count) { off = blkoff(fs, poff); logno = lblkno(fs, poff); ! cnt = size = blksize(fs, &inode, logno); ! bnum = fsbtodb(fs, block_map(logno)) + boff; if ( (!off) && (size <= count)) { iodest = buffer; --- 64,78 ---- char *buffer; { int logno, off, size; + int cnt2, bnum2; while (count) { off = blkoff(fs, poff); logno = lblkno(fs, poff); ! cnt2 = size = blksize(fs, &inode, logno); ! bnum2 = fsbtodb(fs, block_map(logno)) + boff; ! cnt = cnt2; ! bnum = bnum2; if ( (!off) && (size <= count)) { iodest = buffer; *************** *** 128,134 **** goto loop; } ! char mapbuf[BUFSIZE]; int mapblock = 0; block_map(file_block) --- 132,138 ---- goto loop; } ! char mapbuf[MAXBSIZE]; int mapblock = 0; block_map(file_block)