*BSD News Article 5345


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)