Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Oct 1996 04:49:26 +0200 (MET DST)
From:      Tor Egge <tegge@itea.ntnu.no>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/1783: fdisk calculates wrong start/end addresses in dos partition table
Message-ID:  <199610130249.EAA12293@skarven.itea.ntnu.no>
Resent-Message-ID: <199610130250.TAA26477@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         1783
>Category:       bin
>Synopsis:       fdisk calculates wrong start/end addresses in dos partition table
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 12 19:50:01 PDT 1996
>Last-Modified:
>Originator:     Tor Egge
>Organization:
Norwegian University of Science and Technology, Trondheim, Norway
>Release:        FreeBSD 2.2-CURRENT i386
>Environment:

FreeBSD skarven.itea.ntnu.no 2.2-CURRENT FreeBSD 2.2-CURRENT #0: Fri Oct i386

>Description:

	Installing FreeBSD on a machine where NetBSD has previously been
	installed and where no floppy drive is present causes a lot of
	error mesages to be given, e.g.


	Oct 11 17:25:54 skarven /kernel: sd3: invalid primary partition table: no magic
	Oct 11 17:25:54 skarven /kernel: sd3: raw partition size != slice size
	Oct 11 17:25:54 skarven /kernel: sd3: start 0, end 8388314, size 8388315
	Oct 11 17:25:54 skarven /kernel: sd3c: start 0, end 4294967295, size 0

	Using fdisk to correct these problems, and always specifying 
	block 0 as start of the FreeBSD slice and the size of the disk
	as the size of the FreeBSD slice removed some of these error messages.
        Using disklabel to extend the raw partition size to the size
	of the disk removed the rest of the error messasges. 

	BUT! The system became unbootable, due to the mapping of start 
	block 0 to cylinder 0, head 0, sector 0 performed in dos(). 
	This special case should should only be performed if the size
	of the partition is 0 (i.e. unused partition). If the size is 
	nonzero, a starting block of 0 should be mapped to 
        cylinder 0, head 0, sector 1.
	
	Installing a floppy drive, booting the kernel on the hard disk using
	the boot blocks on a fixit floppy, running fdisk, explicitly
	specifying the bios begin/end addresses of the FreeBSD slice brought
	the system up again.

>How-To-Repeat:

	Install FreeBSD upon an existing NetBSD installation, where
	the first partition starts at sector 0 on the disk. Use fdisk
	to bring the DOS partition table into sync with the disklabel,
	but don't explicitly specify bios start/end addresses.

	Watch the system die on next reboot. 

>Fix:

	For wrong start address:

	  The dos() function needs a new second argument, containing the size
	  of the partition. Only if the size is 0 should the 
	  special handling of 0 as first argument be triggered.

        For wrong end address:

	  The init_sector0 function needs do decrease the first argument
	  to the second call to dos() by one to be consistent with the 
	  calls to dos() in change_part().

Index: fdisk.c
===================================================================
RCS file: /export/ftpsearch3/cvs/src/sbin/i386/fdisk/fdisk.c,v
retrieving revision 1.10
diff -u -r1.10 fdisk.c
--- fdisk.c	1996/06/21 02:39:19	1.10
+++ fdisk.c	1996/10/13 02:40:06
@@ -183,7 +183,7 @@
 static void print_params();
 static void change_active(int which);
 static void get_params_to_use();
-static void dos(int sec, unsigned char *c, unsigned char *s, unsigned char *h);
+static void dos(int sec, int size, unsigned char *c, unsigned char *s, unsigned char *h);
 static int open_disk(int u_flag);
 static ssize_t read_disk(off_t sector, void *buf);
 static ssize_t write_disk(off_t sector, void *buf);
@@ -372,8 +372,10 @@
 	partp->dp_start = start;
 	partp->dp_size = size;
 
-	dos(partp->dp_start, &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
-	dos(partp->dp_start+partp->dp_size, &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
+	dos(partp->dp_start, partp->dp_size, 
+	    &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
+	dos(partp->dp_start+partp->dp_size-1, partp->dp_size,
+	    &partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
 }
 
 static void
@@ -424,9 +426,9 @@
 			partp->dp_esect = DOSSECT(tsec,tcyl);
 			partp->dp_ehd = thd;
 		} else {
-			dos(partp->dp_start,
+			dos(partp->dp_start,partp->dp_size,
 				&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
-			dos(partp->dp_start+partp->dp_size - 1,
+			dos(partp->dp_start+partp->dp_size - 1,partp->dp_size,
 				&partp->dp_ecyl, &partp->dp_esect, &partp->dp_ehd);
 		}
 
@@ -491,14 +493,14 @@
 * Change real numbers into strange dos numbers	*
 \***********************************************/
 static void
-dos(sec, c, s, h)
-int sec;
+dos(sec, size, c, s, h)
+int sec, size;
 unsigned char *c, *s, *h;
 {
 int cy;
 int hd;
 
-	if (sec == 0) {
+	if (sec == 0 && size == 0) {
 		*s = *c = *h = 0;
 		return;
 	}
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610130249.EAA12293>