Loading learning content...
Disk geometry refers to the complete specification of how a storage device is organized—the number of cylinders, heads, sectors per track, sector size, and total capacity. This characterization forms the interface between physical storage medium and the software that must read and write data.
Historically, geometry was a precise description of physical reality: the actual number of platters, the measurable track count, and the manufactured sectors per track. Today, geometry has become largely an abstraction—numbers reported for compatibility rather than physical truth.
This page provides an exhaustive examination of disk geometry: how it's defined, how it's discovered, how physical and logical geometry diverge, and what modern operating systems actually need to know about the storage devices they manage.
By the end of this page, you will understand: the components of disk geometry specifications; the distinction between physical and logical geometry; geometry discovery via ATA IDENTIFY and SCSI commands; BIOS geometry translation and reporting; zone bit recording's impact on "true" geometry; and practical geometry considerations for operating systems.
A complete geometry specification describes the structure of storage at multiple levels. Let's define each component precisely.
| Component | Symbol | Description | Units |
|---|---|---|---|
| Cylinders | C | Total number of track positions (across all surfaces at same radius) | Count |
| Heads | H | Number of read/write heads (typically = surfaces) | Count |
| Sectors per Track | S | Number of sectors in each track | Count |
| Bytes per Sector | B | Size of each sector | 512 or 4096 |
Derived Values:
$$\text{Sectors per Cylinder} = H \times S$$ $$\text{Total Sectors} = C \times H \times S$$ $$\text{Total Capacity} = C \times H \times S \times B$$
With LBA, geometry simplifies to:
| Component | Description | Typical Values |
|---|---|---|
| Total Sectors | Number of addressable LBA blocks | 2 billion+ |
| Logical Sector Size | Size of each LBA block as seen by OS | 512 or 4096 bytes |
| Physical Sector Size | Actual hardware sector size | 512 or 4096 bytes |
| Optimal I/O Size | Recommended transfer unit | Often matches physical sector |
Modern storage standards include additional parameters:
| Parameter | Description | Significance |
|---|---|---|
| Write Cache | Size of volatile write buffer | Affects durability |
| Queue Depth | Maximum queued commands (NCQ/TCQ) | Affects concurrency |
| Rotation Rate | RPM (or solid-state indicator, 0 or 1) | Helps scheduler |
| Form Factor | Physical size (3.5", 2.5", M.2, etc.) | Compatibility |
| Alignment Granularity | Optimal alignment boundary | Critical for 4Kn/512e |
| Physical/Logical per Physical | Logical sectors per physical sector | Identifies 512e |
The shift from CHS to LBA geometry reflects storage's transition from physical addressing to logical addressing. CHS geometry described what the drive physically contained; LBA geometry describes what the drive presents to software. The two may have little correlation.
A fundamental concept in modern storage is the divergence between what the drive physically contains and what it presents to the host system.
Physical geometry describes the actual manufactured structure:
Physical geometry is NOT reported to the host. It's internal to the drive, inaccessible via standard commands, and changes with every drive model.
Logical geometry is what the drive reports to the BIOS and operating system:
The physical/logical split exists for critical reasons:
Compatibility: Operating systems expect certain geometry formats; drives accommodate legacy expectations.
Defect Hiding: Physical defects are transparently remapped; the host sees only usable LBA space.
Zone Complexity: Variable sectors-per-track (ZBR) is too complex for simple CHS; LBA abstracts it.
Flexibility: Drive internals can evolve without OS changes; only LBA capacity matters.
Performance Optimization: Drive firmware optimizes layout, skew, and mapping—invisible to host.
The drive's firmware maintains translation structures:
LBA Request (e.g., LBA 1,000,000,000)
↓
Zone Table Lookup → Zone 5 (cylinders 200,000-249,999)
↓
In-Zone Offset Calculation
↓
Physical (Cylinder, Head, Sector) = (215,423, 7, 342)
↓
Defect Table Check → No remap needed
↓
Actuator positions head to cylinder 215,423
↓
Read sector 342 on surface 7
Physical geometry is not standardized or documented. Each manufacturer, and often each drive model, has unique internal layouts. Data recovery tools that bypass the firmware and read physical locations require vendor-specific knowledge—often proprietary or reverse-engineered.
Operating systems and BIOS discover disk geometry through standardized commands issued to the storage controller. Here are the key mechanisms.
For ATA/SATA drives, the IDENTIFY DEVICE command returns a 512-byte structure containing geometry and capability information:
Key Geometry Fields:
| Word | Bits | Field | Description |
|---|---|---|---|
| 1 | 15-0 | Logical Cylinders | Default CHS cylinders (obsolete, usually 16383) |
| 3 | 15-0 | Logical Heads | Default CHS heads (obsolete, usually 16) |
| 6 | 15-0 | Logical Sectors/Track | Default CHS sectors (obsolete, usually 63) |
| 60-61 | 31-0 | Total LBA Sectors (28-bit) | User addressable LBA sectors (obsolete) |
| 100-103 | 63-0 | Total LBA Sectors (48-bit) | User addressable LBA48 sectors |
| 106 | 15-0 | Physical/Logical Sector Info | Bit 12: Logical sector >512B; Bit 13: Multiple logical per physical |
| 117-118 | 31-0 | Logical Sector Size | Size in words (if bit 12 of word 106 is set) |
| 209 | 15-0 | Alignment Offset | Logical sector offset within physical sector |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
/* * ATA IDENTIFY DEVICE Data Structure Parser * * Demonstrates extraction of geometry information from * the 512-byte IDENTIFY DEVICE response. */ #include <stdint.h>#include <stdio.h>#include <stdbool.h> /* IDENTIFY DEVICE data is 256 16-bit words (512 bytes) */typedef struct { uint16_t word[256];} IdentifyDeviceData; /* Geometry information extracted from IDENTIFY DEVICE */typedef struct { /* CHS geometry (largely obsolete) */ uint16_t cylinders; uint16_t heads; uint16_t sectors_per_track; /* LBA capacity */ uint32_t lba28_sectors; /* 28-bit LBA capacity */ uint64_t lba48_sectors; /* 48-bit LBA capacity */ /* Sector sizes */ uint32_t logical_sector_size; /* Bytes per logical sector */ uint32_t physical_sector_size; /* Bytes per physical sector */ uint16_t alignment_offset; /* Sector alignment offset */ /* Capabilities */ bool lba48_supported; bool ncq_supported; uint8_t ncq_queue_depth; uint16_t rotation_rate; /* 0x0001 = SSD, other = RPM */} DriveGeometry; /* * Parse IDENTIFY DEVICE response into usable geometry */DriveGeometry parse_identify_device(const IdentifyDeviceData* id) { DriveGeometry geom = {0}; /* Word 1, 3, 6: Legacy CHS geometry (usually fabricated) */ geom.cylinders = id->word[1]; geom.heads = id->word[3]; geom.sectors_per_track = id->word[6]; /* Words 60-61: 28-bit LBA capacity */ geom.lba28_sectors = id->word[60] | ((uint32_t)id->word[61] << 16); /* Words 83, 86: Check for LBA48 support */ if ((id->word[83] & (1 << 10)) && (id->word[86] & (1 << 10))) { geom.lba48_supported = true; /* Words 100-103: 48-bit LBA capacity */ geom.lba48_sectors = (uint64_t)id->word[100] | ((uint64_t)id->word[101] << 16) | ((uint64_t)id->word[102] << 32) | ((uint64_t)id->word[103] << 48); } /* Word 106: Physical/Logical sector size info */ uint16_t sector_info = id->word[106]; if (sector_info & (1 << 14)) { /* Word 106 valid */ if (sector_info & (1 << 12)) { /* Logical sector size != 512 bytes */ /* Words 117-118 contain size in words */ geom.logical_sector_size = ((id->word[118] << 16) | id->word[117]) * 2; } else { geom.logical_sector_size = 512; } if (sector_info & (1 << 13)) { /* Multiple logical sectors per physical sector */ uint8_t ratio = 1 << (sector_info & 0x0F); geom.physical_sector_size = geom.logical_sector_size * ratio; } else { geom.physical_sector_size = geom.logical_sector_size; } } else { /* Word 106 not valid; assume 512-byte sectors */ geom.logical_sector_size = 512; geom.physical_sector_size = 512; } /* Word 209: Alignment offset */ if (id->word[209] & (1 << 14)) { geom.alignment_offset = id->word[209] & 0x3FFF; } /* Word 75: NCQ Queue Depth */ if (id->word[75] != 0) { geom.ncq_supported = true; geom.ncq_queue_depth = (id->word[75] & 0x1F) + 1; /* 0-based */ } /* Word 217: Rotation Rate (NVM: 0x0001) */ geom.rotation_rate = id->word[217]; return geom;} /* * Calculate and display capacity */void print_geometry(const DriveGeometry* geom) { printf("ATA Drive Geometry:"); printf(" CHS (Legacy): %u/%u/%u", geom->cylinders, geom->heads, geom->sectors_per_track); uint64_t sectors = geom->lba48_supported ? geom->lba48_sectors : geom->lba28_sectors; uint64_t capacity = sectors * geom->logical_sector_size; printf(" LBA Sectors: %llu", (unsigned long long)sectors); printf(" Logical Sector Size: %u bytes", geom->logical_sector_size); printf(" Physical Sector Size: %u bytes", geom->physical_sector_size); printf(" Capacity: %.2f GiB (%.2f GB)", capacity / (1024.0 * 1024.0 * 1024.0), capacity / 1e9); if (geom->logical_sector_size != geom->physical_sector_size) { printf(" Note: 512e emulation mode"); } if (geom->rotation_rate == 1) { printf(" Type: Solid State Drive (SSD)"); } else if (geom->rotation_rate > 0) { printf(" Type: HDD @ %u RPM", geom->rotation_rate); }}For SCSI/SAS devices, geometry is discovered differently:
READ CAPACITY (10/16):
MODE SENSE - Rigid Disk Geometry Page (04h):
| Byte | Field | Description |
|---|---|---|
| 1-3 | Number of Cylinders | 24-bit (not reflecting physical) |
| 4 | Number of Heads | 8-bit |
| 5-7 | Write Precompensation | Starting cylinder |
| 8-10 | Reduced Write Current | Starting cylinder |
| 12-13 | Medium Rotation Rate | RPM (0001h = SSD) |
Note: SCSI geometry pages often return fabricated values for compatibility, just like ATA.
BIOS reports geometry via INT 13h function 08h:
MOV AH, 08h ; Get Drive Parameters
MOV DL, 80h ; First hard drive
INT 13h
; Returns:
; CH = max cylinder (low 8 bits)
; CL = max sector (bits 0-5) + cylinder high (bits 6-7)
; DH = max head
; DL = number of drives
These values are BIOS-translated and may not match drive-reported or physical values.
Modern operating systems primarily need just three values: total LBA sectors, logical sector size, and physical sector size. CHS geometry is only relevant for BIOS boot compatibility. File systems and drivers work entirely in LBA.
Zone Bit Recording (ZBR) fundamentally complicates the concept of disk geometry. Since sectors-per-track varies with radial position, there is no single "geometry" that describes the entire drive.
A modern drive might have 20-50 zones:
| Zone | Cylinder Range | Sectors/Track | Data Rate | LBA Range |
|---|---|---|---|---|
| 0 | 0-24,999 | 1008 | 250 MB/s | 0-403,199,999 |
| 1 | 25,000-49,999 | 984 | 244 MB/s | 403,200,000-796,799,999 |
| 2 | 50,000-74,999 | 960 | 238 MB/s | 796,800,000-1,180,799,999 |
| ... | ... | ... | ... | ... |
| 19 | 475,000-499,999 | 504 | 125 MB/s | ... |
Key Observations:
| Disk Region | Track Density | Sequential Speed | Typical Use |
|---|---|---|---|
| Outer 25% | Highest sectors/track | 100% (baseline) | OS, frequently accessed files |
| Middle 50% | Medium sectors/track | 75-85% | General data storage |
| Inner 25% | Lowest sectors/track | 50-60% | Archives, infrequently accessed data |
Traditional CHS assumes constant sectors-per-track:
$$\text{LBA} = (C \times H + Head) \times SPT + (S - 1)$$
With ZBR, SPT varies with cylinder. No constant formula can translate CHS to LBA correctly for all cylinders.
Solutions:
Report Fake Geometry: Drives report nonsensical CHS values (16383/16/63) that don't correspond to anything physical
Use LBA Exclusively: Modern software ignores CHS and addresses by LBA only
Firmware Translation: Internal firmware tables map LBA to true physical location considering zones
Short-stroking is deliberately using only a portion of a drive to maximize performance:
|-----Outer Zones-----|-----Middle Zones-----|-----Inner Zones-----|
| Used (Fast) | Unused | Unused |
50% 25% 25%
Benefits:
Applications:
Short-stroking requires understanding that LBAs 0 through N are on outer (faster) zones.
Fortunately, drive manufacturers consistently map LBA 0 to the outer edge. Lower LBA values are on faster outer tracks; higher LBA values are on slower inner tracks. This allows performance-aware placement without knowing internal geometry details.
Modern operating systems interact with disk geometry at multiple levels. Understanding these layers reveals why geometry matters (or doesn't) for different subsystems.
BIOS (Legacy Boot):
UEFI (Modern Boot):
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
/* * Linux Kernel Block Device Geometry * * The kernel exposes geometry through sysfs and ioctl interfaces. * This demonstrates how geometry appears at the driver level. */ #include <linux/blkdev.h>#include <linux/hdreg.h> /* HDIO_GETGEO */ /* * struct hd_geometry - Legacy CHS geometry (mostly unused) * * This structure dates from the era of IDE drives with real CHS. * Modern drivers often return fabricated values for compatibility. */struct hd_geometry { unsigned char heads; /* Heads (usually 255 for compat) */ unsigned char sectors; /* Sectors/track (usually 63) */ unsigned short cylinders; /* Cylinders (derived from size) */ unsigned long start; /* Offset from partition start */}; /* * Modern kernel geometry is in the block device structure: */struct block_device_pseudo { sector_t nr_sects; /* Total sectors (512-byte) */ unsigned int logical_block_size; /* 512 or 4096 */ unsigned int physical_block_size; /* 512 or 4096 */ unsigned int alignment_offset; /* For 512e alignment */ unsigned int min_io_size; /* Minimum I/O size */ unsigned int opt_io_size; /* Optimal I/O size */}; /* * Block layer geometry discovery * * The SCSI and ATA layers populate these values from device queries. */void show_geometry_info(struct block_device* bdev) { struct request_queue* q = bdev_get_queue(bdev); printk("Block device geometry:"); printk(" Total sectors: %llu", (unsigned long long)i_size_read(bdev->bd_inode) / 512); printk(" Logical block size: %u", bdev_logical_block_size(bdev)); printk(" Physical block size: %u", bdev_physical_block_size(bdev)); printk(" Alignment offset: %u", bdev_alignment_offset(bdev)); printk(" Optimal I/O size: %u", bdev_io_opt(bdev)); /* Queue limits (derived from device properties) */ printk(" Max sectors per request: %u", queue_max_sectors(q)); printk(" Max segments per request: %u", queue_max_segments(q)); /* For checking 512e vs 4Kn */ if (bdev_logical_block_size(bdev) != bdev_physical_block_size(bdev)) { printk(" Note: 512e emulation mode"); printk(" Logical/Physical ratio: %u", bdev_physical_block_size(bdev) / bdev_logical_block_size(bdev)); }} /* * sysfs exposes geometry at /sys/block/<dev>/queue/ * * Key files: * logical_block_size - Logical sector size (512 or 4096) * physical_block_size - Physical sector size * optimal_io_size - Optimal I/O size * alignment_offset - Partition alignment offset * minimum_io_size - Minimum I/O size * hw_sector_size - Hardware sector size (= physical) * rotational - 1 for HDD, 0 for SSD */File systems use geometry for layout decisions:
| Geometry Aspect | File System Use |
|---|---|
| Block size | ext4/XFS typically use 4096-byte blocks matching physical sector |
| Total sectors | Determines maximum file system size |
| Physical/logical ratio | mkfs tools align structures to physical sectors |
| Rotational hint | Enables/disables HDD-specific optimizations (prefetch, etc.) |
| Optimal I/O | Guides default read-ahead and stripe unit sizing |
Partitioning tools must consider geometry for alignment:
fdisk/parted Alignment:
GPT Partition Start:
Modern partitioning conventions start partitions at 1 MiB (2048 512-byte sectors) boundaries. This alignment works correctly with: 512-byte sectors, 4K sectors, 512e drives, RAID arrays (most stripe sizes), and SSD erase block boundaries. It's a safe default that avoids performance penalties.
The history of geometry translation reveals how the industry navigated capacity growth while maintaining backward compatibility.
Early drives had simple, directly addressable geometry:
IBM 350 (1956): 50 platters, 100 surfaces, 100 tracks/surface
IBM PC XT (1983): 4 heads, 306 cylinders, 17 sectors/track (10 MB)
IBM AT (1984): 4 heads, 615 cylinders, 17 sectors/track (20 MB)
CHS directly reflected physical structure. BIOS and drive agreed on geometry.
As drives grew, BIOS limits forced translation:
| Problem | BIOS Limit | Drive Reality | Translation |
|---|---|---|---|
| 504 MB barrier | 16 heads | 16+ heads | ECHS: multiply heads, divide cylinders |
| 2.1 GB barrier | Signed integer bug | - | BIOS updates |
| 7.88 GiB barrier | 1024 cyl × 256 heads × 63 sec | More cylinders | LBA translation mode |
Translation Types:
Drives and operating systems adopted LBA as the primary interface:
CHS geometry became purely a compatibility fiction:
Typical "geometry" reported: 16383 cylinders, 16 heads, 63 sectors
(This equals about 8 GB - drives just report this regardless of actual size)
With UEFI and GPT:
Current Reality:
UEFI boot loader reads ESP (EFI System Partition) via LBA
OS kernel queries: total sectors, logical sector size, physical sector size
File system formats based on total sectors and sector size
CHS geometry is never used
The only common use of CHS in modern systems is legacy BIOS boot. The MBR boot sector is loaded from CHS (0, 0, 1) or LBA 0. After that, bootloaders typically switch to LBA. Systems using UEFI bypass this entirely.
Here are practical commands and techniques for examining disk geometry on modern systems.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
#!/bin/bash# Comprehensive disk geometry examination on Linux DISK="/dev/sda" echo "=== Block Device Geometry for $DISK ===" # 1. Total sectors and sector sizesecho "--- Sector Information ---"cat /sys/block/sda/size # Total 512-byte sectorscat /sys/block/sda/queue/logical_block_sizecat /sys/block/sda/queue/physical_block_sizecat /sys/block/sda/queue/hw_sector_size # 2. Rotational status (HDD vs SSD)echo -n "Rotational (1=HDD, 0=SSD): "cat /sys/block/sda/queue/rotational # 3. I/O alignment informationecho "--- Alignment Info ---"echo -n "Minimum I/O size: "cat /sys/block/sda/queue/minimum_io_sizeecho -n "Optimal I/O size: "cat /sys/block/sda/queue/optimal_io_sizeecho -n "Alignment offset: "cat /sys/block/sda/alignment_offset # 4. hdparm detailed infoecho "--- hdparm -I (ATA IDENTIFY DEVICE) ---"sudo hdparm -I $DISK | grep -E "(Model|Serial|LBA|sector|Size|speed)" # 5. lsblk for high-level viewecho "--- lsblk detail ---"lsblk -d -o NAME,SIZE,PHY-SEC,LOG-SEC,ROTA,MODEL $DISK # 6. fdisk for partition and geometry infoecho "--- fdisk geometry ---"sudo fdisk -l $DISK | head -20 # 7. smartctl disk info (requires smartmontools)echo "--- SMART disk info ---"sudo smartctl -i $DISK | grep -E "(Model|Capacity|Sector|Rotation|Form)" # 8. Check for 512e (emulation) modeLOGICAL=$(cat /sys/block/sda/queue/logical_block_size)PHYSICAL=$(cat /sys/block/sda/queue/physical_block_size)if [ "$LOGICAL" != "$PHYSICAL" ]; then echo "*** Drive is in 512e emulation mode ***" echo " Logical: $LOGICAL, Physical: $PHYSICAL"fi # 9. Calculate capacitySECTORS=$(cat /sys/block/sda/size)SECTOR_SIZE=$LOGICALBYTES=$((SECTORS * SECTOR_SIZE))GB=$(echo "scale=2; $BYTES / 1000000000" | bc)GIB=$(echo "scale=2; $BYTES / 1073741824" | bc)echo "Calculated capacity: $GB GB ($GIB GiB)" # 10. blockdev for raw infoecho "--- blockdev info ---"sudo blockdev --report $DISK123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
# Comprehensive disk geometry examination on Windows # 1. Get disk information via Get-Disk$disk = Get-Disk -Number 0$disk | Format-List Number, FriendlyName, PartitionStyle, Size, LogicalSectorSize, PhysicalSectorSize, AllocatedSize, LargestFreeExtent # 2. Check sector sizes explicitlyWrite-Host "=== Sector Sizes ==="Write-Host "Logical Sector Size: $($disk.LogicalSectorSize) bytes"Write-Host "Physical Sector Size: $($disk.PhysicalSectorSize) bytes" if ($disk.LogicalSectorSize -ne $disk.PhysicalSectorSize) { Write-Host "*** Drive is in 512e emulation mode ***" -ForegroundColor Yellow} # 3. Calculate total sectors$totalSectors = $disk.Size / $disk.LogicalSectorSizeWrite-Host "Total Sectors: $totalSectors" # 4. WMI for detailed disk infoGet-WmiObject Win32_DiskDrive | Where-Object {$_.Index -eq 0} | Format-List Caption, Model, SerialNumber, TotalSectors, BytesPerSector, Size, InterfaceType # 5. Disk geometry via WMI (legacy)Get-WmiObject Win32_DiskGeometry | Where-Object {$_.DeviceID -like "*0"} | Format-List * # 6. Storage cmdlets for modern systemsGet-StorageDriver | Format-Table Name, DriverFileNameGet-PhysicalDisk | Format-Table FriendlyName, MediaType, Size, LogicalSectorSize, PhysicalSectorSize # 7. Check for SSD vs HDD$physkind = (Get-PhysicalDisk -DeviceNumber 0).MediaTypeWrite-Host "Media Type: $physkind" # 8. Partition alignment checkGet-Partition -DiskNumber 0 | ForEach-Object { $startSector = $_.Offset / 512 $aligned = ($startSector % 2048) -eq 0 Write-Host "Partition $($_.PartitionNumber): Start=$startSector, 1MiB-Aligned=$aligned"} # 9. diskpart for detailed geometry# diskpart# list disk# select disk 0# detail diskWhen examining geometry, focus on: (1) Total sectors × logical sector size = capacity; (2) Physical ≠ Logical indicates 512e; (3) Rotational = 0 or SSD indicates solid-state; (4) Partition alignments should be multiples of physical sector size.
We have completed our exploration of disk structure—from the physical platters spinning at thousands of RPM to the abstract geometry parameters reported to operating systems. Let's consolidate the geometry concepts:
This module has covered the foundational architecture of hard disk drives:
| Topic | Key Concepts |
|---|---|
| Platters and Surfaces | Magnetic media, perpendicular recording, multi-platter design |
| Tracks and Sectors | Concentric organization, sector structure, 4K Advanced Format |
| Cylinders | 3D organization, cylinder groups, disk scheduling |
| Disk Addressing | CHS vs. LBA, capacity barriers, MBR/GPT structures |
| Disk Geometry | Physical vs. logical, discovery mechanisms, alignment |
You now have a comprehensive understanding of hard disk drive structure—from magnetic domains on spinning platters to the LBA addressing seen by operating systems. This foundation prepares you for the next module: Disk Scheduling Algorithms, where we'll explore how operating systems optimize access to these physical structures.
Next Module: Disk Scheduling Algorithms
With disk structure understood, we'll examine how operating systems schedule I/O operations to minimize seek time and maximize throughput. Topics include FCFS, SSTF, SCAN, C-SCAN, LOOK, and the interplay between OS schedulers and drive-level command queuing.