Next-> Inside Ext2 fs, previous-> Ext2Internals.htm, Home
Inside Hard Disk.
Hard Disks are the most popular storage devices. We cannot imagine a computer without a hard disk. Hard disks offer high capacity and low costs.
The organization of disk.
In a disk, the data is stored in the surface of a circular disc called platters. The platters are double sided and the data is read by a read/write head. So, there are two heads per platter. There are many of them and each of them is divided into circular rings called tracks. The collection of tracks that are exactly above or below the other tracks is called a cylinder. Again each track is divided into a number of sectors (usually 64). Thus, sectors are the smallest addressable unit in disk. The disk can also be viewed as a large array of sectors.
Addressing the disk sectors.
The data in the disk can be addressed in mainly two ways. They are the CHS addressing and the LBA addressing.
The CHS (cylinder/head/sector) addressing uses the exact cylinder number, sector number and the head number to address a disk. The PC bios rely on this technique for booting the OS. The bios interrupt 0x13 function 0x2 (for details see Ralph brown’s interrupt list) can be used to read the disk using CHS addressing.
In the LBA (logical block addressing), the disk is viewed as a large array of sectors. The sector to address is number of sectors from the starting of disk. The first sector is 0. For reading the disk using LBA we use bios interrupt 0x13, function 0x42 (also called IBM’s int 13 extensions).
Reading the disk sectors
The disk sectors can be in many ways. Firstly, we can use the Operating System’s system call facility like open (), read () etc. Secondly, we can use IO instructions to read and write the IO ports of the disk (0x1f0 – 0x1f7 for 1st IDE). And thirdly using the bios (or DOS) interrupts.
Reading disk sectors from Dos
We can use bios interrupts to read the sectors in real mode OS like DOS. After inserting the values in the general purpose registers (function no. in AX, ) we call int 0x13. After returning from interrupt it will fill the buffer by sector’s content.
A C language example.
BOOL ReadSect(BYTE disk, int nsects,DWORD lsects,void* data)
{
union REGS iregs, oregs;
struct SREGS sregs;
iregs.h.ah = 0x02;
iregs.h.al = nsects;
iregs.x.bx = FP_OFF (data);
sregs.es = FP_SEG (data);
iregs.h.ch = (BYTE) track;
iregs.h.cl = (BYTE) sector;
iregs.h.dh = (BYTE) head;
iregs.h.dl = disk;
int86x (0x13, &iregs, &iregs, &sregs);
if (iregs.x.cflag)
Return FALSE;
Else
Return TRUE;
}
The above method has limitations of reading up to 1034 cylinders so we should use extend read method. See our source code for details. Bios and DOS interrupt details can be found on Ralph Brown’s interrupt list.
Reading sectors from UNIX and Windows.
In UNIX (and UNIX like systems) everything is file, so a disk is a file and is identified by a block device file /dev/hda (varies according to UNIX implementation). It can be Opened, read written and seeked as a simple file.
In Windows (NT), reading disk is similar to UNIX. The disk is identified as \\\\.\\PhysicalDrive0 and partitions as \\\\.\\c:. We simply open a file using CreateFile()(win32 API), read using ReadFile(), and seek using SetFilePointer(). Here are the examples.
/* Unix Implementation (User mode)*/
BOOL ReadSect(BYTE disk, int nsects,DWORD lsects,void* data)
{
int desc;
desc = open(“/dev/hda”, O_READ); /* file name differs from one implementation to other */
lseek (desc, lsects*512, SEEK_SET);
read (desc, data, nsects*512);
}
/* Windows Implementation */
BOOL ReadSect(BYTE disk, int nsects,DWORD lsects,void* data)
{
HANDLE hDevice;
DWORD dummy;
hDevice = CreateFile(“////.//PhysicalDrive0”, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);
if(!hDevice)
return FALSE;
SetFilePointer(hDevice, (lsects*512), NULL, FILE_BEGIN);
if(!ReadFile(hDevice, data, (512*nsects), &dummy, NULL))
return FALSE;
CloseHandle(hDevice);
Return TRUE;
}
The Partition structure
In Dos like system, the partition table entry is stored in a data structure called Master Boot Record (MBR). MBR is the most important data structure in the disk. It lies on the first sector of the disk and is created by disk partitioning programs like fdisk. It is the most critical part of the disk. If it is damaged or erased accidentally, all the data will be lost.
The MBR structure contains of three parts: the master boot code, partition table and the signature. The master boot code is a small program which scans the partition table for the active partition, finds the starting sector of the active partition, loads the boot sector from the active partition to the memory and transfers the execution flow to the loaded code.
The last two bytes of the MBR is a magic number ‘0x55AA’ which is called the signature.
The information of the partitions lies in the Partition table entry. It starts at 446 bytes and is 64 bytes long. It contains 4 partition table entries each 16 bytes long. Thus, there can be only four primary partitions in a disk. The fields of the partition structure are given below in the form of C structure.
Struct partition {
BYTE bootIndicator;
BYTE startingHead;
unsigned startingSector :6;
unsigned startingCylinder:10;
BYTE systemId;
BYTE endingHead;
unsigned endingSector:6;
unsigned endingCylinder:10;
DWORD relativeSectors;
DWORD totalSectors;
};
Among the four primary partitions one is the extended partition and contains the logical partitions. The Partition Table Entry in the Extended Partition points to the MBR like structure called the Extended Boot Record (EBR). There is a EBR for each logical partition. Among the four Partition table entry, first entry points to the boot sector of the logical partition. Second entry points to the EBR of the second logical partition. Thus, the logical partitions are the linked lists.
Next-> Inside Ext2 fs, previous-> Ext2Internals, Home