free web hosting | free hosting | Web Hosting | Free Website Submission | shopping cart | php hosting
affordable web hosting | Pets | web page hosting | web hosting | website hosting | web hosting service | web hosting | best web hosting

Partitioning Primer


What is inside hard disk?

        First disks had a simple design. They had one or more rotating platters and a moving arm with read/write heads attached to it - one head on each side of the platter. The arm could move and stop at the certain number of positions. When it stopped each head could read or write data on the underlying track. Every read or write had to be done in blocks of bytes, called sectors. Sectors were usually 512 bytes long and there were fixed number of sectors on each track. Hard Disk Internals

        The drives themself didn't have much electronics and had to be controlled by CPU for every single step. First CPU had to issue command to position the arm. Then it had to instruct the drive which head should perform read and from which sector. After that CPU waited until the desired sector was moving under the head and started data transfer. This design was relatively simple and inexpensive. But there were several disadvantages.

        First of all, each Input/Output operation involved a lot of CPU attention and, also, the disk surface was used inefficiently. It was convenient for the programmers to have fixed number of sectors on each track, but it was a waste of space, because the longer outer tracks could hold much more data than the shorter inner ones. Later, when digital electronics became cheap, hardware engineers could resolve this problem.

        When IDE (Integrated Drive Electronics) disks came out they had a little processor on each drive. This helped to free up CPU time by implementing more sophisticated set of commands. The disk space was also used more efficiently. Engineers had placed more sectors on the outer tracks, but still provided software writers with a convenient "cubical" look of the disk by doing internal translation of CHS (cylinders, heads, sectors). For example my old 340M disk has only two platters = 4 heads (sides), but it reports 665 cylinders, 16 heads (sides), and 63 sectors. In reality it, probably, has more then 4*63 sectors on each outer track and a little less than 4*63 on the most inner tracks, but we could never know for sure.

        With the IDE disks CPU only has to tell the CHS of the sector that it wants to read and drive's electronics will position the heads and call back the CPU when it is ready to start data transfer.

        The newest drives have even simpler interface. Instead of addressing sectors by their CHS (cylinder, head, sector) address they use LBA (Logical Block Addressing) mode. In LBA mode a program has to tell only number of the sector from the beginning of the disk (all sectors on disk are numbered 0, 1, 2, 3, ... ). In addition to that new disks have internal buffers, where they can store many sectors. This can speed up disk access a lot, because they could read data in buffer using all four heads at the same time.

        Virtually all modern operating systems use LBA addressing, but the CHS notation is still around. First of all, MS-DOS, which is almost 20 years old, uses only CHS. Also some programs, like Partition Magic, would not work if partitions do not start at the cylinder or side boundary. And finally, it is easier to talk about hundreeds of cylinders than about millions of sectors. Therefore we will be using CHS notation throughout this discussion.

        There are several things that you have to know about CHS addressing. Suppose that we have a 340M disk with 665 cylinders, 16 heads, and 63 sectors per track. Then the legal values for cylinder numbers are 0..664, for head (side) numbers are 0..15, and for sector - 1..63.

        The maximum allowable values for CHS addressing mode are 0..1023, 0..255, 1..63 for cylinders, heads, and sectors respectively. If you multiply these values you will see that the largest hard disk that could be addressed with CHS is 8G. Therefore, if your disk is 12G many programs will see only 8G, because they use CHS.

 


How disks are partitioned?

        All hard disks on all IBM compatible computers have the same way of partitioning. First sector of the disk, called MBR (Master Boot Record), which we will be discussing in details later, contains partition table. This table has four records, each of them can describe one partition. In the simplest case we would have all disk space assigned to one partition, like in the following example: MBR FAT-16 Disk Partition

        Note that MBR occupies one sector at cylinder 0, side 0, sector 1 and partition starts on the cylinder 0, side 1, sector 1. The 62 sector gap between them was left unused, because we want all partitions to start at the cylinder boundary or, at least, on the side boundary. This is not required with LBA, but we need to follow this rule in order to make happy old software (MS-DOS for example).

        Another important point that I want to make is that Operating System and File System are different things, which many people use interchangeably. Operating System is a piece of software which controls CPU and lets different application programs to run on the computer and use different system resources. The File System is a way to organize files and directories on the hard disk. The confusion comes because every decent operating system has one or more of its own file systems and they become clousely associated.

        In our example all we know is that we have FAT-16 file system. And we have no idea which operating system is installed on it. It could be MS-DOS 6.22, it could be Windows 95 or NT, or it could be all three of them installed in the different directories in the same partition. If we put additional efforts we could even install there Linux, but it is usually better to have different operating systems installed in separate partitions.

        Another reason to have multiple partitions is the security against computer crushes. For example, if the system crushes in such a way that FAT tables get corrupted you will lose access to all your files, because FAT table tells where each file is located on the disk. The FAT table is so important that they decided to keep two copies of FAT table at the beginning of the disk. But in case if you have very valuable files, it, might be wise to create second partition (then it will have its own FATs) and keep copies of important files there.

        However, do not rush to create the second partition. First of all, experience shows that 99% of errors damage only one copy of FAT and, secondly, for the majority of users it would be sufficient to copy their personal work to the floppy once a week and keep it in the safe place. So, in the case of a crash, they would only have to reformat the disk and reinstall all programs. Now, regardless of the reason, let's see what happens if we have multiple partitions.

        In the second example we have two partitions with the FAT-16 file system. For some reason makers of DOS decided that if you want to have second or third FAT partition you have to put them not in MBR but into the Extended DOS partition. Extended partition appears like an ordinary partition in MBR (it occupies space) and inside it has a table similar to partition table in MBR, called EMBR (Extended MBR), which lists partititions enclosed in the extended partition. Inside of extended partition you can have one more FAT partition and the reference to the next extended partition, then another FAT, and so forth, as long as you have drive letters for them (D:, E:, F:, ... ). All those partitions have special name: logical drives, on contrary to the first FAT partition C:, listed in MBR, which is primary partition. MBR FAT-16 Extended Partition

        We can only speculate about the reasons for choosing such design, but there are two very obvious ones. First one is that partition table has only four records and you couldn't have more than four partitions if you didn't have extended partitions. To understand the second reason you have to know that, according to Microsoft, you can have only one primary partition on the disk and you cannot boot from the logical drives, which means that you cannot have more than one DOS-like operating system on the computer, which is another way to cut off the competitors. In fact, you can have more than one primary FAT partition and we will show later how to do that.

        Also note that FAT tables in the second partition are smaller than in the first one. It obviously happens because the second partition is smaller. The FAT tables has one entry for each cluster in the partition - it contains number of the next cluster in the chain. There is one chain of clusters for each file. Number of the first cluster of the file is stored in the directory entry for that file, along with file size, attributes, and last modification date. Space for the directories other than root is allocated among the data clusters, just as if they were ordinary files. Only root directory has special location. FAT-16/FAT-32 File Allocation Table internal structure

        The name of the file system is FAT-16 because it has FAT (File Allocation Table) and also because each entry in FAT is 16-bits long (2 bytes). This means that FAT-16 partition cannot have more than 65,535 clusters (2^16 = 65,536). Similarly FAT-32 has 32-bit entries and could address up to 2^32 clusters. (Actually they use only 28 bits). Based on that we can calculatete maximum partition sizes for FAT file systems. Here is the table:

 
Cluster
size
File system type
FAT-12 FAT-16 FAT-32
2K 8M 128M 512G
4K 16M 256M 1024G
8K 32M 512M 2048G
16K 64M 1G 2048G
32K 128M 2G 2048G

 
Partition size Recommended file system / cluster size
1-16M FAT-12 / 4K
16-256M FAT-16 / 4K
256-512M FAT-16 / 8K
512M-1G FAT-16 / 16K or FAT-32 / 4K
1-8G FAT-32 / 4K
8G and up FAT-32 / 8K

        The next example shows coexistance of DOS and Linux on the same disk and some more insights on the structure of the extended partition. Beginners can skip it and go to the next section. MBR FAT-16 Ext2fs Linux Swap Partition

        First of all, this configuration could be derived from Example 2 if I we shrink both FAT partitions and then install Linux. Also you probably noticed that Linux native file system uses different way of organizing files than does FAT file system. The main structure is called i-node table. There is one i-node allocated for each file. The i-node keeps file size, attributes and file creation, last modification, and last access times. Unlike FAT file system directories have only file names and i-node numbers. The space allocation also differs from FAT, but it is out of the scope of our discussion.

        If you study carefully cylinder numbers in the third example you will see that extended partition has three EMBR tables each one is stored at the beginning of the extended partition and keeps a record about FAT (or other) partition and the pointer to the next extended partition. Note that first extended partition encloses all FAT and extended partitions, but all other extended partitions (level 2, 3, ... ) enclose only one data partitions.

        And finally I want to say, that even though this was the real partitioning scheme on my hard disk it has some drawbacks. First of all, Linux swap partition is located at the end of the disk, far from the Linux root partition. It turned out that disk heads kept going long way back and forth all the time, decreasing system performance. It is much better to place swap partition as close as possible to the partition where the OS is installed. Also some people think that if they put Windows swap file into the separate partition computer will work faster. This is true only if that partition is located on the separate hard drive, which is faster or as fast as the first one. Placing swap file on the old slow drive will not do any good. It is much better to set in the Control Panels fixed size for the swap file equal to the amount of RAM and place it on C:. Then you can run Norton Speed Disk which will optimize swap file.


      

The Master Boot Record

Introduction

At the early ages of the PC, the capacity of hard disks didn't exceed 10 Mb. As a result, the FAT filesystem didn't support disks with more than 32 Mb. However, the capacity of hard disks quickly increased and operating system manufacturers had to find a way to manage these disks. The idea was to divide a disk of more than 32 Mb into smaller parts. This is called partitioning and each part of a partitioned disk is called a partition.

The latest versions of the FAT filesystem can handle much larger disks, and new and more sophisticated filesystems have been created. However, in some cases partitioning is still needed. One of these cases is when several operating systems have to share one hard disks. On the other hand, some people don't like to have such large disks and prefer to divide them in smaller parts just for convenience.

This page explains how the system maintains the information about the partitions of a hard disk.

The Master Boot Record

The master boot record is the sector where all the partition information is stored. The system needs to know where this sector is so it was given a fixed location : the first sector of the hard disk (head 0, cylinder 0, sector 1). Before looking at the structure of the master boot record, I'll say a word about the booting of an operating system.

At startup, the BIOS of the PC loads the first sector of the first hard disk into memory (we suppose that no floppy disk is present). You can get details on this at Boot sequence of a PC. In our case the sector that will be loaded will thus be the master boot record. To identify the sector as bootable, the last word of the sector must be AA55h. This implies that, if the hard disk is the first one, the first bytes of the master boot record have to be instructions.
Notice that the BIOS itself has no idea of what a partition is, it only loads the first sector of the disk into memory and executes it.

Here is the structure of the master boot record.



Address Content
+000h Partition code : the code lying here is executed if the sector is identified as an executable sector, i.e. the word at offset 1FEh is AA55h.
+1BEh Partition table
+1FEh These 2 bytes are tested by the BIOS to check if the sector can be executed. If byte +1FEh is equal to 55h and byte +1FFh is equal to AAh then the BIOS assumes the sector can be executed.

The structure of the partition table will be explained in the next section. For the moment, we will focus on the partition code.

One of the partitions holds the operating system we want to launch. This partition is called the active partition. Only one active partition can be defined at any moment. It's the partition table which stores the information about the active partition. If more than one partition is active the partition table is considered invalid.

It's the job of the partition code to identify the active partition, to load the boot sector of this partition into memory and then to execute it. This sector must also be loaded at address 0000h:7C00h, so the partition code moves itself elsewhere before loading the boot sector.

The partition table

This table lies at offset +1BEh of the master boot record. It has four entries of 16 bytes each. The structure of the partition table is as follows :

+1BEh First entry of the partition table
+1CEh Second entry of the partition table
+1DEh Third entry of the partition table
+1EEh Fourth entry of the partition table
Each partition is described by a 16 byte structure. The follow table shows this structure.

Offset Content
+00h State of partition : 00h if not active, 80h if active
+01h Head where the partition starts
+02h Sector and cylinder where the partition starts
+04h Type of partition : see Appendix A.
+05h Head where the partition ends
+06h Sector and cylinder where the partition ends
+08h Distance, in sectors, from the partition sector to the first sector of the partition
+0Ch Number of sectors in the partition

Appendix A : Type of partitions

Reference number Type
0h Empty
1h DOS 12-bits FAT
2h XENIX root
3h XENIX usr
4h DOS 16-bits < 32 Mb
5h Extended partition
6h DOS 16-bits >= 32 Mb
7h OS/2 HPFS
8h AIX
9h AIX initializable
Ah OS/2 Boot Manager
40h Venix 80286
51h Novell
52h Microport
63h GNU HURD
64h Novell
75h PC/IX
80h Old MINIX
81h MINIX/Linux
82h Linux Swap
83h Linux Native
93h Amoeba
94h Amoeba BBT
A5h BSD/386
B7h BSDI fs
B8h BSDI swap
C7h Syrinx
DBh CP/M
E1h Access to DOS
E3h DOS R/O
F2h DOS secondary
FFh BBT


Example of partition tables

Partition table of a 850 Mbyte hard disk with a DOS partition

The disk we analyze here is a 850 Mbyte hard disk in LBA mode with 827 cylinders, 63 sectors and 32 heads.
This is the code found at addresses 1BEh to 1FEh of the Master Boot Record. It's the partition table.

Entry 1 80 01 01 00 06 1F FF 39 3F 00 00 00 81 68 19 00
Entry 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

As we see only the first entry of the table is used.

The content of address 1BEh is 80h, meaning that this is the boot partition.

The next byte (address 1BFh) is the head where the partition starts. This partition starts at head 1.

The bytes at addresses 1C0h and 1C1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the thwo most significant bits of the cylinder number and must be appended to the value in 1C1h. This gives : 0000000000b.

From all the fields above, we know the partition starts at sector 1, head 1, cylinder 0.

The byte at address 1C2h is the type of partition. Here we have a DOS 4.0 with more than 32 Mbyte partition (value 06h).

The next byte (address 1C3h) is the head where the partitions ends : head 1Fh or 31 (remember this is a disk with 32 heads, head 31 is thus the last).

The bytes at addresses 1C4h and 1C5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is FFh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the thwo most significant bits of the cylinder number and must be appended to the value in 1C5h. This gives : 1100111001b (825).

From all the fields above, we know the partition ends at sector 63, head 31, cylinder 825.

The bytes at addresses 1C6h to 1C9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 0000003Fh (remember that Intel architecture uses the Little-Endian format) or 63. The distance from the beginning of the partition sector to the beginning of the partition is 63 sectors since the partition begins at head 1, cylinder 0, sector 0 and there are 63 sectors per track.

The bytes at addresses 1CAh to 1CDh are the number of sectors in the partition. Here we have : 00196881h or 1665153. If we multiply this number by the number of bytes in a sector (512), we get 852,558,336 bytes. This is the result expected because the partition covers all the disk space.

Partition table of a 3.2 Gbyte hard disk with a Linux partition

The disk we analyze here is a 3.2 Gbyte hard disk in LBA mode with 63 sectors/track and 128 heads/cylinder. It has two partitions : a Linux swap partition of 100 Mb and a Linux native partition of 1.5 Gb. About half of the disk is thus unused.
This is the code found at addresses 1BEh to 1FEh of the Master Boot Record. It's the partition table.

Entry 1 00 01 01 00 82 7F 3F 19 3F 00 00 00 C1 32 03 00
Entry 2 80 00 01 1A 83 7F 7F 96 00 33 03 00 80 E1 2E 00
Entry 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

As we see only the first and second entries of the table are used.

The content of address 1BEh is 00h, so this isn't the boot partition (in fact, it's a Linux swap partition).

The next byte (address 1BFh) is the head where the partition starts. This partition starts at head 1.

The bytes at addresses 1C0h and 1C1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the thwo most significant bits of the cylinder number and must be appended to the value in 1C1h. This gives : 0000000000b.

From all the fields above, we know the partition starts at sector 1, head 1, cylinder 0.

The byte at address 1C2h is the type of partition. Here we have a Linux swap partition (value 82h).

The next byte (address 1C3h) is the head where the partitions ends : head 7Fh or 127 (remember this is a disk with 128 heads, head 127 is thus the last).

The bytes at addresses 1C4h and 1C5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is 3Fh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1C5h. This gives : 0000011001b (25).

From all the fields above, we know the partition ends at sector 63, head 127, cylinder 25.

The bytes at addresses 1C6h to 1C9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 0000003Fh (remember that Intel architecture uses the Little-Endian format) or 63. The distance from the beginning of the partition sector to the beginning of the partition is 63 sectors since the partition begins at head 1, cylinder 0, sector 1 and there are 63 sectors per track.

The bytes at addresses 1CAh to 1CDh are the number of sectors in the partition. Here we have : 000332C1h or 209601. If we multiply this number by the number of bytes in a sector (512), we get 107,315,712 bytes.

The content of address 1CEh is 80h, this is a boot partition.

The next byte (address 1CFh) is the head where the partition starts. This partition starts at head 0.

The bytes at addresses 1D0h and 1D1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the thwo most significant bits of the cylinder number and must be appended to the value in 1D1h. This gives : 0000011010b.

From all the fields above, we know the partition starts at sector 1, head 0, cylinder 26.

The byte at address 1D2h is the type of partition. Here we have a Linux native partition (value 83h).

The next byte (address 1D3h) is the head where the partitions ends : head 7Fh or 127 (remember this is a disk with 128 heads, head 127 is thus the last).

The bytes at addresses 1D4h and 1D5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is 7Fh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1D5h. This gives : 0110010110b (406).

From all the fields above, we know the partition ends at sector 63, head 127, cylinder 406.

The bytes at addresses 1D6h to 1D9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 00033300h (remember that Intel architecture uses the Little-Endian format) or 209664. This is approximately the length of the first partition (107 Mb).

The bytes at addresses 1DAh to 1DDh are the number of sectors in the partition. Here we have : 002EE180h or 3075384. If we multiply this number by the number of bytes in a sector (512), we get 1,573,060,608 bytes.

Partition table of a 2.5 Gbyte hard disk with two DOS partitions

The disk we analyze here is a 2.5 Gbyte hard disk in LBA mode with 620 cylinders, 63 sectors/track and 128 heads/cylinder. It has two partitions : a partition of 1 Gb and a partition of 1.5 Gb.
This is the code found at addresses 1BEh to 1FEh of the Master Boot Record. It's the partition table.

Entry 1 00 00 01 01 05 7F BF 6A 80 1F 00 00 00 0B 4C 00
Entry 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

As we see only the first entry of the table are used.

The content of address 1BEh is 00h, so this isn't a boot partition.

The next byte (address 1BFh) is the head where the partition starts. This partition starts at head 0.

The bytes at addresses 1C0h and 1C1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1C1h. This gives : 0000000001b.

From all the fields above, we know the partition starts at sector 1, head 0, cylinder 1.

The byte at address 1C2h is the type of partition. Here we have an extended partition (05h), meaning that the first sector of this partition is a master boot record itself.

The next byte (address 1C3h) is the head where the partitions ends : head 7Fh or 127 (remember this is a disk with 128 heads, head 127 is thus the last).

The bytes at addresses 1C4h and 1C5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is BFh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1C5h. This gives : 1001101010b (618).

From all the fields above, we know the partition ends at sector 63, head 127, cylinder 618.

The bytes at addresses 1C6h to 1C9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 00001F80h (remember that Intel architecture uses the Little-Endian format) or 8064. The distance from the beginning of the partition sector to the beginning of the partition is 8064 sectors since the partition begins at head 0, cylinder 1, sector 1. The first cylinder is unused, it holds 63*128 = 8064 sectors.

The bytes at addresses 1CAh to 1CDh are the number of sectors in the partition. Here we have : 004C0B00h or 4983552. If we multiply this number by the number of bytes in a sector (512), we get 2,551,578,624 bytes.

Since this is an extended partition, its first sector has also a partition table. Here is this table :

Entry 1 00 01 01 01 06 7F 3F FE 3F 00 00 00 C1 40 1F 00
Entry 2 00 00 01 FF 05 7F BF 6A 00 41 1F 00 00 CA 2C 00
Entry 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

As we see only the first and second entries of the table are used.

The content of address 1BEh is 00h, so this isn't a boot partition.

The next byte (address 1BFh) is the head where the partition starts. This partition starts at head 1.

The bytes at addresses 1C0h and 1C1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1C1h. This gives : 0000000001b.

From all the fields above, we know the partition starts at sector 1, head 1, cylinder 1.

The byte at address 1C2h is the type of partition. Here we have a DOS 4.0 partition (06h).

The next byte (address 1C3h) is the head where the partitions ends : head 7Fh or 127 (remember this is a disk with 128 heads, head 127 is thus the last).

The bytes at addresses 1C4h and 1C5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is 3Fh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1C5h. This gives : 0011111110b (254).

From all the fields above, we know the partition ends at sector 63, head 127, cylinder 254.

The bytes at addresses 1C6h to 1C9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 0000003Fh (remember that Intel architecture uses the Little-Endian format) or 63.

The bytes at addresses 1CAh to 1CDh are the number of sectors in the partition. Here we have : 001F40C1h or 2048193. If we multiply this number by the number of bytes in a sector (512), we get 1,048,674,816 bytes.

The content of address 1CEh is 00h, this isn't a boot partition either.

The next byte (address 1CFh) is the head where the partition starts. This partition starts at head 0.

The bytes at addresses 1D0h and 1D1h are used to know the sector and the cylinder where the partition starts.
The value of the first byte is 01h but only the 6 least significant bits are used for the sector number. The sector number is thus 000001b. The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1D1h. This gives : 0011111111b (255).

From all the fields above, we know the partition starts at sector 1, head 0, cylinder 255.

The byte at address 1D2h is the type of partition. Here we have an extended partition (05h).

The next byte (address 1D3h) is the head where the partitions ends : head 7Fh or 127 (remember this is a disk with 128 heads, head 127 is thus the last).

The bytes at addresses 1D4h and 1D5h are used to know the sector and the cylinder where the partition ends.
The value of the first byte is BFh but only the 6 least significant bits are used for the sector number. The sector number is thus 111111b (63). The 2 most significant bits are the two most significant bits of the cylinder number and must be appended to the value in 1D5h. This gives : 1001101010b (618).

From all the fields above, we know the partition ends at sector 63, head 127, cylinder 618.

The bytes at addresses 1D6h to 1D9h are the distance from the partition sector to the first sector of the partition calculated in sectors. Here we have 001F4100h (remember that Intel architecture uses the Little-Endian format) or 2048256. This is approximately the length of the first partition (1 Gb).

The bytes at addresses 1DAh to 1DDh are the number of sectors in the partition. Here we have : 002CCA00h or 2935296. If we multiply this number by the number of bytes in a sector (512), we get 1,502,871,552 bytes.

Since this is an extended partition, we look at its first sector to find the partition table :

Entry 1 00 01 01 FF 06 7F BF 6A 3F 00 00 00 C1 C9 2C 00
Entry 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Entry 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

We have here a DOS 4.0 partition of 1.5 Gb.


Example of a Master Boot Code (IPL)

Here's a copy of the code found a the first sector of 850 Mbyte hard drive with one DOS 4.0 partition.

Offset Hexadecimal code Instruction or data
00 FA cli
01 33C0 xor ax,ax
03 8ED0 mov ss,ax
05 BC007C mov sp,7C00h
08 8BF4 mov si,sp
0A 50 push ax
0B 07 pop es
0C 50 push ax
0D 1F pop ds
0E FB sti
0F FC cld
10 BF0006 mov di,0600h
13 B90001 mov cx,0100h
16 F2A5 repnz movsw
18 EA1D060000 jmp 0000h:061Dh
1D BEBE07 mov si,07BEh
20 B304 mov bl,04h
22 803C80 cmp byte ptr [si],80h
25 740E je 35h
27 803C00 cmp byte ptr [si],00h
2A 751C jne 48h
2C 83C610 add si,0010h
2F FECB dec bl
31 75EF jne 22h
33 CD18 int 18h
35 8B14 mov dx,[si]
37 8B4C02 mov cx,[si+02h]
3A 8BEE mov bp,si
3C 83C610 add si,0010h
3F FECB dec bl
41 741A je 5Dh
43 803C00 cmp byte ptr [si],00h
46 74F4 je 3Ch
48 BE8B06 mov si,068Bh
4B AC lodsb
4C 3C00 cmp al,00h
4E 740B je 5Bh
50 56 push si
51 BB0700 mov bx,7h
54 B40E mov ah,0Eh
56 CD10 int 10h
58 5E pop si
59 EBF0 jmp 4Bh
5B EBFE jmp 5Bh
5D BF0500 mov di,5h
60 BB007C mov bx,7C00h
63 B80102 mov ax,0201h
66 57 push di
67 CD13 int 13h
69 5F pop di
6A 730C jnb 78h
6C 33C0 xor ax,ax
6E CD13 int 13h
70 4F dec di
71 75ED jne 60h
73 BEA306 mov si,06A3h
76 EBD3 jmp 4Bh
78 BEC206 mov si,06C2h
7B BFFE7D mov di,7DFE
7E 813D55AA cmp word ptr [di],AA55h
82 75C7 jne 4Bh
84 8BF5 mov si,bp
86 EA007C0000 jmp 0000h:7C00h
8B   Invalid partition table
A2 00  
A3   Error loading operating system
C1 00  
C2   Missing operating system
DA 00  
DB-1BE 00 Unused space
1BE-1CD See description of this entry in Partition Table of a 850 Mb hard disk
1CE-1DD 00 Unused entry of partition table
1DE-1ED 00 Unused entry of partition table
1EE-1FD 00 Unused entry of partition table
1FE 55AA The sector can be executed
Note : when a jump is made in this table, the value that follows the instruction refers to the offset in the table, you don't have to add this value to the offset of the instruction (i.e. je 48h sends you to offset 48h).

00-0E :
The first thing the code does, is to disable interrupts while it is initializing the segment and stack registers. After that, it reenables them. Please note that the si register is also initialized. Its initial value is 7C00h, so that it points to the boot code.

0F-18 :
The boot code is copied to 0000h:0600h. The program then jumps to the next instruction but in the copy of the code.

1D :
si is loaded with 07BEh. This is the location of the first entry of the partition table. Remember that this entry is at offset 1BEh of the boot sector and that this sector is now at 600h (600h + 1BEh = 7BEh).

20-33 :
This code goes through the partition table and looks for a bootable partition.
If it has found a boot partition, it goes to offset 35h.
If it has found a partition whose first byte isn't 80h nor 00h, it goes to offset 48h.
If it hasn't found a bootable partition in any of the 4 entries of the table, it triggers interrupt 18h.

35-46 :
This code is executed when a bootable partition has been found. It checks if the entries that haven't been examined yet start with a null byte (indicating a non bootable partition). If anything else is found, the partition table is considered invalid and the execution continues with the code located at offset 48h.
cx is loaded with the cylinder and head information.
If all the other entries of the table are start with 0, the code at offset 5Dh is executed.

48 : si is loaded with 68B. This is the offset of the string "Invalid partition table". Then execution is continued with the code at 4Bh.

4B-5B :
This code is used to print an error message on the screen. si has been previously loaded by the offset of the string to print. It uses interrupt 10h to do so. The last byte of the string must be equal to 0 to indicate the end of the string. When the procedure detects the end of the string it jumps to offset 5Bh, which is an infinite loop.

5D-76 :
This code loads the boot sector of the active partition at address 0000h:7C00h. It tries to do so with interrupt 13h, function 2h. cx has already been loaded with the appropriate value by the procedure at offset 35h.
If an error is detected, the procedure resets the drive with interrupt 13h, function 0h and retries to read the disk. It retries 5 times. After that, si is loaded with 06A3h, the offset of the "Error loading operating system" string, and the printing procedure at offset 4Bh is called.
If the procedure managed to load the boot sector, the code at offset 78h is executed.

78-86 :
The si register is loaded with the value 06C2h, which is the offset of string "Missing operating system". This is done in prevision of an error.
The procedure checks if the newly loaded boot sector is executable. If it is, it should find a word with value AA55h at offset 7DFEh (7C00h+1FEh). If it doesn't find it, it calls the printing procedure at offset 4Bh.
If everything is allright, the procedure jumps to the boot code.