summaryrefslogtreecommitdiff
path: root/sbin/fdisk
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>1998-09-14 03:54:36 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>1998-09-14 03:54:36 +0000
commit430fb2f326b8644b48e9dfac81edad297a72017d (patch)
tree3f5611ed885aa0e2a060ca4f738794819fbb6ef5 /sbin/fdisk
parent62d203b1aea6a5195937032bb27c074afa7e2f7c (diff)
Since on the powerpc, the system does not supply the user with
bios valid cyl,head,sector information (the information comes from the sd driver) I have made some changes to fdisk to do the following. Allow the powerpc to specify values larger than the bios limits. All platforms now have code that will translate the LBA values in the mbr into CHS values according to the disk geometry. This occurs if the start and ending CHS values have been stored as 0xffffff. If writing to the disk and one of the values of a partition violates the bios limits, it writes the requested values in the LBA fields , and stores 0xffffff for the starting and ending CHS values. This should not change the default formatting of any existing system other than the CHS and LBA values should always match given the detected geometry of the disk.
Diffstat (limited to 'sbin/fdisk')
-rw-r--r--sbin/fdisk/cmd.c56
-rw-r--r--sbin/fdisk/fdisk.c4
-rw-r--r--sbin/fdisk/mbr.c49
-rw-r--r--sbin/fdisk/mbr.h4
-rw-r--r--sbin/fdisk/part.c69
-rw-r--r--sbin/fdisk/part.h4
-rw-r--r--sbin/fdisk/user.c38
7 files changed, 135 insertions, 89 deletions
diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c
index 2068fd042ad..88193040b5b 100644
--- a/sbin/fdisk/cmd.c
+++ b/sbin/fdisk/cmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd.c,v 1.19 1998/09/08 11:03:15 pefo Exp $ */
+/* $OpenBSD: cmd.c,v 1.20 1998/09/14 03:54:34 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -57,38 +57,9 @@ Xreinit(cmd, disk, mbr, tt, offset)
/* Copy template MBR */
MBR_make(tt, buf);
- MBR_parse(buf, 0, 0, mbr);
-
- /* Fix up given mbr for this disk */
- mbr->part[0].flag = 0;
- mbr->part[1].flag = 0;
- mbr->part[2].flag = 0;
- mbr->part[3].flag = DOSACTIVE;
- mbr->signature = DOSMBR_SIGNATURE;
-
- /* Use whole disk, save for first head, on first cyl. */
- mbr->part[3].id = DOSPTYP_OPENBSD;
- mbr->part[3].scyl = 0;
- mbr->part[3].shead = 1;
- mbr->part[3].ssect = 1;
-
- /* Go right to the end */
- mbr->part[3].ecyl = disk->real->cylinders - 1;
- mbr->part[3].ehead = disk->real->heads - 1;
- mbr->part[3].esect = disk->real->sectors;
-
- /* Fix up start/length fields */
- PRT_fix_BN(disk, &mbr->part[3]);
-
-#if defined(__powerpc__)
- /* Now fix up for the MS-DOS boot partition on PowerPC. */
- mbr->part[0].flag = DOSACTIVE; /* Boot from dos part */
- mbr->part[3].flag = 0;
- mbr->part[3].ns += mbr->part[3].bs;
- mbr->part[3].bs = mbr->part[0].bs + mbr->part[0].ns;
- mbr->part[3].ns -= mbr->part[3].bs;
- PRT_fix_CHS(disk, &mbr->part[3]);
-#endif
+ MBR_parse(disk, buf, 0, 0, mbr);
+
+ MBR_init(disk, mbr);
/* Tell em we did something */
printf("In memory copy is initialized to:\n");
@@ -107,18 +78,27 @@ Xdisk(cmd, disk, mbr, tt, offset)
mbr_t *tt;
int offset;
{
+ int maxcyl = 1024;
+ int maxhead = 256;
+ int maxsec = 64;
/* Print out disk info */
DISK_printmetrics(disk);
+#ifdef __powerpc__
+ maxcyl = 9999999;
+ maxhead = 9999999;
+ maxsec = 9999999;
+#endif
+
/* Ask for new info */
if (ask_yn("Change disk geometry?")) {
disk->real->cylinders = ask_num("BIOS Cylinders", ASK_DEC,
- disk->real->cylinders, 1, 1024, NULL);
+ disk->real->cylinders, 1, maxcyl, NULL);
disk->real->heads = ask_num("BIOS Heads", ASK_DEC,
- disk->real->heads, 1, 256, NULL);
+ disk->real->heads, 1, maxhead, NULL);
disk->real->sectors = ask_num("BIOS Sectors", ASK_DEC,
- disk->real->sectors, 1, 64, NULL);
+ disk->real->sectors, 1, maxsec, NULL);
disk->real->size = disk->real->cylinders * disk->real->heads
* disk->real->sectors;
@@ -196,6 +176,10 @@ Xedit(cmd, disk, mbr, tt, offset)
EDIT("Partition offset", ASK_DEC, pp->bs, 0,
disk->real->size, NULL);
m = MAX(pp->ns, disk->real->size - pp->bs);
+ if ( m > disk->real->size - pp->bs) {
+ /* dont have default value extend beyond end of disk */
+ m = disk->real->size - pp->bs;
+ }
EDIT("Partition size", ASK_DEC, pp->ns, 1,
m, NULL);
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c
index adaa036d255..ebcee38392a 100644
--- a/sbin/fdisk/fdisk.c
+++ b/sbin/fdisk/fdisk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdisk.c,v 1.29 1997/10/28 03:12:14 deraadt Exp $ */
+/* $OpenBSD: fdisk.c,v 1.30 1998/09/14 03:54:34 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -148,7 +148,7 @@ main(argc, argv)
err(1, "open mbr file");
MBR_read(fd, 0, mbr_buf);
close(fd);
- MBR_parse(mbr_buf, 0, 0, &mbr);
+ MBR_parse(&disk, mbr_buf, 0, 0, &mbr);
/* Punt if no i or m */
if ((i_flag + m_flag) != 1)
diff --git a/sbin/fdisk/mbr.c b/sbin/fdisk/mbr.c
index b19718bd182..da458a81159 100644
--- a/sbin/fdisk/mbr.c
+++ b/sbin/fdisk/mbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbr.c,v 1.6 1997/10/21 22:49:33 provos Exp $ */
+/* $OpenBSD: mbr.c,v 1.7 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -45,9 +45,52 @@
#include "mbr.h"
#include "part.h"
+MBR_init(disk_t *disk, mbr_t *mbr)
+{
+ /* Fix up given mbr for this disk */
+ mbr->part[0].flag = 0;
+ mbr->part[1].flag = 0;
+ mbr->part[2].flag = 0;
+
+ mbr->part[3].flag = DOSACTIVE;
+ mbr->signature = DOSMBR_SIGNATURE;
+
+ /* Use whole disk, save for first head, on first cyl. */
+ mbr->part[3].id = DOSPTYP_OPENBSD;
+ mbr->part[3].scyl = 0;
+ mbr->part[3].shead = 1;
+ mbr->part[3].ssect = 1;
+
+ /* Go right to the end */
+ mbr->part[3].ecyl = disk->real->cylinders - 1;
+ mbr->part[3].ehead = disk->real->heads - 1;
+ mbr->part[3].esect = disk->real->sectors;
+
+ /* Fix up start/length fields */
+ PRT_fix_BN(disk, &mbr->part[3]);
+
+#if defined(__powerpc__)
+ /* Now fix up for the MS-DOS boot partition on PowerPC. */
+ mbr->part[0].flag = DOSACTIVE; /* Boot from dos part */
+ mbr->part[3].flag = 0;
+ mbr->part[3].ns += mbr->part[3].bs;
+ mbr->part[3].bs = mbr->part[0].bs + mbr->part[0].ns;
+ mbr->part[3].ns -= mbr->part[3].bs;
+ PRT_fix_CHS(disk, &mbr->part[3]);
+ if ((mbr->part[3].shead != 1) || (mbr->part[3].ssect != 1)) {
+ /* align the parition on a cylinder boundary */
+ mbr->part[3].shead = 0;
+ mbr->part[3].ssect = 1;
+ mbr->part[3].scyl += 1;
+ }
+ /* Fix up start/length fields */
+ PRT_fix_BN(disk, &mbr->part[3]);
+#endif
+}
void
-MBR_parse(mbr_buf, offset, reloff, mbr)
+MBR_parse(disk, mbr_buf, offset, reloff, mbr)
+ disk_t *disk;
char *mbr_buf;
off_t offset;
off_t reloff;
@@ -63,7 +106,7 @@ MBR_parse(mbr_buf, offset, reloff, mbr)
mbr->signature = getshort(&mbr_buf[MBR_SIG_OFF]);
for (i = 0; i < NDOSPART; i++)
- PRT_parse(&mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i],
+ PRT_parse(disk, &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i],
offset, reloff,
&mbr->part[i]);
}
diff --git a/sbin/fdisk/mbr.h b/sbin/fdisk/mbr.h
index 5a8efae6794..d91f14a5a79 100644
--- a/sbin/fdisk/mbr.h
+++ b/sbin/fdisk/mbr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbr.h,v 1.3 1997/10/21 22:49:34 provos Exp $ */
+/* $OpenBSD: mbr.h,v 1.4 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -58,7 +58,7 @@ typedef struct _mbr_t {
/* Prototypes */
void MBR_print_disk __P((char *));
void MBR_print __P((mbr_t *));
-void MBR_parse __P((char *, off_t, off_t, mbr_t *));
+void MBR_parse __P((disk_t *, char *, off_t, off_t, mbr_t *));
void MBR_make __P((mbr_t *, char *));
int MBR_read __P((int, off_t, char *));
int MBR_write __P((int, off_t, char *));
diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c
index 53d223d4769..02763963061 100644
--- a/sbin/fdisk/part.c
+++ b/sbin/fdisk/part.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.c,v 1.8 1998/02/19 20:48:08 deraadt Exp $ */
+/* $OpenBSD: part.c,v 1.9 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -127,7 +127,8 @@ PRT_ascii_id(id)
}
void
-PRT_parse(prt, offset, reloff, partn)
+PRT_parse(disk, prt, offset, reloff, partn)
+ disk_t *disk;
void *prt;
off_t offset;
off_t reloff;
@@ -135,7 +136,19 @@ PRT_parse(prt, offset, reloff, partn)
{
unsigned char *p = prt;
off_t off;
-
+ int need_fix_chs = 0;
+
+ /* dont check fields 0 and 4, they are flag and id, always preserved */
+ if ((p[1] == 0xff) &&
+ (p[2] == 0xff) &&
+ (p[3] == 0xff) &&
+ (p[5] == 0xff) &&
+ (p[6] == 0xff) &&
+ (p[7] == 0xff))
+ {
+ /* CHS values invalid */
+ need_fix_chs =1;
+ }
partn->flag = *p++;
partn->shead = *p++;
@@ -153,8 +166,28 @@ PRT_parse(prt, offset, reloff, partn)
partn->bs = getlong(p) + off;
partn->ns = getlong(p+4);
+
+ if (need_fix_chs == 1) {
+ printf("warning MBR CHS values invalid, translating LBA values\n");
+ PRT_fix_CHS(disk, partn);
+ }
}
+int
+PRT_check_chs(partn)
+ prt_t *partn;
+{
+ if ( (partn->shead > 255) ||
+ (partn->ssect >63) ||
+ (partn->scyl > 1023) ||
+ (partn->ehead >255) ||
+ (partn->esect >63) ||
+ (partn->ecyl > 1023) )
+ {
+ return 0;
+ }
+ return 1;
+}
void
PRT_make(partn, offset, reloff, prt)
prt_t *partn;
@@ -165,16 +198,30 @@ PRT_make(partn, offset, reloff, prt)
unsigned char *p = prt;
off_t off = partn->id != DOSPTYP_EXTEND ? offset : reloff;
- *p++ = partn->flag & 0xFF;
- *p++ = partn->shead & 0xFF;
- *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
- *p++ = partn->scyl & 0xFF;
+ if (PRT_check_chs(partn)) {
+ *p++ = partn->flag & 0xFF;
- *p++ = partn->id & 0xFF;
+ *p++ = partn->shead & 0xFF;
+ *p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
+ *p++ = partn->scyl & 0xFF;
- *p++ = partn->ehead & 0xFF;
- *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
- *p++ = partn->ecyl & 0xFF;
+ *p++ = partn->id & 0xFF;
+
+ *p++ = partn->ehead & 0xFF;
+ *p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
+ *p++ = partn->ecyl & 0xFF;
+ } else {
+ /* should this really keep flag, id and set others to 0xff? */
+ *p++ = partn->flag & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = partn->id & 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ *p++ = 0xFF;
+ printf("Warning CHS values out of bounds only saving LBA values\n");
+ }
putlong(p, partn->bs - off);
putlong(p+4, partn->ns);
diff --git a/sbin/fdisk/part.h b/sbin/fdisk/part.h
index f42f6df2d51..073b6ac57f9 100644
--- a/sbin/fdisk/part.h
+++ b/sbin/fdisk/part.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.h,v 1.4 1997/10/21 22:49:35 provos Exp $ */
+/* $OpenBSD: part.h,v 1.5 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -46,7 +46,7 @@ typedef struct _prt_t {
/* Prototypes */
void PRT_printall __P((void));
char *PRT_ascii_id __P((int));
-void PRT_parse __P((void *, off_t, off_t, prt_t *));
+void PRT_parse __P((disk_t *, void *, off_t, off_t, prt_t *));
void PRT_make __P((prt_t *, off_t, off_t, void *));
void PRT_print __P((int, prt_t *));
diff --git a/sbin/fdisk/user.c b/sbin/fdisk/user.c
index 7cd9497c63c..f771fe965b5 100644
--- a/sbin/fdisk/user.c
+++ b/sbin/fdisk/user.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: user.c,v 1.13 1998/09/08 11:03:16 pefo Exp $ */
+/* $OpenBSD: user.c,v 1.14 1998/09/14 03:54:35 rahnds Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -74,36 +74,8 @@ USER_init(disk, tt)
int fd;
char mbr_buf[DEV_BSIZE];
- /* Fix up given mbr for this disk */
- tt->part[0].flag = 0;
- tt->part[1].flag = 0;
- tt->part[2].flag = 0;
- tt->part[3].flag = DOSACTIVE;
- tt->signature = DOSMBR_SIGNATURE;
-
- /* Use whole disk, save for first head, on first cyl. */
- tt->part[3].id = DOSPTYP_OPENBSD;
- tt->part[3].scyl = 0;
- tt->part[3].shead = 1;
- tt->part[3].ssect = 1;
-
- /* Go right to the end */
- tt->part[3].ecyl = disk->real->cylinders;
- tt->part[3].ehead = disk->real->heads;
- tt->part[3].esect = disk->real->sectors;
-
- /* Fix up start/length fields */
- PRT_fix_BN(disk, &tt->part[3]);
-
-#if defined(__powerpc__)
- /* Now fix up for the MS-DOS boot partition on PowerPC. */
- tt->part[0].flag = DOSACTIVE; /* Boot from dos part */
- tt->part[3].flag = 0;
- tt->part[3].ns += tt->part[3].bs;
- tt->part[3].bs = tt->part[0].bs + tt->part[0].ns;
- tt->part[3].ns -= tt->part[3].bs;
- PRT_fix_CHS(disk, &tt->part[3]);
-#endif
+ MBR_init(disk, tt);
+
/* Write sector 0 */
printf("\a\n"
"\t-----------------------------------------------------\n"
@@ -147,7 +119,7 @@ USER_modify(disk, tt, offset, reloff)
DISK_close(fd);
/* Parse the sucker */
- MBR_parse(mbr_buf, offset, reloff, &mbr);
+ MBR_parse(disk, mbr_buf, offset, reloff, &mbr);
printf("Enter 'help' for information\n");
@@ -222,7 +194,7 @@ USER_print_disk(disk)
do {
MBR_read(fd, (off_t)offset, mbr_buf);
- MBR_parse(mbr_buf, offset, firstoff, &mbr);
+ MBR_parse(disk, mbr_buf, offset, firstoff, &mbr);
printf("Offset: %d\t", (int)offset);
MBR_print(&mbr);