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>