How Linux Works: What Every Superuser Should Know

2.3 Devices

You will find it very easy to manipulate devices on a Unix system because the kernel normally presents the device I/O interface to system and user processes as files. Not only can a programmer use regular file operations to work with a device, but some devices are also accessible to standard programs like cat , so you don't have to be a programmer to use a device. Linux uses the same design of device files as other Unix flavors, but device filenames and functionality vary among flavors.

Linix device files are in the /dev directory, and running ls /dev reveals that there are more than a few files in /dev . So how do you work with devices?

To get started, consider this command:

echo blah blah > /dev/null

Like any command with redirected output, this sends some stuff on the standard output to a file. However, the file is /dev/null , a device, and the kernel decides what to do with any data written to this device. In the case of /dev/null , the kernel simply ignores the data (making /dev/null a bitbucket ). Of course, other devices actually do things, such as /dev/dsp , which plays a sound if you send appropriate output there (for example, cat blab.wav > /dev/dsp ).

To identify a device, use ls -l to get a long listing and look at the permissions. Here are four examples:

brw-rw---- 1 root disk 3, 65 Jul 20 1998 hdb1 crw-rw-rw- 1 root root 1, 3 Jul 20 1998 null prw-r--r-- 1 root root 0 Mar 3 19:17 gpmdata srw-rw-rw- 1 root root 0 Dec 18 07:43 log

Notice the very first character of each line in the listing. If this character is b , c , p , or s , then the file is a device. These letters stand for block , character , pipe , and socket , respectively:

The numbers before the dates in the first two lines of the previous listing are the major and minor device numbers that help the kernel identify the device. Similar devices usually have the same major number, such as hda3 and hdb1 (these are both hard disk partitions).

2.3.1 dd and Devices

The name dd stands for convert and copy. dd is extremely useful when working with block and character devices. This program's sole function is to read from an input file or stream and write to an output file or stream, possibly doing some encoding conversion on the way. It was originally developed for reblocking .

dd copies data in blocks of a fixed size. Here is an example of using dd with a character device and some common options:

dd if=/dev/zero of=new_file bs=1024 count=1

As you can see, the dd option format is different than the option formats of most other Unix commands; rather than use the - character to signal an option, you name an option and set its value to something with the = sign. The preceding example copies a single 1024 -byte block from /dev/zero (a continuous stream of zero bytes) to the file new_file . These are the important dd options:

2.3.2 Device Name Summary

Sometimes it is difficult to find the name of a device (for example, when partitioning a disk). Here are two tactics for finding out:

Neither method is terribly reliable, especially because the kernel does not load certain device drivers until you try to use them. (Section 10.8 has information on the driver-loading mechanism.)

The following sections list the most common Linux devices and their naming conventions.

Hard Disks: /dev/hd*

These are the ATA (IDE) disks and partitions. All are block devices.

Two example names are /dev/hda1 and /dev/hdb . The letter after hd identifies the disk, and the number represents the partition. A device without a number is a device for an entire disk. (Information on how to partition disks is in Section 2.3.4. To connect disks to your current systems, start at Section 2.4.3.)

SCSI Disks: /dev/sd*

SCSI disks carry the names /dev/sda , /dev/sdb , and so on, and the disks work much like their ATA counterparts, although the SCSI disk names do not directly correspond to a SCSI host controller and target. Linux assigns the devices in the order that it encounters the disks.

For example, if you have two SCSI controllers, scsi0 and scsi1 , with disks at scsi0 targets 0, 3, and scsi1 target 1, the device assignments are as shown in Table 2-1.

Table 2-1: Sample Device Assignments

Controller

Target

Device Assignment

scsi0

/dev/sda

scsi0

3

/dev/sdb

scsi1

1

/dev/sdc

This naming scheme can cause problems when reconfiguring hardware. Let's say that scsi0 target 3 explodes and you must remove the disk so that the machine can work again. When you do so, scsi1 target 1 moves to /dev/sdb from /dev/sdc , and you have to change the fstab file (described later in this chapter).

Terminals: /dev/tty*, /dev/pts/*, /dev/tty

Terminals are devices for moving characters between the system and an I/O device, usually for text output to a terminal screen. The terminal device interface goes back a long way, to the days when terminals were typewriter-based devices.

Pseudo-terminal devices are emulated terminals that understand the I/O features of real terminals, but rather than talk to a real piece of hardware, the kernel presents the I/O interface to a piece of software, such as a shell window.

Two common terminal devices are /dev/tty1 (the first virtual console) and /dev/pts/0 (the first pseudo-terminal device).

The /dev/tty device is the controlling terminal of the current process. If a program is currently reading from and writing to a terminal, this device is a synonym for that terminal. A process does not need to be attached to aterminal.

Serial Ports: /dev/ttyS*

Serial ports are special terminal devices. You can't do much on the command line with serial port devices because there are too many settings to worry about, such as baud rate and flow control.

The port known as COM1 on Windows is /dev/ttyS0 , COM2 is /dev/ttyS1 , and so on. For add-in modem cards, check the output of the dmesg command for the port assignment.

Floppy Disks: /dev/fd*

Section 11.1.1 covers operations on these block devices. The 3.5-inch floppy on most modern systems is /dev/fd0 .

Parallel Ports: /dev/lp0, /dev/lp1

These unidirectional port devices correspond to LPT1 and LPT2 in Windows. You can send files (such as a file to be printed) directly to a parallel port with the cat command, but you might need to give the printer an extra form feed or reset afterward.

The bidirectional parallel ports are /dev/parport0 and /dev/parport1 .

Audio Devices: /dev/dsp, /dev/audio, /dev/mixer, /dev/snd/*, etc.

Linux has two different sets of audio devices. There are separate devices for the OSS (Open Sound System) and the newer ALSA (Advanced Linux Sound Architecture) system interface. Linux systems that use ALSA usually contain OSS compatibility devices, because most applications still use OSS. Some rudimentary operations are possible with the dsp and audio devices that belong to OSS. As mentioned earlier, the computer plays any WAV file that you send to /dev/dsp . However, it may not sound right due to frequency mismatches . The ALSA devices are in the /dev/snd directory, but you can't do much by redirecting standard I/O to them.

Note  

The play and aplay programs can play samples from the command line. To adjust the volume and mixer settings, aumix and alsamixer are available on most systems.

2.3.3 Creating Device Files

To create one individual device file, use mknod . You must know the device name as well as its major and minor numbers. For example, if you remove /dev/hda2 by accident , you can create it again with this command:

mknod /dev/hda2 b 3 2

The b 3 2 specifies a block device with a major number 3 and a minor number 2. For character or named pipe devices, use c or p instead of b .

The mknod command is useful only for creating the occasional missing device or named pipe. As you upgrade your system and add device drivers, you may need to create entirely new groups of devices. Because there are so many devices, it's better to use the MAKEDEV program (found in /dev ) to create groups of devices. Device groups can be named after the common part of several device names, such as hda , or they can have a completely separate name, such as std-hd . For example, to create all devices beginning with hda , run this command:

/dev/MAKEDEV hda

Note  

The MAKEDEV command is harmless if the devices already exist on your system.

devfs

Before you go to the trouble of making any device files, you should see whether you're running devfs , an automatic device-file generation system. The easiest way to check for devfs is to run mount and look for devfs in the output.

If your system runs devfs , you should not have to create missing device files because the kernel maintains the directory of available device files. Linux kernels typically configure devfs at boot time, starting a special auxiliary system program called devfsd that gives the administrator the ability to customize the device system.

Note  

devfs was an experimental feature in older Linux kernels, but is classified as obsolete in the latest Linux kernels.

2.3.4 Partitioning Disk Devices

Before you can use a new disk on your system, you need to know how to partition disks with their device files. If you've never worked with partitions before, don't worry. A disk partition is just a piece of the disk dedicated to one purpose, such as a specific directory tree. On PCs, partitions have numbers starting at 1.

To get started, identify the disk device that you want to partition. Most PCs have two ATA interfaces, called primary and secondary interfaces, and each interface can have a master and slave disk, for a total of four disk devices. The standard ATA disk assignments are as follows :

There are several partitioning utilities, but the most simple and direct is fdisk . To get started, run fdisk dev (where dev is one of the devices listed above), then print the current partition list with p .

Here is sample from fdisk output for a device with three partitions, two containing filesystems and one with swap (see Section 2.5 for more information on swap partitions).

Disk /dev/hda: 240 heads, 63 sectors, 2584 cylinders Units = cylinders of 15120 * 512 bytes Device Boot Start End Blocks Id System /dev/hda1 1 136 1028128+ 83 Linux /dev/hda2 137 204 514080 82 Linux swap /dev/hda3 205 2584 17992800 83 Linux

Partition dimensions are usually in units of cylinders . Each partition has a start and end cylinder, determining its size, but the amount of space per cylinder varies depending on the disk. The second line in the preceding output shows you the cylinder size, but you don't need to do any weird computations to create partitions.

When creating a new partition, you only need to know the starting cylinder. Cylinders do not overlap in PC partitions, so if you're partitioning a disk, pick the first available cylinder in the fdisk partition list output. In the preceding example, you would choose 2585 as the starting cylinder.

Each partition also has a system ID , a number that represents an operating system. Linux uses 83 for partitions containing files and 82 for Linux swap.

When you partition a new disk, there is usually one partition on the disk already, containing some sort of variant on the FAT filesystem for Microsoft systems. If you want only a single partition on the disk, just change the system ID to Linux with the t command inside fdisk . However, if you want to customize the partitions, use d to delete any old partitions and n to add new ones.

fdisk is easy to use because each command steps you through the partition number and size. In addition, there is an important safety feature: fdisk does not actually change the partition table until you tell it to with the w command. If you're uneasy about your changes, or you were just testing something, use q to exit without altering the disk.

Here is an example of fdisk in action on a very small disk. Command input is in boldface:

# fdisk /dev/hdc Command (m for help): p Disk /dev/hdc: 2 heads, 16 sectors, 247 cylinders Units = cylinders of 32 * 512 bytes Device Boot Start End Blocks Id System /dev/hdc1 * 1 494 7891+ 1 FAT12 Command (m for help): d Partition number (1-4): 1 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 Last cylinder or +size or +sizeM or +sizeK (1-247, default 247): 120 Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): 83 Command (m for help): p Disk /dev/hdc: 2 heads, 16 sectors, 247 cylinders Units = cylinders of 32 * 512 bytes Device Boot Start End Blocks Id System /dev/hdc1 1 120 1912 83 Linux Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: If you have created or modified any DOS 6.x partitions, please see the fdisk manual page for additional information. Syncing disks.

When you write the partition table to the disk with the w command, fdisk tells the kernel to re-read the partition table from the disk and update the system's in-memory partition list ( fdisk does not relay the new partition list directly to the kernel). Therefore, you should never write the partition table to a disk that already has a mounted (attached) filesystem; doing so risks damage to the filesystem.

Note  

The ioctl operation that causes the kernel to re-read the partition table can fail on rare occasions. If such a failure occurs, you need to reboot the system to get the kernel to see the changes.

After writing the partition table, a new list of partition tables should appear on the console. If you don't see this list, run dmesg to see the kernel messages and look at the end of the output. For the fdisk session earlier in this section, here is what you would see:

hdc: hdc1

The hda indicates the disk that you repartitioned. The new partition list appears after the colon . For example, if you create three partitions on the disk, the output might appear as hdc: hdc1 hdc2 hdc3 .

Note  

Looking at the fdisk session in this section, you may be wondering what the difference between a primary and an extended partition is. The standard PC disk-partitioning scheme originally only allowed a maximum of four partitions, 1 “4. These are the primary partitions. If you want more partitions, fdisk can designate one of these primary partitions as an extended partition, allowing you to place subpartitions in the extended partition. Each of these subpartitions is called a logical partition .

After partitioning a disk, you're not quite ready to attach it to your system because you must put a filesystem on your partition(s) first.

Категории