ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Dividing Your Data

02/21/2001

Also in FreeBSD Basics:

Fun with Xorg

Sharing Internet Connections

Building a Desktop Firewall

Using DesktopBSD

Using PC-BSD

In the next few articles, I'll look at how FreeBSD stores data on your hard disk. To store data on a hard drive, the drive must first be divided into logical storage units, and each unit must be assigned an address. The file system will save data to these storage units and keep track of which storage units contain which files.

Like any other version of Unix, FreeBSD uses "inode" (index number) tables to record where files are physically located on disk. Before any inode tables can be created, the disk storage units must be created and given addresses. Let's summarize the steps involved in this process:

Notice that your FreeBSD system contains both a BIOS partition table and a Unix partition table. This is necessary as FreeBSD is a Unix operating system, meaning it understands the Unix partition table; however, FreeBSD is also an operating system which runs on a PC (personal computer). PCs require software known as the BIOS in order to initialize the computer, discover the physical geometry of the drives, and locate the software that will boot the desired operating system.

One of the instructions in the BIOS is to look at the contents of the first sector of the first hard disk. This sector is 512 bytes in size; out of those 512 bytes, 64 bytes have been set aside for the BIOS partition table. Every entry in the BIOS partition table consists of 16 bytes, therefore there is only enough room to describe four BIOS partitions.

The BIOS partition table can be viewed or changed using an fdisk utility. If you change the BIOS partition table, you are actually "slicing" your physical disk into as many as four logical disks. FreeBSD users prefer to call these logical disks "slices" so they won't be confused with the "partitions" described by the Unix partition table.

You may be familiar with the DOS fdisk utility; I'd like to compare it to the FreeBSD fdisk utility so you can see the similarities between the two programs. I'll start by showing the output from one of my PCs; I booted this PC with a DOS boot disk, then ran fdisk from the floppy prompt:

           Microsoft Windows 95
         Fixed Disk Setup Program
 (C)Copyright Microsoft Corp/ 1983 - 1995

FDISK Options

Current fixed disk drive: 1

Choose one of the following:

1. Create DOS partition or Logical DOS Drive
2. Set active partition
3. Delete partition or Logical DOS Drive
4. Display partition information

Enter choice: [4]

Here we've entered the main menu of the DOS fdisk utility. I don't want to change the BIOS partition table, so I'll choose option 4 to display the partition information.

Display Partition Information

Current fixed disk drive: 1

Partition Status Type Volume Label Mbytes System Usage
C: 1 A PRI DOS 204 FAT16 3%
2 Non-DOS 3193 52%
3 EXT DOS 2753 45%

Total disk space is 6150 Mbytes (1 Mbyte = 1048576 bytes)

The Extended DOS Partition contains Logical DOS Drives.
Do you want to display the logical drive information (Y?N)......?[Y]

Notice that I have "sliced" up my hard drive into three slices, which DOS calls "partitions." The first slice has a status of A for active, meaning that it contains boot code in order to boot an operating system. It is 204 Mbytes in size and has been formatted with the FAT16 file system.

The second slice is 3,193 Mbytes and contains my FreeBSD partitions. This file type is not recognized by the DOS fdisk utility and has been simply labeled as non-DOS.

The third slice is a 2,753-Mbyte extended partition. Notice that you must enter another screen to see the layout of the extended partition. Extended partitions were designed to allow you to slice your hard drive into more than four slices; the extended partition is simply a pointer to another area on disk which contains yet another table to describe the layout of the "logical" partitions contained within the "extended" partition. Unfortunately, these logical partitions are truly "logical" as they cannot contain boot code, and many operating systems will not install on an extended partition. I'll press Y to enter into the screen that will show these logical partitions:

Display Logical DOS Drive Information

Drv Volume Label Mbytes System Usage
D: 1396 FAT16 51%
E: 361 FAT16 13%

Total Extended DOS Partition size is 2753 Mbytes (1 Mbyte = 1048576 bytes)

Let's summarize the information we've gleaned out of the DOS fdisk utility. This PC has one hard drive of 6,150 Mbytes. It has been sliced up and labeled as follows:

DOS slice name DOS slice type Slice size Filesystem
C: primary 204 Mbytes FAT16
D: logical 1,396 Mbytes FAT16
E: logical 361 Mbytes FAT16
none unknown 3,193 Mbytes unknown

DOS uses the following naming scheme for its slices:

Let's compare this to the output from FreeBSD's fdisk utility. If you just type fdisk at a prompt, it will display the contents of the BIOS partition table. However, if you try to run fdisk as a regular user, you'll receive this message:

fdisk 
fdisk: can't open device /dev/ad0
fdisk: cannot open disk /dev/ad0: Permission denied

Only the superuser has permission to access the device that represents my first IDE disk; this is a good thing, as all fdisk utilities give you the option to modify the slices that have been defined on a hard disk. If you modify a slice, you lose all the data on that slice. Don't worry, the superuser won't be able to modify a slice if he just types fdisk to view the BIOS partition table; the superuser has to actually specify a drive and a switch in order to change a slice. I'll become the superuser and try that view command again:

fdisk

******* Working on device /dev/ad0 *******
parameters extracted from in-core disklabel are:
cylinders=784 heads=255 sectors/track=63 (16065 blks/cyl)

parameters to be used for BIOS calculations are:
cylinders=784 heads=255 sectors/track=63 (16065 blks/cyl)

Media sector size is 512
Warning: BIOS sector numbering starts with sector 1
Information from DOS bootblock is:
The data for partition 1 is:
sysid 6,(Primary "big" DOS (> 32MB))
start 63, size 417627 (203 Meg), flag 80 (active)
beg: cyl 0/ sector 1/ head 1;
end: cyl 25/ sector 63/ head 254
The data for partition 2 is:
sysid 165,(FreeBSD/NetBSD/386BSD)
start 417690, size 6538455 (3192 Meg), flag 0
beg: cyl 26/ sector 1/ head 0;
end: cyl 432/ sector 63/ head 254
The data for partition 3 is:
sysid 5,(Extended DOS)
start 6956145, size 5638815 (2753 Meg), flag 0
beg: cyl 433/ sector 1/ head 0;
end: cyl 783/ sector 63/ head 254
The data for partition 4 is:
<UNUSED>

If you take a close look at this output, you'll notice that FreeBSD's fdisk utility yields the same information as the DOS fdisk utility plus more detailed information regarding the physical layout of the disk. This information is always contained in the BIOS partition table, but not all of the information is displayed with the DOS fdisk utility.

Hard drives are divided into logical units known as cylinders and sectors. My FreeBSD slice (partition 2) starts at cylinder 26/sector 1 and ends at cylinder 432/sector 63. Since cylinders are comprised of 63 sectors, we've started at the beginning of cylinder 26 and ended at the end of cylinder 432, for a total of 407 cylinders. We'll see that cylinder information again when we look at the Unix partition table.

You can also use the fdisk utility to view a summary of the BIOS partition table if you include the s switch:

fdisk -s

/dev/ad0: 784 cyl 255 hd 63 sec
Part        Start        Size Type Flags
   1:          63      417627 0x06 0x80
   2:      417690     6538455 0xa5 0x00
   3:     6956145     5638815 0x05 0x00

This output again shows three defined slices. It also shows the starting address of each slice, and the size of each slice in sectors. The type of each slice is written in hex as hex values always begin with 0x. The hex value a5 is equivalent to the decimal number 165 which is the magic number used by FreeBSD; the hex value 06 is equivalent to the decimal number 6 which is the magic number for FAT16; the hex value 05 is equivalent to the decimal number 5 which is the magic number for a DOS extended partition. Only one flag can be set to 0x80 as this represents the active partition and a BIOS partition table can only have one active partition.

Let's summarize the BIOS partition table: It is used by a PC's BIOS to determine the physical layout of a hard disk which may have been logically divided into as many as four slices. Normally, users create multiple slices when they wish to run multiple operating systems. If a slice is to contain a Microsoft operating system, it must first be formatted with a file system that the operating system understands. The formatting process will create a table on that slice which will be used by the file system to keep track of where data is stored on that slice.

The nice thing about slicing up a hard drive is that you can reformat a slice (which destroys the table for that slice, meaning you'll no longer be able to find the data on that slice) without affecting the data on the other slices of the disk. However, a slice formatted for a Microsoft operating system can only contain one file system; that is, you can't have two or more file systems on a slice that contains a Microsoft operating system.

If a slice is to contain the FreeBSD operating system, the Unix partition table will be written to that slice. A FreeBSD slice can contain up to eight partitions, and each partition can be either a separate file system or a swap partition.

If you run the disklabel utility without any switches, you will be able to safely view the Unix partition table without modifying it; again, only the superuser can use this utility as only the superuser has permission to access the disk's device name. My PC is running FreeBSD 4.2, so its IDE drive is called ad. Drives are numbered starting with the number 0; since my FreeBSD slice is on my first drive, I'll specify the device ad0 like so:

disklabel ad0

# /dev/ad0c:
type: ESDI
disk: ad0s2
label:
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 255
sectors/cylinder: 16065
cylinders: 407
sectors/unit: 6538455
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # milliseconds
track-to-track seek: 0 # milliseconds
drivedata: 0

8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 102400 0 4.2BSD 0 0 0 # (Cyl. 0 - 6*)
b: 270976 102400 swap # (Cyl. 6*- 23*)
c: 6538455 0 unused 0 0 # (Cyl. 0 - 406)
e: 40960 373376 4.2BSD 0 0 0 # (Cyl. 23*- 25*)
f: 6124119 414336 4.2BSD 0 0 0 # (Cyl. 25*- 406*)

The Unix partition table looks quite different from the BIOS partition table. All of these entries live in that one FreeBSD slice which the BIOS sees as "partition 2". Notice that this one slice has been assigned five letters, but the letter c shows a filesystem type of unused. By convention, the letter c represents the entire slice, so the actual filesystems will be assigned the letters a-b and d-h. On this FreeBSD slice, there are three separate filesystems lettered a, e, and f. The swap partition has been assigned the letter b.

Each filesystem is defined by its cylinder groups, which are simply a bunch of cylinders grouped together. Each filesystem is only responsible for the data stored on its cylinder group. So, filesystem a has been assigned the cylinders 0-6, the filesystem e has been assigned the cylinders 23-25, and the filesystem f has been assigned the cylinders 25-406. Notice that the entire slice, or c, is composed of cylinders 0-406, for a total of 407 cylinders which was the number of cylinders we saw with FreeBSD's fdisk utility.

We can also see from the beginning of this output how the cylinders are divided into their storage units: cylinders are divided into sectors and tracks, each track is intersected by 63 sectors, and each sector is composed of 512 byte "blocks". If you are unfamiliar with sectors and tracks, there is a good picture here.

Finally, with a bit of math we can figure out how big this slice is in megabytes. There are 6,538,455 sectors and each sector is 512 bytes. If we multiply the number of sectors by the number of bytes, we'll get the total number of bytes. If we divide this result by 1,024, we'll get the number of kilobytes; if we divide that result by another 1,024, we'll get the number of megabytes:

6,538,455 x 512 = 3,347,688,960 bytes
3,347,688,960 / 1,024 = 3,269,227 kilobytes
3,269,227 / 1,024 = 3,192 megabytes

which just happens to be the size reported by the fdisk utility.

The disklabel utility can be used to create the Unix partition table, but it does not actually create the filesystems. Instead, it creates a "disk pack label" which is read by the newfs utility. It is the newfs or new filesystem utility which creates the actual filesystems and their associated inode tables. I want to take a good look at newfs and inode tables, so we'll continue the rest of this article next week.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Discuss this article in the Operating Systems Forum.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.