Subject: Untested patch for installation problem
To: None <port-i386@NetBSD.ORG>
From: Greg Hudson <ghudson@MIT.EDU>
List: port-i386
Date: 09/03/1996 15:24:46
A long-standing problem with the i386 installation is that it requires
you to specify your NetBSD partition's offset and size, and if your
NetBSD partition is at the beginning of the disk, you will probably
get it wrong (especially if you're using cylinder mode) and crunch
your MBR.

I have written a patch to use the existing disklabel's "a" or "c"
partition (the "c" partition takes precedence if it exists) to
determine the offset and the size of the NetBSD partition.  Currently,
the kernel-constructed fake disklabel puts the MBR NetBSD partition in
the "a" slot, so this works even if you've never installed NetBSD on
the disk before.

(There is a certain movement towards putting the MBR NetBSD partition
in the "c" parition slot in the fake disklabel as well as the "a"
parition slot.  If this ever happens, the installation script could
just use the "c" partition and not bother with the "a" partition.)

Anyway, testing an installation script unfortunately requires a lot of
effort and a throwaway machine, and I may not ever get around to it.
So I'm including the patch here in case anyone wants to test it and
report on the results.  It applies to distrib/i386/floppies/inst.

If you decide to try this out, let me know how it went, regardless of
whether you had problems.  Send me a copy of your post-installation
disklabel and tell me whether you used sector or cylinder mode (or,
ideally, if you tried it both ways) so I can gauge what's been tested.

*** install.sh	1996/07/10 17:13:48	1.1
--- install.sh	1996/07/10 17:52:47
***************
*** 231,247 ****
  	echo	"multiples of the cylinder size ($cylindersize sectors)."
  fi
  
! echo -n ""
! echo -n "Size of NetBSD portion of disk (in $sizeunit)? "
! getresp
! partition=$resp
! partition_sects=`expr $resp \* $sizemult`
! part_offset=0
! if [ $partition_sects -lt $disksize ]; then
! 	echo -n "Offset of NetBSD portion of disk (in $sizeunit)? "
  	getresp
! 	part_offset=$resp
  fi
  badspacesec=0
  if [ "$sect_fwd" = "sf:" ]; then
  	badspacecyl=`expr $sects_per_track + 126`
--- 231,270 ----
  	echo	"multiples of the cylinder size ($cylindersize sectors)."
  fi
  
! # Try to get NetBSD portion via disklabel.
! label_size=0
! eval `disklabel "$drivename" 2>&1 | awk '
! 	/^  [ac]:/		{ print "label_size = " $2
! 				  print "label_offset = " $3 }'`
! 
! partition=0
! if [ -n "$label_size" ]; then
! 	echo ""
! 	echo "You appear to have marked the region of $label_size sectors"
! 	echo "starting at sector $label_offset for use by NetBSD.  Do you"
! 	echo -n "wish to use this region as the NetBSD portion of your disk? "
! 	getresp "y"
! 	case "$resp" in
! 		y*|Y*)
! 			partition=$label_size
! 			part_offset=$label_offset
! 			;;
! 	esac
! fi
! 
! if [ -z "$partition" ]; then
! 	echo ""
! 	echo -n "Size of NetBSD portion of disk (in $sizeunit)? "
  	getresp
! 	partition=`expr $resp \* $sizemult`
! 	part_offset=0
! 	if [ $partition_sects -lt $disksize ]; then
! 		echo -n "Offset of NetBSD portion of disk (in $sizeunit)? "
! 		getresp
! 		part_offset=`expr $resp \* $sizemult`
! 	fi
  fi
+ 
  badspacesec=0
  if [ "$sect_fwd" = "sf:" ]; then
  	badspacecyl=`expr $sects_per_track + 126`
***************
*** 253,259 ****
  	echo	"bad144 bad block table"
  fi
  
! sects_left=`expr $partition_sects - $badspacesec`
  units_left=`expr $sects_left / $sizemult`
  echo	""
  echo	"There are $units_left $sizeunit left to allocate."
--- 276,282 ----
  	echo	"bad144 bad block table"
  fi
  
! sects_left=`expr $partition - $badspacesec`
  units_left=`expr $sects_left / $sizemult`
  echo	""
  echo	"There are $units_left $sizeunit left to allocate."
***************
*** 269,282 ****
  				echo -n	"Root size is greater than remaining "
  				echo	"free space on disk."
  			else
! 				root=$resp
  			fi
  			;;
  	esac
  done
  root_offset=$part_offset
! part_used=`expr $root + $badspacesec / $sizemult`
! units_left=`expr $partition - $part_used`
  echo	""
  
  swap=0
--- 292,305 ----
  				echo -n	"Root size is greater than remaining "
  				echo	"free space on disk."
  			else
! 				root=`expr $resp \* $sizemult`
  			fi
  			;;
  	esac
  done
  root_offset=$part_offset
! part_used=`expr $root + $badspacesec`
! units_left=`expr ( $partition - $part_used ) / $sizemult`
  echo	""
  
  swap=0
***************
*** 290,296 ****
  				echo -n	"Swap size is greater than remaining "
  				echo	"free space on disk."
  			else
! 				swap=$resp
  			fi
  			;;
  	esac
--- 313,319 ----
  				echo -n	"Swap size is greater than remaining "
  				echo	"free space on disk."
  			else
! 				swap=`expr $resp \* $sizemult`
  			fi
  			;;
  	esac
***************
*** 309,334 ****
  echo -n	"	:nc#${cyls_per_disk}:ns#${sects_per_track}" >> $DT
  echo	":nt#${tracks_per_cyl}:\\" >> $DT
  echo	"	:se#${bytes_per_sect}:${sect_fwd}\\" >> $DT
! _size=`expr $root \* $sizemult`
! _offset=`expr $root_offset \* $sizemult`
! echo -n	"	:pa#${_size}:oa#${_offset}" >> $DT
  echo	":ta=4.2BSD:ba#${blocksize}:fa#${fragsize}:\\" >> $DT
! _size=`expr $swap \* $sizemult`
! _offset=`expr $swap_offset \* $sizemult`
! echo	"	:pb#${_size}:ob#${_offset}:tb=swap:\\" >> $DT
! _size=`expr $partition \* $sizemult`
! _offset=`expr $part_offset \* $sizemult`
! echo	"	:pc#${_size}:oc#${_offset}:\\" >> $DT
  
  echo	"You will now have to enter information about any other partitions"
  echo	"to be created in the NetBSD portion of the disk.  This process will"
  echo	"be complete when you've filled up all remaining space in the NetBSD"
  echo	"portion of the disk."
  
! while [ $part_used -lt $partition ]; do
! 	part_size=0
! 	units_left=`expr $partition - $part_used`
! 	while [ $part_size -eq 0 ]; do
  		echo	""
  		echo -n	"$units_left $sizeunit remaining in NetBSD portion of "
  		echo	"the disk"
--- 332,352 ----
  echo -n	"	:nc#${cyls_per_disk}:ns#${sects_per_track}" >> $DT
  echo	":nt#${tracks_per_cyl}:\\" >> $DT
  echo	"	:se#${bytes_per_sect}:${sect_fwd}\\" >> $DT
! echo -n	"	:pa#${root}:oa#${root_offset}" >> $DT
  echo	":ta=4.2BSD:ba#${blocksize}:fa#${fragsize}:\\" >> $DT
! echo	"	:pb#${swap}:ob#${swap_offset}:tb=swap:\\" >> $DT
! echo	"	:pc#${partition}:oc#${part_offset}:\\" >> $DT
  
  echo	"You will now have to enter information about any other partitions"
  echo	"to be created in the NetBSD portion of the disk.  This process will"
  echo	"be complete when you've filled up all remaining space in the NetBSD"
  echo	"portion of the disk."
  
! offset=`expr $root_offset + $root + $swap`
! while [ `expr $partition - $part_used` -gt $sizemult ]; do
! 	units_left=`expr ( $partition - $part_used ) / $sizemult`
! 	size=0
! 	while [ $size -eq 0 ]; do
  		echo	""
  		echo -n	"$units_left $sizeunit remaining in NetBSD portion of "
  		echo	"the disk"
***************
*** 336,388 ****
  		getresp
  		case $resp in
  			[1-9]*)
! 				total=`expr $part_used + $resp`
  				if [ $total -gt $partition ]; then
  					echo -n	"That would make the parition"
  					echo	"too large to fit!"
  				else
- 					part_size=$resp
  					part_used=$total
! 					part_name=""
! 					while [ "$part_name" = "" ]; do
  						echo -n "Mount point? "
  						getresp
! 						part_name=$resp
  					done
  				fi
  				;;
  		esac
  	done
  	if [ "$ename" = "" ]; then
! 		ename=$part_name
! 		offset=`expr $part_offset + $root + $swap`
! 		_size=`expr $part_size \* $sizemult`
! 		_offset=`expr $offset \* $sizemult`
! 		echo -n "	:pe#${_size}:oe#${_offset}" >> $DT
  		echo ":te=4.2BSD:be#${blocksize}:fe#${fragsize}:\\" >> $DT
- 		offset=`expr $offset + $part_size`
  	elif [ "$fname" = "" ]; then
! 		fname=$part_name
! 		_size=`expr $part_size \* $sizemult`
! 		_offset=`expr $offset \* $sizemult`
! 		echo -n "	:pf#${_size}:of#${_offset}" >> $DT
  		echo ":tf=4.2BSD:bf#${blocksize}:ff#${fragsize}:\\" >> $DT
- 		offset=`expr $offset + $part_size`
  	elif [ "$gname" = "" ]; then
! 		gname=$part_name
! 		_size=`expr $part_size \* $sizemult`
! 		_offset=`expr $offset \* $sizemult`
! 		echo -n "	:pg#${_size}:og#${_offset}" >> $DT
  		echo ":tg=4.2BSD:bg#${blocksize}:fg#${fragsize}:\\" >> $DT
- 		offset=`expr $offset + $part_size`
  	elif [ "$hname" = "" ]; then
! 		hname=$part_name
! 		_size=`expr $part_size \* $sizemult`
! 		_offset=`expr $offset \* $sizemult`
! 		echo -n "	:ph#${_size}:oh#${_offset}" >> $DT
  		echo ":th=4.2BSD:bh#${blocksize}:fh#${fragsize}:\\" >> $DT
  		part_used=$partition
  	fi
  done
  echo	"	:pd#${disksize}:od#0:" >> $DT
  sync
--- 354,395 ----
  		getresp
  		case $resp in
  			[1-9]*)
! 				total=`expr $part_used + $resp \* $sizemult`
  				if [ $total -gt $partition ]; then
  					echo -n	"That would make the parition"
  					echo	"too large to fit!"
  				else
  					part_used=$total
! 					size=`expr $resp \* $sizemult`
! 					name=""
! 					while [ "$name" = "" ]; do
  						echo -n "Mount point? "
  						getresp
! 						name=$resp
  					done
  				fi
  				;;
  		esac
  	done
  	if [ "$ename" = "" ]; then
! 		ename=$name
! 		echo -n "	:pe#${size}:oe#${offset}" >> $DT
  		echo ":te=4.2BSD:be#${blocksize}:fe#${fragsize}:\\" >> $DT
  	elif [ "$fname" = "" ]; then
! 		fname=$name
! 		echo -n "	:pf#${size}:of#${offset}" >> $DT
  		echo ":tf=4.2BSD:bf#${blocksize}:ff#${fragsize}:\\" >> $DT
  	elif [ "$gname" = "" ]; then
! 		gname=$name
! 		echo -n "	:pg#${size}:og#${offset}" >> $DT
  		echo ":tg=4.2BSD:bg#${blocksize}:fg#${fragsize}:\\" >> $DT
  	elif [ "$hname" = "" ]; then
! 		hname=$name
! 		echo -n "	:ph#${size}:oh#${offset}" >> $DT
  		echo ":th=4.2BSD:bh#${blocksize}:fh#${fragsize}:\\" >> $DT
  		part_used=$partition
  	fi
+ 	offset=`expr $offset + $size`
  done
  echo	"	:pd#${disksize}:od#0:" >> $DT
  sync