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>
index | next in thread | raw e-mail
>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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610130249.EAA12293>
