The Disk Is Just a Numbered Array of 512-Byte Slots
The Contract
Every storage device — spinning platter, NAND flash, NVMe stick — presents one interface to the silicon that reads instructions: an array of fixed-size slots numbered 0, 1, 2, 3, ...
Each slot holds exactly 512 bytes. The numbering scheme is called LBA (Logical Block Addressing). Slot 0 is at byte offset 0. Slot 1 is at byte offset 512. Slot N is at byte offset N * 512.
Slot 0: bytes [0x000 .. 0x1FF] (0 .. 511)
Slot 1: bytes [0x200 .. 0x3FF] (512 .. 1023)
Slot 2: bytes [0x400 .. 0x5FF] (1024 .. 1535)
...
Slot N: bytes [N*512 .. N*512+511]
Two Operations, Nothing Else
The silicon sends exactly two commands to the disk controller:
READ(slot_number, count) → returns count * 512 bytes
WRITE(slot_number, data) → overwrites 512 bytes at that slot
That's it. The disk knows nothing about files, directories, permissions, timestamps, or names. Those are inventions layered on top by software running in ring 0.
Real Numbers on a Real Disk
A 256 GB SSD has 256 * 1024^3 / 512 = 500,000,000 slots (500 million). Slot 0 through slot 499,999,999.
Total bytes: 256 * 1073741824 = 274877906944
Slot count: 274877906944 / 512 = 536870912
Last slot: 536870911
ioctl(fd, BLKSSZGET, &sz) — the return is 512 or 4096.
What the Kernel Sees
When the kernel wants to read slot 100 from /dev/sda, it builds a request with these fields:
struct bio {
sector_t bi_sector; /* = 100 (8 bytes, slot number) */
unsigned int bi_size; /* = 512 (how many bytes) */
int bi_rw; /* = READ (0) or WRITE (1) */
struct bio_vec *bi_io_vec; /* points to DRAM destination */
};
The bi_sector field is the slot number. The device driver translates that to the right electrical signals on the SATA/NVMe bus.
Proving It: Read Raw Sectors
/* read sector 0 (the MBR or protective GPT header) */
/* STEP 1: open the raw disk device */
int fd = open("/dev/sda", O_RDONLY);
/* STEP 2: read 512 bytes from offset 0 */
char buf[512];
pread(fd, buf, 512, 0); /* offset = sector_number * 512 */
/* STEP 3: first 2 bytes of a GPT protective MBR */
/* buf[510] = 0x55, buf[511] = 0xAA → boot signature */