Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/fdisk Add a large comment about disk geometries.
details: https://anonhg.NetBSD.org/src/rev/15cbf51fac80
branches: trunk
changeset: 750215:15cbf51fac80
user: dsl <dsl%NetBSD.org@localhost>
date: Sun Dec 20 17:32:09 2009 +0000
description:
Add a large comment about disk geometries.
Rename (with #defines) the variables use for aligning partitions to
separate them from the bios geometry.
All in advance of allowing other partition alignments (eg 2048 sectors).
diffstat:
sbin/fdisk/fdisk.c | 118 +++++++++++++++++++++++++++++++++++-----------------
1 files changed, 78 insertions(+), 40 deletions(-)
diffs (266 lines):
diff -r 583a8ffb0f20 -r 15cbf51fac80 sbin/fdisk/fdisk.c
--- a/sbin/fdisk/fdisk.c Sun Dec 20 16:59:39 2009 +0000
+++ b/sbin/fdisk/fdisk.c Sun Dec 20 17:32:09 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdisk.c,v 1.126 2009/12/17 14:27:49 pooka Exp $ */
+/* $NetBSD: fdisk.c,v 1.127 2009/12/20 17:32:09 dsl Exp $ */
/*
* Mach Operating System
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: fdisk.c,v 1.126 2009/12/17 14:27:49 pooka Exp $");
+__RCSID("$NetBSD: fdisk.c,v 1.127 2009/12/20 17:32:09 dsl Exp $");
#endif /* not lint */
#define MBRPTYPENAMES
@@ -120,9 +120,6 @@
#define GPT_TYPE(offs) ((offs) == GPT_HDR_BLKNO ? "primary" : "secondary")
-#define LBUF 100
-static char lbuf[LBUF];
-
#ifndef PRIdaddr
#define PRIdaddr PRId64
#endif
@@ -131,17 +128,6 @@
#define _PATH_DEFDISK "/dev/rwd0d"
#endif
-const char *disk = _PATH_DEFDISK;
-
-struct disklabel disklabel; /* disk parameters */
-
-unsigned int cylinders, sectors, heads;
-daddr_t disksectors;
-#define cylindersectors (heads * sectors)
-
-struct mbr_sector mboot;
-
-
struct {
struct mbr_sector *ptn; /* array of pbrs */
daddr_t base; /* first sector of ext. ptn */
@@ -151,6 +137,15 @@
int is_corrupt; /* 1 if extended chain illegal */
} ext;
+#define LBUF 100
+static char lbuf[LBUF];
+
+const char *disk = _PATH_DEFDISK;
+
+struct disklabel disklabel; /* disk parameters */
+
+struct mbr_sector mboot;
+
const char *boot_dir = DEFAULT_BOOTDIR;
char *boot_path = 0; /* name of file we actually opened */
@@ -162,6 +157,45 @@
#define OPTIONS "0123FSafiluvs:b:c:E:r:w:"
#endif
+/*
+ * Disk geometry and partition alignment.
+ *
+ * Modern disks do not have a fixed geomery and will always give a 'faked'
+ * geometry that matches the ATA standard - max 16 heads and 256 sec/track.
+ * The ATA geometry allows access to 2^28 sectors (as does LBA mode).
+ *
+ * The BIOS calls originally used an 8bit register for cylinder, head and
+ * sector. Later 2 bits were stolen from the sector number and added to
+ * cylinder number. The BIOS will translate this faked geometry either to
+ * the geometry reported by the disk, or do LBA reads (possibly LBA48).
+ * BIOS CHS reads have all sorts of limits, but 2^24 is absolute.
+ * For historic reasons the BIOS geometry is the called the dos geometry!
+ *
+ * If you know the disks real geometry it is usually worth aligning
+ * disk partitions to cylinder boundaries (certainly traditional!).
+ * For 'mbr' disks this has always been done with the BIOS geometry.
+ * The first track (typically 63 sectors) is reserved because the first
+ * sector is used for boot code. Similarly the data partition in an
+ * extended partition will start one track in. If an extended partition
+ * starts at the beginning of the disk you lose 2 tracks.
+ *
+ * However non-magnetic media in particular has physical sectors that are
+ * not the same size as those reported, so has to do read modify write
+ * sequences for misaligned transfers. The alignment of partitions to
+ * cylinder boundaries makes this happen all the time.
+ *
+ * It is thus sensible to align partitions on a sensible sector boundary.
+ * For instance 1MB (2048 sectors).
+ * Common code can do this by using a geometry with 1 head and 2048
+ * sectors per track.
+ */
+
+/* Disks reported geometry and overall size from device driver */
+unsigned int cylinders, sectors, heads;
+daddr_t disksectors;
+#define cylindersectors (heads * sectors)
+
+/* Geometry from the BIOS */
unsigned int dos_cylinders;
unsigned int dos_heads;
unsigned int dos_sectors;
@@ -180,6 +214,10 @@
#define MAXSECTOR 63
int partition = -1;
+/* Alignment of partition, and offset if first sector unusable */
+#define ptn_alignment dos_cylindersectors
+#define ptn_offset dos_sectors
+
int fd = -1, wfd = -1, *rfd = &fd;
char *disk_file = NULL;
char *disk_type = NULL;
@@ -745,8 +783,8 @@
indent, "", start, size);
if (size != 0) {
printf(" (%u MB, Cyls ", SEC_TO_MB(size));
- if (v_flag == 0 && le32toh(partp->mbrp_start) == dos_sectors)
- pr_cyls(start - dos_sectors, 0);
+ if (v_flag == 0 && le32toh(partp->mbrp_start) == ptn_offset)
+ pr_cyls(start - ptn_offset, 0);
else
pr_cyls(start, 0);
printf("-");
@@ -1676,8 +1714,8 @@
partp = &ext.ptn[part - 1].mbr_parts[1];
ext.ptn[part].mbr_parts[1] = *partp;
/* and prev onto us */
- partp->mbrp_start = htole32(start - dos_sectors - ext.base);
- partp->mbrp_size = htole32(size + dos_sectors);
+ partp->mbrp_start = htole32(start - ptn_offset - ext.base);
+ partp->mbrp_size = htole32(size + ptn_offset);
}
partp->mbrp_type = 5; /* as used by win98 */
partp->mbrp_flag = 0;
@@ -1701,7 +1739,7 @@
if (start == 0)
return "Sector zero is reserved for the MBR";
#if 0
- if (start < dos_sectors)
+ if (start < ptn_offset)
/* This is just a convention, not a requirement */
return "Track zero is reserved for the BIOS";
#endif
@@ -1803,7 +1841,7 @@
}
} else {
/* must create an empty slot */
- add_ext_ptn(start, dos_sectors);
+ add_ext_ptn(start, ptn_offset);
ext.ptn[0].mbr_parts[1].mbrp_start = htole32(ext.base
- start);
}
@@ -1828,8 +1866,8 @@
return "Nested extended partitions are not allowed";
/* allow one track at start for extended partition header */
- start -= dos_sectors;
- size += dos_sectors;
+ start -= ptn_offset;
+ size += ptn_offset;
if (start < ext.base || start + size > ext.limit)
return "Outside bounds of extended partition";
@@ -1844,7 +1882,7 @@
+ le32toh(ext.ptn[p].mbr_parts[0].mbrp_size);
if (p == 0)
p_s += le32toh(ext.ptn[p].mbr_parts[0].mbrp_start)
- - dos_sectors;
+ - ptn_offset;
if (start < p_e && start + size > p_s) {
if (!f_flag)
return "Overlaps another extended partition";
@@ -1930,23 +1968,23 @@
if (ext.ptn[p].mbr_parts[0].mbrp_type == 0)
continue;
n_s = ext_offset(p);
- if (n_s > start + dos_sectors)
+ if (n_s > start + ptn_offset)
break;
start = ext_offset(p)
+ le32toh(ext.ptn[p].mbr_parts[0].mbrp_start)
+ le32toh(ext.ptn[p].mbr_parts[0].mbrp_size);
}
- if (ext.limit - start <= dos_sectors) {
+ if (ext.limit - start <= ptn_offset) {
printf("No space in extended partition\n");
return 0;
}
- start += dos_sectors;
+ start += ptn_offset;
}
if (!s_flag && sysid == 0 && !extended) {
/* same for non-extended partition */
/* first see if old start is free */
- if (start < dos_sectors)
+ if (start < ptn_offset)
start = 0;
for (p = 0; start != 0 && p < MBR_PART_COUNT; p++) {
if (mboot.mbr_parts[p].mbrp_type == 0)
@@ -1958,7 +1996,7 @@
}
if (start == 0) {
/* Look for first gap */
- start = dos_sectors;
+ start = ptn_offset;
for (p = 0; p < MBR_PART_COUNT; p++) {
if (mboot.mbr_parts[p].mbrp_type == 0)
continue;
@@ -2041,9 +2079,9 @@
if (size == 0 || size > lim)
size = lim;
fl = DEC_SEC;
- if (start % dos_cylindersectors == dos_sectors)
+ if (start % ptn_alignment == ptn_offset)
fl |= DEC_RND_DOWN;
- if (start == 2 * dos_sectors)
+ if (start == 2 * ptn_offset)
fl |= DEC_RND_DOWN | DEC_RND_DOWN_2;
size = decimal("size", size, fl, 0, lim);
#ifdef BOOTSEL
@@ -2110,7 +2148,7 @@
if (extended) {
if (part != -1)
delete_ext_ptn(part);
- if (start == ext.base + dos_sectors)
+ if (start == ext.base + ptn_offset)
/* First one must have been free */
part = 0;
else
@@ -2684,21 +2722,21 @@
if (valid || !strncasecmp(cp, "mb", len)) {
acc *= SEC_IN_1M;
/* round to whole number of cylinders */
- acc += dos_cylindersectors / 2;
- acc /= dos_cylindersectors;
+ acc += ptn_alignment / 2;
+ acc /= ptn_alignment;
valid = 1;
}
if (valid || !strncasecmp(cp, "cyl", len)) {
- acc *= dos_cylindersectors;
+ acc *= ptn_alignment;
/* adjustments for cylinder boundary */
if (acc == 0 && flags & DEC_RND_0)
- acc += dos_sectors;
+ acc += ptn_offset;
if (flags & DEC_RND)
- acc += dos_sectors;
+ acc += ptn_offset;
if (flags & DEC_RND_DOWN)
- acc -= dos_sectors;
+ acc -= ptn_offset;
if (flags & DEC_RND_DOWN_2)
- acc -= dos_sectors;
+ acc -= ptn_offset;
cp += len;
}
}
Home |
Main Index |
Thread Index |
Old Index