<!--Chapter 8 Device Drivers-->
<sect>デバイスドライバ<label id="chapter_dd">
<p>

<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/penguin2.gif">
</figure>

<!--
One of the purposes of an operating system is to hide the peculiarities of the
system's hardware devices from its users. For example the Virtual File
System presents a uniform view of the mounted filesystems irrespective of
the underlying physical devices. This chapter describes how the Linux kernel
manages the physical devices in the system. 
-->
<p>オペレーティングシステムの目的のひとつは、ユーザからシステムのハードウェア
の特殊性を隠すことである。たとえば仮想ファイルシステムは、土台となる物理
デバイスとは無関係に、マウントされたファイルシステムに統一的な視野を提供する。
この章では、Linux カーネルがシステム上の物理デバイスをどのように管理している
のかを解説する。

<!--
The CPU is not the only intelligent device in the system, every physical device
has its own hardware controller. The keyboard, mouse and serial ports are
controlled by a SuperIO chip, the IDE disks by an IDE controller, SCSI disks
by a SCSI controller and so on. Each hardware controller has its own control
and status registers (CSRs) and these differ between devices. The CSRs for
an Adaptec 2940 SCSI controller are completely different from those of an
NCR 810 SCSI controller. The CSRs are used to start and stop the device, to
initialize it and to diagnose any problems with it. Instead of putting code to
manage the hardware controllers in the system into every application, the
code is kept in the Linux kernel. The software that handles or manages a
hardware controller is known as a device driver. The Linux kernel device
drivers are, essentially, a shared library of privileged, memory resident, low
level hardware handling routines. It is Linux's device drivers that handle the
peculiarities of the devices they are managing. 
-->
<p>CPU だけがシステムで唯一の情報処理デバイスではなく、すべての物理デバイスが
独自のハードウェア制御装置を持っている。キーボード、マウス、シリアルポートは
 Super I/O チップで制御されており、IDE ディスクは IDE コントローラで、SCSI 
ディスクは SCSI コントローラで制御されている。個々のハードウェアコントローラは
独自のコントロールレジスタ(control registers)とステータスレジスタ(status 
registers)(あわせて CSRs)を持っている。それらレジスタの仕様はデバイスごとに異
なっており、Adaptec 2940 SCSI コントローラの CSRs は NCR 810 SCSI コントローラ
のそれとは別物である。CRSs はデバイスの始動と停止、初期化、そして問題診断
(diagnose)のために利用される。システム上のハードウェアコントローラを管理する
コードは、個々のアプリケーションに実装されるのではなく、Linux カーネルの中に
保持されている。
ハードウェアコントローラを操作あるいは管理するソフトウェアはデバイスドライバ
(device driver)と呼ばれている。Linux カーネルのデバイスドライバは、本質的に
特権を与えられ、メモリに常駐する、低レベルハードウェアの処理ルーチンから成る
共有ライブラリである。担当するデバイスの特殊性に対処するのが、Linux のデバイス
ドライバの役割である。

<!--
One of the basic features of Un*x is that it abstracts the handling of 
devices. All
hardware devices look like regular files; they can be opened, closed, read and
written using the same, standard, system calls that are used to manipulate
files. Every device in the system is represented by a device special file, for
example the first IDE disk in the system is represented by /dev/hda. For
block (disk) and character devices, these device special files are created by
the mknod command and they describe the device using major and minor
device numbers. Network devices are also represented by device special files
but they are created by Linux as it finds and initializes the network 
controllers in the system. All devices controlled by the same device driver 
have a common major device number. The minor device numbers are used to
distinguish between different devices and their controllers, for example each
partition on the primary IDE disk has a different minor device number. So,
/dev/hda2, the second partition of the primary IDE disk has a major number
of 3 and a minor number of 2. Linux maps the device special file passed in
system calls (say to mount a file system on a block device) to the device's
device driver using the major device number and a number of system tables,
for example the character device table, chrdevs . 
-->
<p>Un*x の基本的特徴のひとつは、デバイスの操作を抽象化していることである。
すべてのハードウェアデバイスは、通常ファイルのようのように見える。それらは、
ファイル操作で使用されるのと同じ標準的なシステムコールを利用して、オープン、
クローズ、書き込み、読み出しが可能である。システム上のあらゆるデバイスは、
デバイススペシャルファイルによって表現されていて、たとえば、システム上の最初の 
IDE ディスクは <tt>/dev/hda</tt> と表される。
<p>ブロック(ディスク)デバイスとキャラクタデバイスに関しては、それらのデバイス
スペシャルファイルは <tt>mknod</tt> コマンドによって作成され、デバイスを記述
するためにメジャー番号(<ref id="major_number" name="major number">)とマイナー
番号(minor number)とのデバイス番号が使用される。ネットワークデバイスも
デバイススペシャルファイルによって表現されるが、それらは Linux がシステム上の
ネットワークコントローラを見つけて初期化するときに Linux によって作成される。
同一のデバイスドライバによって制御されるすべてのデバイスコントローラは、共通の
メジャー番号を持つ。マイナーデバイス番号が使用されるのは、デバイスドライバが
異なるデバイスやそのデバイスのコントローラを区別するためである。たとえば、プラ
イマリ IDE ディスク上の個々のパーティションは異なるマイナー番号を持つ。それゆ
え、プライマリ IDE ディスクの第二パーティション <tt>/dev/hda2</tt> は、メジャー
番号 3 とマイナー番号 2 を持つ。
Linux は、システムコールで(たとえばブロックデバイス上のファイルシステムをマウン
トするなどして)渡されたデバイススペシャルファイルをそのデバイスのデバイスドライ
バにマップする。その際は、デバイスのメジャー番号といくつかのシステムテーブル、
たとえば <tt><ref id="device_struct" name="chrdevs"></tt> というキャラクタ
デバイステーブルなどを使用する。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/devices.c"
name="fs/devices.c">]<newline>

<!--
Linux supports three types of hardware device: character, block and network.
Character devices are read and written directly without buffering, for example
the system's serial ports /dev/cua0 and /dev/cua1. Block devices can
only be written to and read from in multiples of the block size, typically 512
or 1024 bytes. Block devices are accessed via the buffer cache and may be
randomly accessed, that is to say, any block can be read or written no matter
where it is on the device. Block devices can be accessed via their device
special file but more commonly they are accessed via the file system. Only a
block device can support a mounted file system. Network devices are
accessed via the BSD socket interface and the networking subsytems
described in the Networking chapter (Chapter  network-chapter). 
-->
<p>Linux は 3 種類のハードウェアデバイスをサポートしている。キャラクタデバイス
(character device)、ブロックデバイス(block device)、ネットワークデバイス(
network device)である。キャラクタデバイスは、バッファなしで直接読み書き
するデバイスであり、たとえばシステムのシリアルポート <tt>/dev/cua0</tt> や 
<tt>/dev/cua1</tt> などがそうである。ブロックデバイスとは、ブロックサイズの
倍数、典型的には 512 か 1024 バイトでのみ読み書きするデバイスである。
ブロックデバイスはバッファキャッシュ経由でアクセスされ、ランダムなアクセス、
すなわちデバイス上のどこにあるブロックでも読み書きできるアクセス方法が利用
されることが多い。ブロックデバイスへのアクセスは、それぞれに対応した
デバイススペシャルファイルを経由しても可能であるが、ファイルシステム経由で
アクセスするほうがより一般的である。マウントされるファイルシステムをサポート
できるのはブロックデバイスだけである。ネットワークデバイスへのアクセスは、
<ref id="chapter_net" name="「ネットワーク」">の章で解説する 
BSD ソケットインターフェイスまたはネットワークサブシステム経由で行なう。

<!--
There are many different device drivers in the Linux kernel (that is one of
Linux's strengths) but they all share some common attributes: 
-->
<p>Linux カーネル内には多種多様のデバイスドライバがある(これは、Linux の長所
のひとつである)が、それらすべてが以下の一般的な属性を共有している。

<!--
kernel code
      Device drivers are part of the kernel and, like other code within the
      kernel, if they go wrong they can seriously damage the system. A
      badly written driver may even crash the system, possibly corrupting
      file systems and losing data, 
-->
<descrip>
<tag>カーネルコード (kernel code)</tag>
デバイスドライバはカーネルの一部なので、カーネル内の他のコードと同様に、もし
上手く動かないとシステムに深刻な影響を与える。出来の悪いドライバはシステムを
クラッシュさせる場合すらあり、その結果ファイルシステムが破壊されデータが喪失
することもあり得る。

<!--
Kernel interfaces
      Device drivers must provide a standard interface to the Linux kernel
      or to the subsystem that they are part of. For example, the terminal
      driver provides a file I/O interface to the Linux kernel and a SCSI
      device driver provides a SCSI device interface to the SCSI subsystem
      which, in turn, provides both file I/O and buffer cache interfaces to the
      kernel. 
-->
<tag>カーネルインターフェイス (kernel interfaces)</tag>
デバイスドライバは、Linux カーネルやそれが所属するサブシステムに対して標準イン
ターフェイスを提供しなければならない。たとえば端末ドライバは Linux カーネルに
ファイルへの I/O インターフェイスを提供し、SCSI デバイスドライバは SCSI サブ
システムに対してインターフェイスを提供し、そのサブシステムが次に Linux カーネル
に対してファイル I/O とバッファキャッシュインターフェイスを提供する。

<!--
Kernel mechanisms and services
      Device drivers make use of standard kernel services such as memory
      allocation, interrupt delivery and wait queues to operate, 
-->
<tag>カーネルメカニズムとサービス</tag>
デバイスドライバは、メモリ割り当てや割り込みの伝達、待ち行列などの
標準的なカーネルサービスを利用する。

<!--
Loadable
      Most of the Linux device drivers can be loaded on demand as kernel
      modules when they are needed and unloaded when they are no longer
      being used. This makes the kernel very adaptable and efficient with
      the system's resources, 
-->
<tag>動的ロードが可能(loadable)</tag>
Linux のデバイスドライバの大部分は必要なときにオンデマンドでカーネルモジュール
としてロードが可能であり、必要が無くなればアンロードもできる。これによって、
カーネルの適用能力が高くなり、システムリソースの利用効率も上がる。

<!--
Configurable
      Linux device drivers can be built into the kernel. Which devices are
      built is configurable when the kernel is compiled, 
-->
<tag>設定の柔軟性</tag>
Linux のデバイスドライバはカーネル内に組み込むことも可能である。どのデバイス
を組み込むかは、カーネルのコンパイル時に設定できる。

<!--
Dynamic
      As the system boots and each device driver is initialized it looks for
      the hardware devices that it is controlling. It does not matter if the
      device being controlled by a particular device driver does not exist. In
      this case the device driver is simply redundant and causes no harm
      apart from occupying a little of the system's memory. 
-->
<tag>動的な設定(dynamic)</tag>
システムが起動して個々のデバイスドライバが初期化されると、ドライバは制御すべ
きハードウェアデバイスを捜す。特定のデバイスドライバにより制御されるはずの
デバイスが存在しなかったとしても問題はない。その場合、デバイスドライバは、
単に余分なだけであり、少量のシステムメモリが占有されることを除いて如何なる
悪影響も及ぼさない。
</descrip>


<!--8.1  Polling and Interrupts-->
<sect1>ポーリングと割り込み<label id="chapter_dd_sect1">

<!--
Each time the device is given a command, for example ``move the read head to
sector 42 of the floppy disk'' the device driver has a choice as to how it 
finds out that the command has completed. The device drivers can either poll 
the device or they can use interrupts. 
-->
<p>たとえば「読み取りヘッダをフロッピーディスクのセクタ 42 へ動かせ」といった
コマンドをデバイスが受け取ると、デバイスドライバは次のいずれかの方法、つまり
デバイスをポーリング(polling)するか、あるいは割り込み(interrupt)を使うことに
よって、そのコマンドが完了したかどうかを確認する。

<!--
Polling the device usually means reading its status register every so often
until the device's status changes to indicate that it has completed the 
request. As a device driver is part of the kernel it would be disasterous if a
driver were to poll as nothing else in the kernel would run until the device 
had completed the request. Instead polling device drivers use system timers to
have the kernel call a routine within the device driver at some later time. 
This timer routine would check the status of the command and this is exactly 
how Linux's floppy driver works. Polling by means of timers is at best 
approximate, a much more efficient method is to use interrupts. 
-->
<p>通常、デバイスのポーリングとは、デバイスのステータスレジスタが変化して、
リクエストの実行を完了したことが示されるまで、デバイスのステータスレジスタを
頻繁に読み出す操作を意味している。
デバイスドライバはカーネルの一部であるので、もし、ドライバがポーリングし続ける
とすると、システムに悪影響を与える。というのも、その場合、デバイスがリクエスト
を完了するまで、カーネル内では何も実行されなくなるからである。
しかし、実際にポーリングを行うデバイスドライバは、システムタイマーを使用して、
一定時間経過後に、カーネルにデバイスドライバ内のルーチンを呼び出してもらうよう
にしている。
このシステムタイマーのルーチンは、コマンドのステータスをチェックする。Linux の
フロッピードライバは、まさにこの仕組みを使っている。だが、タイマーを使った
ポーリングでは、精々大ざっぱな制御しかできない。もっと効率の良い方法は、
割り込み(interrupt)を使うことである。

<!--
An interrupt driven device driver is one where the hardware device being
controlled will raise a hardware interrupt whenever it needs to be serviced.
For example, an ethernet device driver would interrupt whenever it receives an
ethernet packet from the network. The Linux kernel needs to be able to deliver
the interrupt from the hardware device to the correct device driver. This is
achieved by the device driver registering its usage of the interrupt with the
kernel. It registers the address of an interrupt handling routine and the
interrupt number that it wishes to own. You can see which interrupts are being
used by the device drivers, as well as how many of each type of interrupts
there have been, by looking at /proc/interrupts: 
-->
<p>割り込みによって駆動されるデバイスドライバとは、ハードウェアデバイスが
サービスを要求するとき、ハードウェアデバイスがハードウェア割り込みをかける
ことで、制御されているものである。
たとえばイーサネットドライバは、イーサネットがネットワークからパケットを
受信したときに割り込みをかける。Linux カーネルは、ハードウェアデバイスから正し
いデバイスドライバへとその割り込みを伝達できなければならない。
これを実現するために、デバイスドライバは、割り込みの処理方法をカーネルに登録す
る。デバイスドライバが登録するのは、割り込み処理ルーチンのアドレスと占有したい
割り込み番号である。どの割り込みがデバイスドライバに使用されているか、
割り込みのタイプ(<ref id="type_of_interrupts" name="type of interrupts">)が
それぞれいくつあるかを確認するには、<tt>/proc/interrupts</tt> を見ればよい。

<verb>
 0:     727432   timer
 1:      20534   keyboard
 2:          0   cascade
 3:      79691 + serial
 4:      28258 + serial
 5:          1   sound blaster
11:      20868 + aic7xxx
13:          1   math error
14:        247 + ide0
15:        170 + ide1
</verb>

<!--
This requesting of interrupt resources is done at driver initialization time.
Some of the interrupts in the system are fixed, this is a legacy of the IBM
PC's architecture. So, for example, the floppy disk controller always uses
interrupt 6. Other interrupts, for example the interrupts from PCI devices are
dynamically allocated at boot time. In this case the device driver must first
discover the interrupt number (IRQ) of the device that it is controlling before
it requests ownership of that interrupt. For PCI interrupts Linux supports
standard PCI BIOS callbacks to determine information about the devices in
the system, including their IRQ numbers. 
-->
<p>割り込みリソースに関する要求は、ドライバの初期化の際に処理される。
システム上の割り込みのいくつかは固定されているが、それは IBM PC アーキテクチャ
の遺産である。したがって、たとえばフロッピーディスクコントローラは常に割り込み
 6 を使用する。それ以外の割り込み、たとえば PCI デバイスからの割り込みは、起動
時に動的に割り当てられる。その場合、デバイスドライバは、まず、制御している
デバイスの割り込み番号(IRQ)を検出した上で、その番号を占有する旨要求
しなければならない。PCI デバイスの割り込みに関して、Linux は、標準的な 
<ref id="chapter_pci_sect6-3" name="PCI BIOS"> のコールバックをサポートする
ことで、システム上のデバイスに関する、IRQ 番号等の情報を判断している。

<!--
How an interrupt is delivered to the CPU itself is architecture dependent but
on most architectures the interrupt is delivered in a special mode that stops
other interrupts from happening in the system. A device driver should do as
little as possible in its interrupt handling routine so that the Linux kernel 
can dismiss the interrupt and return to what it was doing before it was 
interrupted. Device drivers that need to do a lot of work as a result of 
receiving an interrupt can use the kernel's bottom half handlers or task 
queues to queue routines to be called later on. 
-->
<p>割り込みが CPU 自体に伝達される方法はアーキテクチャによって異なるが、大部分
のアーキテクチャでは、割り込みの伝達は、システム上で他の割り込みの発生を停止さ
せる特別なモードで行われる。したがって、デバイスドライバは、割り込み処理ルーチ
ン内でできる限り簡潔な処理をすべきである。そうすれば、Linux カーネルは割り込み
処理をすぐに終了して、割り込みが起こる前に実行していたことに戻ることができる。
割り込みを受信した結果多くの処理をしなければならなくなった場合、デバイスドライ
バは、カーネルのボトムハーフハンドラ(<ref id="chapter_km_sect1" 
name="bottom half handler">)かタスクキュー(<ref id="chapter_km_sect2" 
name="task queue">)
を使用してルーチンをキューイングし、後で呼び出すという方法を取ることができる。

<!--8.2  Direct Memory Access (DMA)-->
<sect1>ダイレクトメモリアクセス(Direct Memory Access, DMA)<label 
id="chapter_dd_sect2">

<!--
Using interrupts driven device drivers to transfer data to or from hardware
devices works well when the amount of data is reasonably low. For example a
9600 baud modem can transfer approximately one character every millisecond
(1/1000 'th second). If the interrupt latency, the amount of time that it takes
between the hardware device raising the interrupt and the device driver's
interrupt handling routine being called, is low (say 2 milliseconds) then the
overall system impact of the data transfer is very low. The 9600 baud modem
data transfer would only take 0.002% of the CPU's processing time. For high
speed devices, such as hard disk controllers or ethernet devices the data
transfer rate is a lot higher. A SCSI device can transfer up to 40 Mbytes of
information per second. 
-->
<p>割り込み駆動型のデバイスドライバを使ってハードウェアデバイスと情報をやり
取りすることが有効なのは、データ量が比較的少ないときである。たとえば 9600 baud 
のモデムはミリ秒(1/1000 秒)あたりおよそ一文字を送信可能である。割り込み遅延
(interrupt latency)、すなわちハードウェアデバイスが割り込みを発信してから
デバイスドライバの割り込み処理ルーチンが呼び出されるまでの時間が短い場合
(たとえば 2 ミリ秒)、データ転送に要するシステム全体へのインパクトは非常に小さ
い。9600 baud のモデムのデータ転送は、0.002&percnt; の CPU 処理時間しかかからな
い。しかし、ハードディスクコントローラやイーサネットのような高速なデバイスの
場合、データ転送レートはずっと高くなる。SCSI デバイスは、最大で毎秒 40 M バイト
の情報を転送できる。

<!--
Direct Memory Access, or DMA, was invented to solve this problem. A DMA
controller allows devices to transfer data to or from the system's memory
without the intervention of the processor. A PC's ISA DMA controller has 8
DMA channels of which 7 are available for use by the device drivers. Each
DMA channel has associated with it a 16 bit address register and a 16 bit
count register. To initiate a data transfer the device driver sets up the DMA
channel's address and count registers together with the direction of the data
transfer, read or write. It then tells the device that it may start the DMA 
when it wishes. When the transfer is complete the device interrupts the PC. 
Whilst the transfer is taking place the CPU is free to do other things. 
-->
<p>ダイレクトメモリアクセス(<ref id="DMA" name="DMA">)はこの問題を解決するため
に発明された。DMA 
コントローラによって、デバイスはプロセッサの介在なしでシステムメモリとの
データのやり取りが可能になる。ISA の DMA コントローラは 8 個の DMA チャンネル
を持っていて、そのうち 7 個はデバイスドライバによって使用することができる。
個々の DMA チャンネルは、16 ビットのアドレスレジスタ(address register)と 16 
ビットのカウントレジスタ(count register)を利用して、デバイスとメモリ間での
転送を行っている。データ転送を始める際、デバイスドライバは DMA チャンネルのアド
レスレジスタとカウントレジスタを設定し、同時に読み出しか書き込みかのデータ転送
の方向を設定する。そしてデバイスドライバは、デバイスに対して、デバイス側の準備
が整い次第 DMA データ転送を始めることを告げる。転送が完了したとき、デバイスは 
PC に割り込みをかける。転送が行われている間、CPU は自由の他のことが出来る。

<!--
Device drivers have to be careful when using DMA. First of all the DMA
controller knows nothing of virtual memory, it only has access to the physical
memory in the system. Therefore the memory that is being DMA'd to or from
must be a contiguous block of physical memory. This means that you cannot
DMA directly into the virtual address space of a process. You can however
lock the process's physical pages into memory, preventing them from being
swapped out to the swap device during a DMA operation. Secondly, the DMA
controller cannot access the whole of physical memory. The DMA channel's
address register represents the first 16 bits of the DMA address, the next 8
bits come from the page register. This means that DMA requests are limited
to the bottom 16 Mbytes of memory. 
-->
<p>デバイスドライバは DMA を使用する際に注意しなければならないことがある。
何よりも先ず、DMA コントローラは仮想メモリについては何も知らず、システムの物理
メモリだけにしかアクセスできないことである。したがって、DMA 転送で書き込まれ
たり読み出されたりするメモリは、物理メモリ上の連続したブロックでなければなら
ない。これは、DMA を使ってプロセスの仮想アドレス空間へ直接アクセスできないこと
を意味する。しかし、メモリ上のプロセスの物理ページをロックして、DMA 処理の間に
それらがスワップデバイスにスワップアウトされないようにすることができる。
次に、DMA コントローラは物理メモリの全域にアクセスできるわけではないということ
である。DMA チャンネルのアドレスレジスタは、DMA アドレスの最初の 16 ビットを
表し、次の 8 ビットは DMA のページレジスタ(page register)から来ている。
これは、DMA リクエストは、メモリの下位 16 M バイトに制限されていることを意味
する。

<!--
DMA channels are scarce resources, there are only 7 of them, and they
cannot be shared between device drivers. Just like interrupts, the device
driver must be able to work out which DMA channel it should use. Like
interrupts, some devices have a fixed DMA channel. The floppy device, for
example, always uses DMA channel 2. Sometimes the DMA channel for a
device can be set by jumpers; a number of ethernet devices use this
technique. The more flexible devices can be told (via their CSRs) which DMA
channels to use and, in this case, the device driver can simply pick a free
DMA channel to use. 
-->
<p>DMA チャンネルは 7 本しかない希少資源であり、デバイスドライバ間で共有が
できない。割り込みの場合のように、デバイスドライバは、どの DMA チャンネルを使う
か決定できなければならない。割り込みの場合と同様、デバイスのなかには固定された 
DMA チャンネルを持つものがある。たとえばフロッピーディスクは常に DMA チャンネ
ル 2 を使用する。デバイスによっては、 DMA チャンネルをジャンパによって設定する
ことができる。多くのイーサネットデバイスはこのテクニックを使用する。より柔軟な
デバイスでは、(CSRs 経由で)どの DMA チャンネルを使うかを伝えられるようになって
いて、その場合、デバイスドライバは単に空の DMA チャンネルを選んで使用することが
できる。

<!--
Linux tracks the usage of the DMA channels using a vector of dma_chan
data structures (one per DMA channel). The dma_chan data structure
contains just two fields, a pointer to a string describing the owner of the DMA
channel and a flag indicating if the DMA channel is allocated or not. It is 
this vector of dma_chan data structures that is printed when you cat
/proc/dma. 
-->
<p>Linux は DMA チャンネルの利用状況を監視するために、DMA チャンネルごとにひと
つある <tt><ref id="dma_chan" name="dma_chan"></tt> データ構造体の、配列を
使用する。 <tt>dma_chan</tt> データ構造体にはフィールドがふたつだけあり、DMA 
チャンネルを使用しているデバイスを記述した文字列へのポインタと、その DMA 
チャンネルがすでに割り当てされているかどうかを表すフラグが含まれている。
<tt>/proc/dma</tt> を <tt>cat</tt> した際にプリントされるのは、この
<tt>dma_chan</tt> データ構造体の配列である。


<!--8.3  Memory-->
<sect1>メモリ<label id="chapter_dd_sect3">

<!--
Device drivers have to be careful when using memory. As they are part of the
Linux kernel they cannot use virtual memory. Each time a device driver runs,
maybe as an interrupt is received or as a bottom half or task queue handler is
scheduled, the current process may change. The device driver cannot rely
on a particular process running even if it is doing work on its behalf. Like 
the rest of the kernel, device drivers use data structures to keep track of the
device that it is controlling. These data structures can be statically 
allocated, part of the device driver's code, but that would be wasteful as it 
makes the kernel larger than it need be. Most device drivers allocate kernel, 
non-paged, memory to hold their data. 
-->
<p>デバイスドライバは注意深くメモリを使用しなければならない。デバイスドライバは
Linux カーネルの一部であるので、仮想メモリは使用できない。割り込みの受信や
ボトムハーフハンドラやタスクキューハンドラの実行によって、デバイスドライバが
起動されるたびに、カレントプロセスが変化する。デバイスドライバは、実行中で
あったプロセスに代わって処理をする場合であっても、特定の実行中のプロセスに
依存できない。カーネルの他の部分と同様に、デバイスドライバはデータ構造体を
使用して、現在制御しているデバイスを監視する。それらのデータ構造体はデバイス
ドライバの一部として静的に割り付けられることも可能だが、それはカーネルを
必要以上に大きくするだけでリソースの無駄使いになる。大部分のデバイスドライバ
は、ページ単位に分割されていないカーネルメモリを割り当てて、データを保持して
いる。

<!--
Linux provides kernel memory allocation and deallocation routines and it is
these that the device drivers use. Kernel memory is allocated in chunks that
are powers of 2. For example 128 or 512 bytes, even if the device driver asks
for less. The number of bytes that the device driver requests is rounded up to
the next block size boundary. This makes kernel memory deallocation easier
as the smaller free blocks can be recombined into bigger blocks. 
-->
<p>Linux はカーネルメモリの割り当てと解放のためのルーチンを提供しているので、
デバイスドライバはそのルーチンを使用する。カーネルメモリは 2 の n 乗ごとの範囲
で割り当てられる。たとえば、デバイスドライバが少量のメモリしか要求しない場
合でも 128 や 512 バイトを割り当てる。デバイスドライバが要求するバイト数は、次
のブロックサイズの値にまで切り上げられる。これによって、小さな空きメモリの
ブロックをより大きなブロックに再結合しやすくなるので、カーネルメモリの解放と
統合が容易になる。

<!--
It may be that Linux needs to do quite a lot of extra work when the kernel
memory is requested. If the amount of free memory is low, physical pages may
need to be discarded or written to the swap device. Normally, Linux would
suspend the requestor, putting the process onto a wait queue until there is
enough physical memory. Not all device drivers (or indeed Linux kernel code)
may want this to happen and so the kernel memory allocation routines can be
requested to fail if they cannot immediately allocate memory. If the device
driver wishes to DMA to or from the allocated memory it can also specify that
the memory is DMA'able. This way it is the Linux kernel that needs to
understand what constitutes DMA'able memory for this system, and not the
device driver. 
-->
<p>カーネルメモリがリクエストされた際、Linux カーネルは非常に多くの余計な仕事
をしなければならない場合がある。空きメモリの量が不足する場合、物理ページは
破棄されるかスワップデバイスに書き込まれる必要がある。通常、Linux は、要求した
プロセスを待ち行列に入れて、充分なメモリが確保されるまでそれをサスペンド状態に
する。しかし、デバイスドライバ(あるいは Linux カーネルコード)のなかにはサスペン
ドできないプロセスもあるので、そうした場合、すぐにメモリを確保できないときは、
カーネルメモリ割り当てルーチンは、リクエストの処理に失敗することもある。
デバイスドライバが DMA を使用して割り当てられたメモリに対して書き込みや読み出し
をしたい場合、ドライバは、そのカーネルメモリを DMA 転送が可能であると指定する
こともできる。この場合、システム上で DMA 転送が可能なメモリの構成がどうなって
いるのか理解しなければならないのは、デバイスドライバではなく、Linux カーネル
である。

<!--8.4  Interfacing Device Drivers with the Kernel-->
<sect1>デバイスドライバとカーネルとのインターフェイス<label 
id="chapter_dd_sect4">

<!--
The Linux kernel must be able to interact with them in standard ways. Each
class of device driver, character, block and network, provides common
interfaces that the kernel uses when requesting services from them. These
common interfaces mean that the kernel can treat often very different devices
and their device drivers absolutely the same. For example, SCSI and IDE
disks behave very differently but the Linux kernel uses the same interface to
both of them. 
-->
<p>Linux カーネルとデバイスドライバーとの相互通信は、標準的な方法で行われなけれ
ばならない。キャラクタデバイス、ブロックデバイス、ネットワークデバイスなど
個々のデバイスドライバのクラス(class)は、クラス共通のインターフェイスを提供して
いて、カーネルがそれらにサービスをリクエストする際は個々のクラスのインターフェ
イスを使用する。
各クラスのデバイスやデバイスドライバはしばしばかなり性質の異なることがあるが、
共通のインターフェイスがあることで、それらを全く同じものとして扱うことができ
る。たとえば、SCSI と IDE ディスクとは非常に異なった動作をするが、Linux カーネ
ルはそれら両方に対して同じインターフェイスを使用することができる。

<!--
Linux is very dynamic, every time a Linux kernel boots it may encounter
different physical devices and thus need different device drivers. Linux allows
you to include device drivers at kernel build time via its configuration 
scripts. When these drivers are initialized at boot time they may not discover
any hardware to control. Other drivers can be loaded as kernel modules when 
they are needed. To cope with this dynamic nature of device drivers, device 
drivers register themselves with the kernel as they are initialized. Linux 
maintains tables of registered device drivers as part of its interfaces with 
them. These tables include pointers to routines and information that support 
the interface with that class of devices. 
-->
<p>Linux は動的な設定にも柔軟に対応する。Linux は、起動のたびに異なった物理デバ
イスを検出するかもしれないので、そのために様々なデバイスドライバを必要とする。
Linux では、カーネルビルドの際の設定によって、デバイスドライバをカーネル
に組み込むことができる。しかし、起動時に初期化される際、組み込まれたデバイス
ドライバは、制御すべきハードウェアを見つけられないことがある。また、カーネルに
組み込まれない場合でも、ドライバが必要なときは、カーネルモジュールとしてそれを
ロードすることもできる。
このような動的なデバイスドライバの性質に対処するために、デバイスドライバは初期
化される際にカーネルに対して自分の情報を登録する。Linux は、それらへのインター
フェイスの一部として、登録されたデバイスドライバのテーブルを管理している。
それらのテーブルには、そのクラスのデバイスへのインターフェイスをサポートする
ルーチンおよび情報へのポインタが含まれている。

<!--8.4.1  Character Devices-->
<sect2>キャラクタデバイス<label id="chapter_dd_sect4-1">
<p>

<!--                  Figure 8.1: Character Devices-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure8-1.gif">
</figure>
</#if>
<#unless output="html">
<verb>
   chrdevs
+---------------+
|  name         |
|  fops         |---------->    file operations
|---------------|
|               |                lseek
|               |                read
|               |                write
|               |                readdir
|               |                select
|               |                ioctl
|               |                mmap
|               |                open
|               |                release
|               |                fsync
|               |                fasync
|               |                check_media_change
+---------------+                revalidate
</verb>
</#if>
<p>図表(8.1) キャラクタデバイス


<!--
Character devices, the simplest of Linux's devices, are accessed as files,
applications use standard system calls to open them, read from them, write to
them and close them exactly as if the device were a file. This is true even if
the device is a modem being used by the PPP daemon to connect a Linux
system onto a network. As a character device is initialized its device driver
registers itself with the Linux kernel by adding an entry into the chrdevs
vector of device_struct data structures. The device's major device
identifier (for example 4 for the tty device) is used as an index into this
vector. The major device identifier for a device is fixed. 

-->
<p>キャラクタデバイス(character device)は、Linux の中で最もシンプルなデバイス
である。それらはファイルとしてアクセスできるので、まるでそのデバイスがファイル
と全く同じであるかのように、アプリケーションは、標準システムコールを使用して
それらをオープンし、読み出しや書き込みをし、クローズする。
これは、デバイスとしてモデムを使い、PPP デーモンで Linux システムをネット
ワークに接続する場合でも同じである。キャラクタデバイスが初期化されるとき、その
デバイスドライバは、自分自身を Linux カーネルに登録するのだが、その際は、<tt>
<ref id="device_struct" name="device_struct"></tt> データ構造体による配列 <tt>
<ref id="device_struct" name="chrdevs"></tt> にエントリを追加する。
デバイスのメジャー番号(たとえば、4 は <tt>tty</tt> デバイス)は、
この配列へのインデックスとして使用される。デバイスの<ref id="major_number" 
name="メジャー番号">は、予め決められている。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/major.h"
name="include/linux/major.h">]<newline>

<!--
Each entry in the chrdevs vector, a device_struct data structure
contains two elements; a pointer to the name of the registered device driver
and a pointer to a block of file operations. This block of file operations is 
itself the addresses of routines within the device character device driver 
each of which handles specific file operations such as open, read, write and 
close. The contents of /proc/devices for character devices is taken from the
chrdevs vector. 
-->
<p><tt><ref id="device_struct" name="chrdevs"></tt> 配列の個々のエントリである
<tt><ref id="device_struct" name="device_struct"></tt> データ構造体には、
ふたつの要素がある。登録されたデバイスドライバの名前へのポインタと、ファイル操
作ルーチン群へのポインタである。
このファイル操作ルーチン群は、それ自体が当該デバイスのキャラクタデバイス
ドライバ内にあるルーチンのアドレスであり、その個々のルーチンが、<tt>open, 
read, write, close</tt> などファイルへの特定の操作を処理する。
キャラクタデバイスに関する <tt>/proc/devices</tt> の内容は、<tt>chrdevs</tt> 
配列から取得される。

<!--
When a character special file representing a character device (for example
/dev/cua0) is opened the kernel must set things up so that the correct
character device driver's file operation routines will be called. Just like an
ordinairy file or directory, each device special file is represented by a VFS
inode . The VFS inode for a character special file, indeed for all device 
special files, contains both the major and minor identifiers for the device. 
This VFS inode was created by the underlying filesystem, for example EXT2, from
information in the real filesystem when the device special file's name was
looked up. 
-->
<p>キャラクタデバイスを表すキャラクタ型スペシャルファイル(たとえば <tt>
/dev/cua0</tt>)がオープンされるとき、カーネルは適切な設定を行い、正しいキャラ
クタデバイスドライバのファイル操作ルーチンが呼び出されるようにしなければなら
ない。通常の
ファイルやディレクトリの場合と同様に、個々のデバイススペシャルファイルは VFS 
<tt><ref id="inode" name="inode"></tt> によって表される。
キャラクタ型スペシャルファイルの VFS inode には、すべてのスペシャルファイルと
同様に、デバイスに関するメジャー番号とマイナー番号が含まれている。
この VFS inode は、デバイススペシャルファイルの名前が問い合わせされる際に、
実ファイルシステム内の情報を元にして、<tt>EXT2</tt> などの基本ファイルシステム
によって作成される。
<newline>[see: ext2_read_inode(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/ext2/inode.c" 
name="fs/ext2/inode.c">]<newline>

<!--
Each VFS inode has associated with it a set of file operations and these are
different depending on the filesystem object that the inode represents.
Whenever a VFS inode representing a character special file is created, its file
operations are set to the default character device operations. 
This has only one file operation, the open file operation. When the character
special file is opened by an application the generic open file operation uses 
the device's major identifier as an index into the chrdevs vector to retrieve 
the file operations block for this particular device. It also sets up the file
data structure describing this character special file, making its file 
operations pointer point to those of the device driver. Thereafter all of the 
applications file operations will be mapped to calls to the character devices 
set of file operations. 
-->
<p>個々の VFS inode は一連のファイル操作ルーチンと関連付けられるので、それら 
VFS inode の性質は、その inode が表現しているファイルシステムオブジェクトの
種類によって異なったものとなる。
キャラクタ型スペシャルファイルを表す VFS inode が作成される際はいつも、デフォル
トのキャラクタデバイス操作ルーチンがそのファイルの操作ルーチンとして設定され
る。
<newline>[see: def_chr_fops, in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/devices.c" 
name="fs/devices.c">]
<newline>[see: chrdev_open(), in <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/devices.c" 
name="fs/devices.c">]<newline>
このデフォルトのルーチンは、ファイルのオープンというひとつだけのファイル操作を
含むものである。アプリケーションによってキャラクタファイルがオープンされたと
き、その汎用のファイルオープン操作ルーチンは、デバイスのメジャー番号を <tt>
<ref id="device_struct" name="chrdevs"></tt> 配列へのインデックスとして使用し
て、その特定のデバイス用のファイル操作ルーチン群を取ってくる。またそれは、
当該キャラクタスペシャルファイルを記述する <tt><ref id="file" name="file">
</tt> データ構造体を設定し、そのファイル操作ルーチンへのポインタが当該デバイ
スドライバのファイル操作関数群を差すようにする。こうして、アプリケーションの
ファイル操作ルーチンはすべてマップされ、そのキャラクタデバイスに対する一連の
ファイル操作ルーチンの呼び出しに備える。

<!--8.4.2  Block Devices-->
<sect2>ブロックデバイス<label id="chapter_dd_sect4-2">

<!--
Block devices also support being accessed like files. The mechanisms used to
provide the correct set of file operations for the opened block special file 
are very much the same as for character devices. Linux maintains the set of
registered block devices as the blkdevs vector. It, like the chrdevs vector,
is indexed using the device's major device number. Its entries are also
device_struct data structures. Unlike character devices, there are
classes of block devices. SCSI devices are one such class and IDE devices
are another. It is the class that registers itself with the Linux kernel and
provides file operations to the kernel. The device drivers for a class of block
device provide class specific interfaces to the class. So, for example, a SCSI
device driver has to provide interfaces to the SCSI subsystem which the SCSI
subsystem uses to provide file operations for this device to the kernel. 
-->
<p>ブロックデバイスの場合も、ファイルにアクセスするときのようにアクセスできる
仕組みがサポートされている。オープンされたブロック型スペシャルファイルを操作
するために適切な一連のファイル操作ルーチンを提供する際、そのために使用される
メカニズムは、キャラクタデバイスの場合と全く同じである。Linux は、<tt><ref 
id="device_struct" name="blkdevs"></tt> 配列によって、登録された一連のブロック
デバイスを管理している。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/fs/devices.c" 
name="fs/devices.c">]<newline>
それは、<tt><ref id="device_struct" name="chrdevs"></tt> 配列と同様に、デバイス
のメジャー番号を使って索引付けされている。そのエントリも <tt><ref 
id="device_struct" name="device_struct"></tt> データ構造体である。
キャラクタデバイスと違う点は、ブロックデバイスにはクラスがあることである。
SCSI デバイスがそれであり、IDE デバイスもそうである。Linux に自分自身を
登録するのも、カーネルにファイル操作ルーチンを提供するのも、そうしたクラス
である。
ブロックデバイスのクラスに対するデバイスドライバは、そのクラスにクラス固有の
インターフェイスを提供する。それゆえ、たとえば SCSI デバイスドライバは、SCSI 
サブシステムに対してクラス固有のインターフェイスを提供しなければならず、
SCSI サブシステムはそれを使ってそのデバイスに対するファイル操作をカーネルに
提供する。

<!--
Every block device driver must provide an interface to the buffer cache as
well as the normal file operations interface. Each block device driver fills 
in its entry in the blk_dev vector 
of blk_dev_struct data structures . The index into this vector is, again, the
device's major number. The blk_dev_struct data structure consists of the
address of a request routine and a pointer to a list of request data
structures, each one representing a request from the buffer cache for the
driver to read or write a block of data. 
-->
<p>すべてのブロックデバイスドライバは、通常のファイル操作インターフェイスに
加えて、バッファキャッシュへのインターフェイスを提供しなければならない。個々の
ブロックデバイスドライバは、<tt><ref id="blk_dev_struct" 
name="blk_dev_struct"></tt> データ構造体の配列である <tt><ref 
id="blk_dev_struct" name="blk_dev"></tt> 内に自分のエントリを作成する。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/drivers/block/ll_rw_blk.c" 
name="drivers/block/ll_rw_blk.c">]
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/blkdev.h" 
name="include/linux/blkdev.h">]<newline>
この配列へのインデックスもまたデバイスのメジャー番号である。<tt>blk_dev_struct
</tt> データ構造体は、リクエストルーチンのアドレスと <tt><ref id="request" 
name="request"></tt> データ構造体のリストへのポインタによって構成される。
個々の <tt>request</tt> 構造体は、デバイスドライバにデータブロックを読み書き
させようとする、バッファキャッシュからのリクエストを表現している。


<!--           Figure 8.2: Buffer Cache Block Device Requests-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure8-2.gif">
</figure>
</#if>
<#unless output="html">
<verb>
     blk_dev
+---------------+
|               |
|               |     request          request
|---------------|   +---------+    +---------+
|request_fn()   |-->|rq_status| +->|rq_status|
|current_request|   |---------| |  |---------|
|               |   | rq_dev  | |  | rq_dev  |
|---------------|   |---------| |  |---------|
|               |   | mcd     | |  | mcd     |
|  :            |   |---------| |  |---------|
|               |   |         | |  |         |
|  :            |   |         | |  |         |
|               |   |---------| |  |---------|
|               |   | sem     | |  | sem     |   buffer_head
|               |   |---------| |  |---------|   +---------+
|               |   | bh      | |  | bh      |-->| b_dev   |0x0301
|---------------|   |---------| |  |---------|   |---------|
|               |   | tail    | |  | tail    |   |b_blocknr|39
|               |   |---------| |  |---------|   |---------|
|---------------|   | next    |-+  | next    |   | b_state |
|               |   +---------+    +---------+   |---------|
|               |                                | b_count |
+---------------+                                |---------|
                                                 | b_size  |1024
blk_dev_struct 配列                              |---------|
                                                 |         |
                                                 |         |
                                                 |---------|
                                                 | b_next  |
                                                 |---------|
                                                 | b_prev  |
                                                 |---------|
                                                 |         |
                                                 |         |
                                                 |---------|
                                                 | b_data  |
                                                 +---------+
</verb>
</#if>
<p>図表(8.2) バッファキャッシュブロックデバイスリクエスト


<!--
Each time the buffer cache wishes to read or write a block of data to or from a
registered device it adds a request data structure onto its
blk_dev_struct. Figure  8.2 shows that each request has a pointer to one
or more buffer_head data structures, each one a request to read or write a
block of data. The buffer_head structures are locked (by the buffer cache)
and there may be a process waiting on the block operation to this buffer to
complete. Each request structure is allocated from a static list, the
all_requests list. If the request is being added to an empty request list,
the driver's request function is called to start processing the request queue.
Otherwise the driver will simply process every request on the request list. 
-->
<p>バッファキャッシュが登録済みデバイスに対してデータブロックを読み書きしよ
うとする度に、バッファキャッシュはその <tt><ref id="blk_dev_struct" 
name="blk_dev_struct"></tt> に対して <tt><ref id="request" name="request">
</tt> データ構造体を付け加える。図表(8.2)では、個々のリクエストが
ひとつの以上の <tt><ref id="buffer_head" name="buffer_head"></tt> データ構造体
へのポインタを持っていて、それぞれがデータブロックの読み書きのリクエストとなっ
ていることが示されている。
<tt>buffer_head</tt> データ構造体は、(バッファキャッシュによって)ロックされ
るので、そのバッファへのブロック操作の完了を待っているプロセスが存在すること
がある。個々の <tt>request</tt> 構造体は、<tt><ref id="request" 
name="all_requests"></tt> リストというスタティックなリストから割り当てられる。
リクエストが空のリクエストリストに付け加えられた場合、ドライバのリクエスト処理
関数が呼び出され、リクエストキューの処理を始める。そうでない場合、ドライバは単
にリクエストリストにあるすべての <tt>request</tt> を処理する。

<!--
Once the device driver has completed a request it must remove each of the
buffer_head structures from the request structure, mark them as up to
date and unlock them. This unlocking of the buffer_head will wake up any
process that has been sleeping waiting for the block operation to complete. An
example of this would be where a file name is being resolved and the EXT2
filesystem must read the block of data that contains the next EXT2 directory
entry from the block device that holds the filesystem. The process sleeps on
the buffer_head that will contain the directory entry until the device driver
wakes it up. The request data structure is marked as free so that it can be
used in another block request. 
-->
<p>デバイスドライバがあるリクエストの処理を完了すると、ドライバは、<tt><ref 
id="request" name="request"></tt> 構造体から個々の <tt><ref id="buffer_head" 
name="buffer_head"></tt> 構造体を削除し、それらが更新されたことをマークして、
ロックを解除しなければならない。<tt>buffer_head</tt> のロック
解除はブロック操作の完了を待っているすべてのプロセスを目覚めさせる。たとえば、
ファイル名を解決するために、EXT2 ファイルシステムは、そのファイルシステムを
保持するブロックデバイスから次の EXT2 ディレクトリエントリーを含んだデータ
ブロックを読み出さなければならないとする。そのプロセスは、読み出そうとする
ディレクトリエントリを含む <tt>buffer_head</tt> 上でスリープ状態にあるが、
デバイスドライバがそのプロセスを目覚めさせる。(操作が完了すると) <tt>request
</tt> データ構造体は利用可能とマークされるので、次のブロックリクエストの際に
使用される。

<!--8.5  Hard Disks-->
<sect1>ハードディスク<label id="chapter_dd_sect5">

<!--
Disk drives provide a more permanent method for storing data, keeping it on
spinning disk platters. To write data, a tiny head magnetizes minute particles
on the platter's surface. The data is read by a head, which can detect whether
a particular minute particle is magnetized. 
-->
<p>ディスクドライブは、データを回転ディスクプラッタ(platter)上に保持すること
で、メモリよりもデータを長期的に保存する仕組みを提供する。データの書き込みには
小さなヘッドがプラッタの表面にある微細な粒子を磁化する。データはヘッドによって
読み出され、そのヘッドが特定の微細な粒子の磁化の有無を検出している。

<!--
A disk drive consists of one or more platters, each made of finely polished
glass or ceramic composites and coated with a fine layer of iron oxide. The
platters are attached to a central spindle and spin at a constant speed that 
can vary between 3000 and 10,000 RPM depending on the model. Compare this to
a floppy disk which only spins at 360 RPM. The disk's read/write heads are
responsible for reading and writing data and there is a pair for each platter,
one head for each surface. The read/write heads do not physically touch the
surface of the platters, instead they float on a very thin (10 millionths of an
inch) cushion of air. The read/write heads are moved across the surface of the
platters by an actuator. All of the read/write heads are attached together, 
they all move across the surfaces of the platters together. 
-->
<p>ディスクドライブは一枚以上のプラッタから構成される。個々のプラッタは丹念に
磨かれたガラスかセラミック合金から成り、酸化鉄の非常に薄い層でコートされて
いる。プラッタはセンタースピンドル(central spindle)に取り付けられ、モデルによっ
て違いがあるが、3000 から 10,000 の間の一定の速度で回転する。
これと比較した場合、フロッピーは 360 RPM でしか回転しない。
ディスクの読み書きヘッドはデータの読み書きを担当し、プラッタ
一枚に一組、その両面に装着されている。読み書きヘッドはプラッタ表面に物理的に
接触することなく、非常に薄い(1/1千万 インチ)空気の層をクッションに浮いている。
読み書きヘッドはアクチュエータによってプラッタの表面を移動する。すべての
読み書きヘッドは一体となっていて、プラッタ表面上をすべてが同時に動く。
(訳注: RPM, Revolutions Per Minute, 分あたりの回転数)

<!--
Each surface of the platter is divided into narrow, concentric circles called
tracks. Track 0 is the outermost track and the highest numbered track is the
track closest to the central spindle. A cylinder is the set of all tracks with
the same number. So all of the 5th tracks from each side of every platter in 
the disk is known as cylinder 5. As the number of cylinders is the same as the
number of tracks, you often see disk geometries described in terms of
cylinders. Each track is divided into sectors. A sector is the smallest unit of
data that can be written to or read from a hard disk and it is also the disk's
block size. A common sector size is 512 bytes and the sector size was set
when the disk was formatted, usually when the disk is manufactured. 
-->
<p>プラッタの個々の表面は、トラック(track)とよばれる細い同心円に分割されてい
る。トラック 0 が一番外側のトラックであり、最も大きな番号のトラックがセンター
スピンドルに最も近い位置にある。シリンダー(cylinder)とは、同一番号のトラックを
すべて一組にした概念である。それゆえ、ディスク内のすべてのプラッタの両面にある
 5 番トラック全体が、シリンダー 5 と呼ばれる。シリンダ数はトラック数と同じ
なので、ディスクジオメトリは、シリンダの方を使って記述される。個々のトラック
はセクタ(sector)に分割される。セクタはハードディスクで読み書き可能な最も小さな
データ単位であり、ディスクブロックサイズでもある。一般的なセクタサイズは 512 
バイトであり、セクタサイズはディスクのフォーマット時、通常はディスクが製造
された時に設定される。

<!--
A disk is usually described by its geometry, the number of cylinders, heads
and sectors. For example, at boot time Linux describes one of my IDE disks
as: 
-->
<p>ディスクは通常、シリンダ(cylinder)、ヘッド(head)、セクタ(sector)という
ジオメトリによって記述される。たとえば起動時に、Linux は IDE ディスクを次の
ように記述する。

<verb>
hdb: Conner Peripherals 540MB - CFS540A, 516MB w/64kB Cache, CHS=1050/16/63
</verb>

<!--
This means that it has 1050 cylinders (tracks), 16 heads (8 platters) and 63
sectors per track. With a sector, or block, size of 512 bytes this gives the 
disk a storage capacity of 529200 bytes. This does not match the disk's stated
capacity of 516 Mbytes as some of the sectors are used for disk partitioning
information. Some disks automatically find bad sectors and re-index the disk
to work around them. 
-->
<p>上記は、ディスクが 1050 シリンダ(トラック)、16 ヘッド(8 プラッタ)、そして
トラックごとに 63 セクタを持つことを意味する。セクタもしくはブロックサイズが
 512 バイトの場合、ディスクは 529200 キロバイト (1 キロバイト = 1024 バイト
として) の記憶容量を持つことになる。これはディスク情報として表示されるサイズ
である 516 メガバイトと一見異なっているように見えるが、529200 / 1024 は約 
516.8 となり、実は合っている。
(訳注: ちなみに 540MB というのは 1MB = 1000 x 1000 バイトで計算した場合の
数値である。)
ディスクのなかには、自動的に不良セクタを検出して、そのセクタの周辺にあるセクタ
を適切に利用するために、ディスクのインデックスを付け直すものもある。

<!--
Hard disks can be further subdivided into partitions. A partition is a large
group of sectors allocated for a particular purpose. Partitioning a disk allows
the disk to be used by several operating system or for several purposes. A lot
of Linux systems have a single disk with three partitions; one containing a
DOS filesystem, another an EXT2 filesystem and a third for the swap
partition. The partitions of a hard disk are described by a partition table; 
each entry describing where the partition starts and ends in terms of heads, 
sectors and cylinder numbers. For DOS formatted disks, those formatted by 
fdisk, there are four primary disk partitions. Not all four entries in the 
partition table have to be used. There are three types of partition supported 
by fdisk, primary, extended and logical. Extended partitions are not real 
partitions at all, they contain any number of logical parititions. Extended 
and logical partitions were invented as a way around the limit of four primary
partitions. The following is the output from fdisk for a disk containing two 
primary partitions: 
-->
<p>ハードディスクはさらにパーティションに分割できる。パーティションは特別な
目的のために割り当てられたセクタの大規模なグループである。ディスクを
パーティションに分割することで、そのディスクを様々なオペレーティング
システムや様々な目的に利用することが可能になる。多くの Linux システムは、
単一ディスク上に 3 つのパーティションを持つ。ひとつは DOS ファイルシステムを
持ち、ふたつ目が EXT2 ファイルシステム、3 つ目がスワップパーティションを持つ。
ハードディスクのパーティションは、パーティションテーブルによって記述
されている。その個々のエントリは、パーティションの最初と最後の位置をヘッド、
セクタ、シリンダ番号によって記述している。<tt>fdisk</tt> でフォーマットされ
た、DOS フォーマットのディスクの場合、4 つのプライマリディスクパーティション
が存在するが、4 つ全部のエントリがパーティションテーブルで使用される必要はな
い。<tt>fdisk</tt> によってサポートされているパーティションタイプには、
プライマリ、拡張(extended)、論理(logical)の 3 種類がある。拡張パーティション
は実際のパーティションではなく、それらは任意の数の論理パーティションを含む。
拡張パーティションと論理パーティションとは、4 つのプライマリパーティションと
いう限界を回避するために発明された。次に示すのは、ふたつのプライマリ
パーティションを含むディスクに対する <tt>fdisk</tt> の出力である。

<verb>
Disk /dev/sda: 64 heads, 32 sectors, 510 cylinders
Units = cylinders of 2048 * 512 bytes

   Device Boot   Begin    Start      End   Blocks   Id  System
/dev/sda1            1        1      478   489456   83  Linux native
/dev/sda2          479      479      510    32768   82  Linux swap

Expert command (m for help): p

Disk /dev/sda: 64 heads, 32 sectors, 510 cylinders

Nr AF  Hd Sec  Cyl  Hd Sec  Cyl   Start    Size ID
 1 00   1   1    0  63  32  477      32  978912 83
 2 00   0   1  478  63  32  509  978944   65536 82
 3 00   0   0    0   0   0    0       0       0 00
 4 00   0   0    0   0   0    0       0       0 00
</verb>

<!--
This shows that the first partition starts at cylinder or track 0, head 1 and
sector 1 and extends to include cylinder 477, sector 32 and head 63. As there
are 32 sectors in a track and 64 read/write heads, this partition is a whole
number of cylinders in size. fdisk alligns partitions on cylinder boundaries by
default. It starts at the outermost cylinder (0) and extends inwards, towards
the spindle, for 478 cylinders. The second partition, the swap partition, 
starts at the next cylinder (478) and extends to the innermost cylinder of the
disk. 
-->
<p>上記では、第一パーティションは、シリンダもしくはトラック 0 、ヘッド 1 、
そしてセクタ 1 から始まり、シリンダ 477 、セクタ 32 、そしてヘッド 63 まで
の領域になっている。トラックあたり 32 セクタで、 64 ヘッドあるので、この
パーティションは、シリンダ数に合致した容量を持つ。<tt>fdisk</tt> は、
デフォルトでシリンダの境界線上で区切って、パーティションを割り当てる。
<tt>fdisk</tt>は、最外周のシリンダ(0)から出発して、内側方向に広げていき、
回転軸に向かって 478 シリンダから構成される領域を割り当てている。
第二パーティションはスワップパーティションであり、次のシリンダ(478)から
スタートしてディスクの最内周のシリンダに及んでいる。

<label id="figure8-3">
<!--                  Figure 8.3: Linked list of disks-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure8-3.gif">
</figure>
</#if>
<#unless output="html">
<verb>
gendisk_head    gendisk             gendisk
            +-----------+        +-----------+
----------->| major     |8    +->| major     |3
            |-----------|     |  |-----------|
            |major_name |"sd" |  |major_name |"ide0"
            |-----------|     |  |-----------|
            |minor_shift|     |  |minor_shift|
            |-----------|     |  |-----------|
            | max_p     |     |  | max_p     |
            |-----------|     |  |-----------|
            | max_nr    |     |  | max_nr    |
            |-----------|     |  |-----------|
            | init()    |     |  | init()    |   hd_struct[]
            |-----------|     |  |-----------|   +----------+  *
            | part      |     |  | part      |-->|start_sect| /|
            |-----------|     |  |-----------|   | nr_sects |  |
            | sizes     |     |  | sizes     |   |----------|  |
            |-----------|     |  |-----------|   |          |  |
            | nr_real   |     |  | nr_real   |   |  :       |  |
            |-----------|     |  |-----------|   |          |
            |real_device|     |  |real_device|   |  :       | max_p
            |-----------|     |  |-----------|   |          |
            | next      |-----+  | next      |   |  :       |  |
            +-----------+        +-----------+   |          |  |
                                                 |----------|  |
                                                 |start_sect|  |
                                                 | nr_sects |  |/
                                                 +----------+  *
</verb>
</#if>
<p>図表(8.3) ディスクの連結リスト


<!--
During initialization Linux maps the topology of the hard disks in the system.
It finds out how many hard disks there are and of what type. Additionally,
Linux discovers how the individual disks have been partitioned. This is all
represented by a list of gendisk data structures pointed at by the
gendisk_head list pointer. As each disk subsystem, for example IDE, is
initialized it generates gendisk data structures representing the disks that it
finds. It does this at the same time as it registers its file operations and 
adds its entry into the blk_dev data structure. Each gendisk data structure has
a unique major device number and these match the major numbers of the block
special devices. For example, the SCSI disk subsystem creates a single
gendisk entry (``sd'') with a major number of 8, the major number of all
SCSI disk devices. Figure  8.3 shows two gendisk entries, the first one for
the SCSI disk subsystem and the second for an IDE disk controller. This is
ide0, the primary IDE controller. 
-->
<p>初期化の過程で Linux はシステム上のハードディスクのトポロジーをマップする。
まず、ハードディスクの数と、そのタイプを調べる。さらに、Linux は個別のディスク
がどのようにパーティション分割されているかを発見する。これらはすべて、<tt>
<ref id="gendisk" name="gendisk"></tt> データ構造体のリストによって表現され、
それが <tt><ref id="gendisk" name="gendisk_head"></tt> リストポインタによって
ポイントされる。
個々のディスクサブシステム、たとえば IDE ディスクサブシステムは、初期化される
際、<tt>gendisk</tt> データ構造体を生成して、検出したディスクを記述する。それ
と同時に、ディスクサブシステムは、そのファイル操作ルーチンを登録し、そのエント
リを <tt><ref id="blk_dev_struct" name="blk_dev"></tt> データ構造に付け加える。
個々の <tt>gendisk</tt> データ構造体は、ユニークなデバイスメジャー番号を持ち、
その番号は、ブロックスペシャルデバイスのメジャー番号と一致する。
たとえば、SCSI ディスクサブシステムは、単一の <tt>gendisk</tt> エントリ("<tt>sd
</tt>")を作成し、それに SCSI ディスクデバイス全体のメジャー番号である、メジャー
番号 8 を付ける。図表(8.3)では、ふたつの <tt>gendisk</tt> エントリがあり、最初
はすべての SCSI サブシステムのものであり、ふたつめが IDE ディスクコントローラの
ものとなっている。後者は、プライマリ IDE コントローラである <tt>ide0</tt> であ
る。

<!--
Although the disk subsystems build the gendisk entries during their
initialization they are only used by Linux during partition checking. Instead,
each disk subsystem maintains its own data structures which allow it to map
device special major and minor device numbers to partitions within physical
disks. Whenever a block device is read from or written to, either via the 
buffer cache or file operations, the kernel directs the operation to the 
appropriate device using the major device number found in its block special 
device file (for example /dev/sda2). It is the individual device driver or 
subsystem that maps the minor device number to the real physical device. 
-->
<p>ディスクサブシステムは初期化の過程で <tt><ref id="gendisk" name="gendisk">
</tt> エントリを作成するが、それらは Linux によってパーティションチェックの際に
使用されるだけである。
それとは別に、個々のディスクサブシステムは、それぞれ独自のデータ構造体を管理
することで、デバイスのメジャー番号とマイナー番号を物理ディスク内のパーティショ
ンにマップしている。ブロックデバイスがバッファキャッシュやファイル操作ルーチン
経由で読み書きされるときはいつも、カーネルは、ブロックスペシャルデバイスファイ
ル(たとえば <tt>/dev/sda2</tt>)に書かれたメジャー番号を使って、その操作を
適切なデバイスへと導く。そして、デバイスのマイナー番号を実(real)物理デバイスに
マップしているのが、個別のデバイスドライバやデバイスサブシステムである。

<!--8.5.1  IDE Disks-->
<sect2>IDE ディスク<label id="chapter_dd_sect5-1">

<!--
The most common disks used in Linux systems today are Integrated Disk
Electronic or IDE disks. IDE is a disk interface rather than an I/O bus like
SCSI. Each IDE controller can support up to two disks, one the master disk
and the other the slave disk. The master and slave functions are usually set by
jumpers on the disk. The first IDE controller in the system is known as the
primary IDE controller, the next the secondary controller and so on. IDE can
manage about 3.3 Mbytes per second of data transfer to or from the disk and
the maximum IDE disk size is 538Mbytes. Extended IDE, or EIDE, has raised
the disk size to a maximum of 8.6 Gbytes and the data transfer rate up to 16.6
Mbytes per second. IDE and EIDE disks are cheaper than SCSI disks and
most modern PCs contain one or more on board IDE controllers. 
-->
<p>今日 Linux システム上で利用される最も一般的なディスクは、IDE (Integrated 
Disk Electronics)ディスクである。IDE とは、SCSI のような I/O というよりも、
むしろディスクインターフェイスである。
個々の IDE コントローラはふたつまでのディスクをサポートできる。一方がマスターデ
ィスク(master disk)であり、他方がスレイブディスク(slave disk)である。
マスターとスレイブの機能は通常、ディスクのジャンパピンで設定される。システム上
の最初の IDE コントローラはプライマリコントローラと呼ばれ、次のコントローラは
セカンダリコントローラ等と呼ばれる。IDE はディスクとの間で毎秒 3.3 M バイトの
データ転送能力を持っており、IDE の最大ディスクサイズは 528 M バイトである。
拡張 IDE 、もしくは EIDE(Extended IDE) は、最大ディスクサイズを 8.4 G バイトに
拡大し、データ転送能力も毎秒 16.6 M バイトに上げたものである。IDE と EIDE 
ディスクは SCSI ディスクよりも安価であるので、現在の PC にはひとつ以上の
オンボード IDE コントローラが含まれている。

<!--
Linux names IDE disks in the order in which it finds their controllers. The
master disk on the primary controller is /dev/hda and the slave disk is
/dev/hdb. /dev/hdc is the master disk on the secondary IDE controller.
The IDE subsystem registers IDE controllers and not disks with the Linux
kernel. The major identifier for the primary IDE controller is 3 and is 22 for
the secondary IDE controller. This means that if a system has two IDE
controllers there will be entries for the IDE subsystem at indices at 3 and 22
in the blk_dev and blkdevs vectors. The block special files for IDE disks
reflect this numbering, disks /dev/hda and /dev/hdb, both connected to
the primary IDE controller, have a major identifier of 3. Any file or buffer
cache operations for the IDE subsystem operations on these block special
files will be directed to the IDE subsystem as the kernel uses the major
identifier as an index. When the request is made, it is up to the IDE
subsystem to work out which IDE disk the request is for. To do this the IDE
subsystem uses the minor device number from the device special identifier,
this contains information that allows it to direct the request to the correct
partition of the correct disk. The device identifier for /dev/hdb, the slave
IDE drive on the primary IDE controller is (3,64). The device identifier for 
the first partition of that disk (/dev/hdb1) is (3,65). 
-->
<p>Linux はコントローラを見つけた順番に IDE ディスクに名前を付ける。プライマリ
コントローラのマスターディスクは <tt>/dev/hda</tt> であり、スレイブディスクは
 <tt>/dev/hdb</tt> である。<tt>/dev/hdc</tt> はセカンダリ IDE コントローラの
マスターディスクとなる。IDE サブシステムは Linux カーネルに IDE コントローラ
を登録し、ディスクを登録しない。プライマリ IDE コントローラのメジャー番号は、
3 であり、セカンダリ IDE コントローラのメジャー番号は 22 である。これは、システ
ムにふたつの IDE コントローラがある場合、<tt><ref id="blk_dev_struct" 
name="blk_devs"></tt> と <tt><ref id="device_struct" name="blkdevs"></tt> 
配列には 3 と 22 のインデックスがついた IDE サブシステムのエントリが
存在することを意味する。IDE ディスクのブロックスペシャルファイルはこの番号の
割り当てを反映しているので、プライマリ IDE コントローラに接続されたディスクで
ある <tt>/dev/hda</tt> と <tt>/dev/hdb</tt> は、どちらもメジャー番号 3 を持つ。
カーネルはメジャー番号をインデックスとして使用しているため、それらのブロック
スペシャルファイル上の IDE サブシステム操作ルーチンを使ったファイル操作や
バッファキャッシュ操作は、まず、IDE サブシステムへと導かれる。
そうしたリクエストが為されたとき、リクエストがどの IDE ディスクに対するもの
なのかを判別するのは、IDE サブシステムの役目である。
そのために、IDE サブシステムは、デバイスの特別な識別子としてマイナー
番号を使用する。その識別子には、リクエストを正しいディスクの正しい
パーティションに送るための情報が含まれている。プライマリ IDE コントローラ上
のスレイブ IDE ディスクである <tt>/dev/hdb</tt> のデバイス識別子は、<ref 
id="major_number" name="(3,64)">(メジャー番号 3 、マイナー番号 64)である。
そのディスクの最初のパーティション(<tt>/dev/hdb1</tt>)のデバイス識別子は、
(3,65) である。

<!--8.5.2  Initializing the IDE Subsystem-->
<sect2>IDE サブシステムの初期化<label id="chapter_dd_sect5-2">

<!--
IDE disks have been around for much of the IBM PC's history. Throughout
this time the interface to these devices has changed. This makes the
initialization of the IDE subsystem more complex than it might at first 
appear. 
-->
<p>IDE ディスクは、IBM PC の歴史と深く関わっている。それらの時代を通じて
IDE デバイスに対するインターフェイスは何度も変更された。それによって、
IDE サブシステムの初期化は、それが登場した当初よりも複雑なものになっている。

<!--
The maximum number of IDE controllers that Linux can support is 4. Each
controller is represented by an ide_hwif_t data structure in the
ide_hwifs vector. Each ide_hwif_t data structure contains two
ide_drive_t data structures, one per possible supported master and slave
IDE drive. During the initializing of the IDE subsystem, Linux first looks to
see if there is information about the disks present in the system's CMOS
memory. This is battery backed memory that does not lose its contents when
the PC is powered off. This CMOS memory is actually in the system's real
time clock device which always runs no matter if your PC is on or off. The
CMOS memory locations are set up by the system's BIOS and tell Linux what
IDE controllers and drives have been found. Linux retrieves the found disk's
geometry from BIOS and uses the information to set up the ide_hwif_t data
structure for this drive. More modern PCs use PCI chipsets such as Intel's
82430 VX chipset which includes a PCI EIDE controller. The IDE subsystem
uses PCI BIOS callbacks to locate the PCI (E)IDE controllers in the system.
It then calls PCI specific interrogation routines for those chipsets that are
present. 
-->
<p>Linux がサポートできる IDE コントローラの最大数は 4 つである。個々の
コントローラは、<tt><ref id="ide_hwif_t" name="ide_hwifs"></tt> 配列にある 
<tt><ref id="ide_hwif_t" name="ide_hwif_t"></tt> データ構造体によって表される。
個々の <tt>ide_hwif_t</tt> データ構造体はふたつの <tt><ref id="ide_drive_t" 
name="ide_drive_t"></tt> 構造体を含んでおり、各々がマスターとスレイブの IDE 
ドライブのサポートに備えたものとなっている。IDE サブシステムの初期化の過程で、
Linux はまず、システムの CMOS メモリにディスクに関する情報があるかどうかを
確認する。これは、PC の電源が切られたときもバッテリ駆動のバックアップメモリに
よってその内容が失われないようになっている。この CMOS メモリは実際にはシステム
のリアルタイムクロックの中にあり、そのクロックは PC の電源が入っているかどうか
に関わらず、実行されている。その CMOS メモリの場所は BIOS を使って設定が可能
であり、それが Linux に対してどのような IDE コントローラやドライブが検出され
たかを告げる。Linux は検出されたディスクのジオメトリを BIOS から取ってきて、
その情報を利用して当該デバイスの <tt>ide_hwif_t</tt> データ構造体を設定する。
より現代的な PC では、PCI (E)IDE コントローラに含まれる Intel の 82430 VX 
のような PCI チップセットを使用する。そして、システム上にあるそうしたチップ
セット用の PCI 固有の検出ルーチンをコールする。

<!--
Once each IDE interface or controller has been discovered, its ide_hwif_t
is set up to reflect the controllers and attached disks. During operation the
IDE driver writes commands to IDE command registers that exist in the I/O
memory space. The default I/O address for the primary IDE controller's
control and status registers is 0x1F0 - 0x1F7. These addresses were set by
convention in the early days of the IBM PC. The IDE driver registers each
controller with the Linux block buffer cache and VFS, adding it to the
blk_dev and blkdevs vectors respectively. The IDE drive will also request
control of the appropriate interrupt. Again these interrupts are set by
convention to be 14 for the primary IDE controller and 15 for the secondary
IDE controller. However, they like all IDE details, can be overridden by
command line options to the kernel. The IDE driver also adds a gendisk
entry into the list of gendisk's discovered during boot for each IDE
controller found. This list will later be used to discover the partition 
tables of all of the hard disks found at boot time. The partition checking code
understands that IDE controllers may each control two IDE disks. 
-->
<p>個々の IDE インターフェイスやコントローラが発見されたら、その <tt><ref 
id="ide_hwif_t" name="ide_hvif_t"></tt> 構造体が、そのコントローラやそれに接続
されたディスクの状態を反映するために設定される。
設定の過程で、IDE ドライバは、I/O メモリ空間に存在する IDE コマンドレジスタに
コマンドを書き込む。プライマリ IDE コントローラ上のコントロールレジスタと
ステータスレジスタのデフォルトの I/O アドレスは、0x1F0 から 0x1F7 である。
これらのアドレスの設定は、初期の IBM PC の慣習によって決まっている。
IDE ドライバは、個々のコントローラを Linux のブロック
バッファキャッシュと VFS に登録し、それを <tt><ref id="blk_dev_struct" 
name="blk_dev"></tt> と <tt><ref id="device_struct" name="blkdevs"></tt> 
配列にそれぞれ付け加える。IDE ドライブは適切な割り込み制御も要求する。
ここでもまた、その割り込み番号は慣習的に決まっており、プライマリ IDE コント
ローラが 14 で、セカンダリコントローラが 15 である。しかし、それらは、他の
すべての IDE の詳細と同様に、カーネルへのコマンドラインオプションによって
上書き変更が可能である。また IDE ドライバは、起動中に発見された個々の IDE 
コントローラについて、<tt><ref id="gendisk" name="gendisk"></tt> のリストに 
<tt>gendisk</tt> のエントリを付け加える。このリストは後で、起動時に見つかったす
べてのハードディスクのパーティションテーブルを発見するために使用される。

<!--8.5.3  SCSI Disks-->
<sect2>SCSI ディスク<label id="chapter_dd_sect5-3">

<!--
The SCSI (Small Computer System Interface) bus is an efficient peer-to-peer
data bus that supports up to eight devices per bus, including one or more
hosts. Each device has to have a unique identifier and this is usually set by
jumpers on the disks. Data can be transfered synchronously or
asynchronously between any two devices on the bus and with 32 bit wide data
transfers up to 40 Mbytes per second are possible. The SCSI bus transfers
both data and state information between devices, and a single transaction
between an initiator and a target can involve up to eight distinct phases. You
can tell the current phase of a SCSI bus from five signals from the bus. The
eight phases are: 
-->
<p>SCSI (Small Computer System Interface)バスは、効率的な一対一(peer-to-peer)
のデータバスであり、ひとつ以上のホストを含む 8 個のデバイスをひとつのバスで
サポートする。個々のデバイスは固有の識別子を持つ必要があり、通常それはディスク
上のジャンパピンで設定される。バス上にある任意のふたつのデバイス間で
同期あるいは非同期のデータ転送が可能であり、32 ビット幅のデータ転送により最大
毎秒 40 M バイトの転送速度が得られる。SCSI バスは、デバイス間でデータとステート
(状態)の情報の両方を転送する。イニシエータ(initiater)とターゲット(target)間の
一回の転送中に最大 8 つの異なるフェイズ(phase)を取ることがある。現在の SCSI 
バスのフェイズは 5 本の制御線から、確認できる。8 つのフェイズとは次のような
ものである。

<!--
BUS FREE
      No device has control of the bus and there are no transactions
      currently happening, 
-->
<descrip>
<tag>BUS FREE</tag>
バスを制御しているデバイスは存在せず、トランザクションは現在行われていない。

<!--
ARBITRATION
      A SCSI device has attempted to get control of the SCSI bus, it does
      this by asserting its SCSI identifer onto the address pins. The highest
      number SCSI identifier wins. 
-->
<tag>ARBITRATION</tag>
SCSI デバイスが SCSI バスを制御しようとしていて、SCSI 識別子に対応した
ピンを有効にしている。SCSI 識別子の最高値が優先される。

<!--
SELECTION
      When a device has succeeded in getting control of the SCSI bus
      through arbitration it must now signal the target of this SCSI request
      that it wants to send a command to it. It does this by asserting the
      SCSI identifier of the target on the address pins. 
-->
<tag>SELECTION</tag>
ARBITRATION を通じてデバイスが SCSI バスの制御に成功したとき、そのデバイスは 
SCSI のターゲットに対して、コマンドを送る旨のリクエストを SCSI バスの制御線で
伝えなければならない。それをするために、ターゲットの SCSI 識別子に対応した
ピンを有効にする。

<!--
RESELECTION
      SCSI devices may disconnect during the processing of a request. The
      target may then reselect the initiator. Not all SCSI devices support
      this phase. 
-->
<tag>RESELECTION</tag>
SCSI デバイスは、リクエスト処理中に接続を中止するかもしれない。その場合、
ターゲットは、イニシエータに再接続できる。すべての SCSI デバイスがこのフェーズ
をサポートしているわけではない。

<!--
COMMAND
      6,10 or 12 bytes of command can be transfered from the initiator to the
      target, 
-->
<tag>COMMAND</tag>
6,10, もしくは 12 バイトの命令を、イニシエータからターゲットに送ることが
できる。

<!--
DATA IN, DATA OUT
      During these phases data is transfered between the initiator and the
      target, 
-->
<tag>DATA IN, DATA OUT</tag>
これらのフェーズにおいて、データはイニシエータとターゲット間で転送される。

<!--
STATUS
      This phase is entered after completion of all commands and allows the
      target to send a status byte indicating success or failure to the
      initiator, 
-->
<tag>STATUS</tag>
このフェーズに入るのは、コマンドがすべて実行され、ターゲットがイニシエータに
対して成功か失敗を示すステータスバイトを送ることができる場合である。

<!--
MESSAGE IN, MESSAGE OUT
      Additional information is transfered between the initiator and the
      target. 
-->
<tag>MESSAGE IN, MESSAGE OUT</tag>
イニシエータとターゲット間での追加情報の転送。

</descrip>

<!--
The Linux SCSI subsystem is made up of two basic elements, each of which
is represented by data structures: 
-->
<p>Linux SCSI サブシステムは、ふたつの基本要素から成り、それぞれがデータ構造体
によって表される。

<!--
host A SCSI host is a physical piece of hardware, a SCSI controller. The
      NCR810 PCI SCSI controller is an example of a SCSI host. If a Linux
      system has more than one SCSI controller of the same type, each
      instance will be represented by a separate SCSI host. This means that
      a SCSI device driver may control more than one instance of its
      controller. SCSI hosts are almost always the initiator of SCSI
      commands. 
-->
<descrip>
<tag>host</tag>
SCSI ホスト(host)とは物理的なハードウェアである SCSI コントローラを指す。
NCR810 PCI SCSI コントローラは SCSI ホストの典型である。Linux システムが
同種の SCSI コントローラを複数持つ場合、個々のコントローラは、個別の SCSI 
ホストとして表現される。これは、SCSI デバイスドライバは同種のコントローラを
複数制御できることを意味する。SCSI ホストは、ほとんどいつも SCSI コマンドの
イニシエータである。

<!--
Device The most common set of SCSI device is a SCSI disk but the SCSI
      standard supports several more types; tape, CD-ROM and also a
      generic SCSI device. SCSI devices are almost always the targets of
      SCSI commands. These devices must be treated differently, for
      example with removable media such as CD-ROMs or tapes, Linux
      needs to detect if the media was removed. The different disk types
      have different major device numbers, allowing Linux to direct block
      device requests to the appropriate SCSI type. 
-->
<tag>Device</tag>
SCSI デバイスの中で最も一般的なのが SCSI ディスクであるが、SCSI 規格はもっと
多種類のデバイスをサポートしている。テープ、CD-ROM それに汎用 SCSI デバイス
などである。SCSI デバイスはほとんどいつも SCSI コマンドのターゲットである。
それらのデバイスは異なった取り扱いが必要であり、たとえば CD-ROM やテープなどの
リムーバルメディアの場合、Linux はそのメディアが取り出されたかどうか確認できな
ければならない。
異なるディスクタイプには異なるメジャー番号が与えられ、それによって Linux は
ブロックデバイスへのリクエストを適切な SCSI タイプに伝達することができる。
</descrip>

<!--Initializing the SCSI Subsystem-->
<sect2>SCSI サブシステムの初期化<label id="chapter_dd_sect5-4">

<!--
Initializing the SCSI subsystem is quite complex, reflecting the dynamic
nature of SCSI buses and their devices. Linux initializes the SCSI subsystem
at boot time; it finds the SCSI controllers (known as SCSI hosts) in the
system and then probes each of their SCSI buses finding all of their devices. 
It then initializes those devices and makes them available to the rest of the
Linux kernel via the normal file and buffer cache block device operations. This
initialization is done in four phases: 
-->
<p>SCSI サブシステムの初期化は、SCSI バスやデバイスの動的な性質を反映して、
非常に複雑なものになっている。Linux は SCSI サブシステムをブート時に初期化
する。システム上の SCSI コントローラ(SCSI ホストと呼ばれる)を検出し、
コントローラごとの SCSI バスを検査して、バス上のデバイスをすべて検出する。
その上で、それらのデバイスを初期化して、Linux カーネルの残りの部分が、
通常ファイルの操作ルーチンやバッファキャッシュブロックデバイスの操作ルーチンを
経由して、デバイスを利用することが出来るようにする。
この初期化には 4 つのフェイズがある。

<!--
First, Linux finds out which of the SCSI host adapters, or controllers, that
were built into the kernel at kernel build time have hardware to control. Each
built in SCSI host has a Scsi_Host_Template entry in the
builtin_scsi_hosts vector. The Scsi_Host_Template data structure
contains pointers to routines that carry out SCSI host specific actions such as
detecting what SCSI devices are attached to this SCSI host. These routines
are called by the SCSI subsystem as it configures itself and they are part of
the SCSI device driver supporting this host type. Each detected SCSI host,
those for which there are real SCSI devices attached, has its
Scsi_Host_Template data structure added to the scsi_hosts list of
active SCSI hosts. Each instance of a detected host type is represented by a
Scsi_Host data structure held in the scsi_hostlist list. For example a
system with two NCR810 PCI SCSI controllers would have two Scsi_Host
entries in the list, one per controller. Each Scsi_Host points at the
Scsi_Host_Template representing its device driver. 
-->
<p>まず Linux は、カーネル構築時にカーネルに組み込まれた SCSI ホストアダプタ
もしくはコントローラのうち、制御すべきハードウェアを持つのはどれなのかを見
つけだす。
カーネルに組み込まれた個々のホストは、<tt><ref id="Scsi_Host_Template" 
name="builtin_scsi_host"></tt> 配列内に <tt><ref id="Scsi_Host_Template" 
name="Scsi_Host_Template"></tt> エントリを持つ。
<tt>Scsi_Host_Template</tt> データ構造体にはルーチンへのポインタが含まれてい
て、それによって SCSI ホストに接続された SCSI デバイスの検出といったその SCSI 
ホスト固有の処理が実行される。
それらのルーチンは、SCSI サブシステムによっても呼び出されて、その設定を行ったり
もする。それらは、そのホストタイプをサポートする SCSI デバイスドライバの一部で
ある。
検出された個々の SCSI ホストのうち、実際に SCSI デバイスが接続されていたもの
は、自分の <tt>Scsi_Host_Template</tt> データ構造体を、アクティブな SCSI ホスト
のリストである <tt><ref id="Scsi_Host_Template" name="scsi_hosts"></tt> リスト
に付け加える。
検出されたホストタイプの個々の SCSI コントローラは、<tt><ref id="Scsi_Host" 
name="scsi_hostlist"></tt> リスト内にある <tt><ref id="Scsi_Host" 
name="Scsi_Host"></tt> データ構造体によって表現される。たとえば、NCR810 PCI 
SCSI コントローラを持つシステムは、リスト内に、コントローラごとにひとつ、合計
ふたつの <tt>Scsi_Host</tt> エントリを持つ。個々の <tt>Scsi_Host</tt> 構造体
は、そのデバイスドライバを表している <tt>Scsi_Host_Template</tt> をポイントして
いる。


<!--Figure 8.4: SCSI Data Structures-->
<#if output="html">
<figure><ph vspace="1"><img src="./The-Linux-Kernel-images/figure8-4.gif">
</figure>
</#if>
<#unless output="html">
<verb>

                                  Scsi_Host_Template
scsi_hosts                         +--------------+
---------------------------------->| next         |
                                   |--------------|
                        +--------->| name         |
                        |          |--------------|
                        |          |              |
                        |          | Device       |
                        |          | Driver       |
                        |          | Routines     |
                        |          |              |
                        |          +--------------+
                        +--------------------------------+
                                                         |
scsi_hostlist                         Scsi_Host          |
----------------------------------->+-------------+      |
                        +---------->| next        |      |
                        |           |-------------|      |
                        |           |             |      |
                        |           |-------------|      |
                        |           | this_id     |      |
                        |           |-------------|      |
                        |           | max_id      |      |
                        |           |-------------|      |
                        |           |             |      |
                        |           |-------------|      |
                        |           | host        |<-----+
                        |           |-------------|
                        |           |             |
                        |           +-------------+
                        +--------------------------------+
                                                         |
                 Scsi_Device            Scsi_Device      |
scsi_device    +-------------+        +-------------+    |
-------------->| next        |------->| next        |    |
               |-------------|        |-------------|    |
               |             |        |             |    |
               |-------------|        |-------------|    |
               | id          |        | id          |    |
               |-------------|        |-------------|    |
               | type        |        | type        |    |
               |-------------|        |-------------|    |
               |             |        |             |    |
               |-------------|        |-------------|    |
               | host        |        | host        |<---+
               |-------------|        |-------------|
               |             |        |             |
               |             |        |             |
               +-------------+        +-------------+
</verb>
</#if>
<p>図表(8.4) SCSI データ構造


<!-- 
Now that every SCSI host has been discovered, the SCSI subsystem must
find out what SCSI devices are attached to each host's bus. SCSI devices are
numbered between 0 and 7 inclusively, each device's number or SCSI
identifier being unique on the SCSI bus to which it is attached. SCSI
identifiers are usually set by jumpers on the device. The SCSI initialization
code finds each SCSI device on a SCSI bus by sending it a
TEST_UNIT_READY command. When a device responds, its identification is
read by sending it an ENQUIRY command. This gives Linux the vendor's
name and the device's model and revision names. SCSI commands are
represented by a Scsi_Cmnd data structure and these are passed to the
device driver for this SCSI host by calling the device driver routines within 
its Scsi_Host_Template data structure. Every SCSI device that is found is
represented by a Scsi_Device data structure, each of which points to its
parent Scsi_Host. All of the Scsi_Device data structures are added to the
scsi_devices list. Figure  8.4 shows how the main data structures relate to
one another. 
-->
<p>SCSI ホストがすべて見つかったら、次に SCSI サブシステムは、個々の SCSI ホス
トにどういった SCSI デバイスが繋がれているのか見つけ出さなければならない。SCSI 
デバイスには 0 から 7 までの番号が振られ、個々のデバイス番号もしくは SCSI 
識別子はそれが繋がれた SCSI バス上においてユニークでなければならない。
通常、SCSI 識別子はデバイス上のジャンパピンで設定される。SCSI 初期化コードは、
SCSI バス上の個々の SCSI デバイスを検出するとき、それらに TEST_UNIT_READY コマ
ンドを送信する。デバイスが応答すると、ENQUIRY コマンドが送信されて、そのデバイ
スの識別子が読み出される。これによって Linux は、そのベンダ名、デバイスモデル、
リビジョン名を取得する。
SCSI コマンドは <tt><ref id="Scsi_Cmnd" name="Scsi_Cmnd"></tt> 
データ構造体によって表現され、それらがこの SCSI ホストに対するデバイスドライバ
に渡されるときは、その <tt><ref id="Scsi_Host_Template" 
name="Scsi_Host_Template"></tt> データ構造体内にあるデバイスドライバルーチンが
呼び出される。発見されたすべての SCSI デバイスは <tt><ref 
id="Scsi_Device" name="Scsi_Device"></tt> データ構造体によって表現され、その
個々の構造体がその親である <tt><ref id="Scsi_Host" name="Scsi_Host"></tt> を
ポイントしている。すべての <tt>Scsi_Device</tt> データ構造体は <tt><ref 
id="Scsi_Device" name="scsi_devices"></tt> リストに付け加えられる。図表(8.4)
では、主要なデータ構造体がどのような相互関係にあるのかが示されている。

<!--
There are four SCSI device types: disk, tape, CD and generic. Each of these
SCSI types are individually registered with the kernel as different major block
device types. However they will only register themselves if one or more of a
given SCSI device type has been found. Each SCSI type, for example SCSI
disk, maintains its own tables of devices. It uses these tables to direct 
kernel block operations (file or buffer cache) to the correct device driver or
SCSI host. Each SCSI type is represented by a Scsi_Device_Template data
structure. This contains information about this type of SCSI device and the
addresses of routines to perform various tasks. The SCSI subsystem uses
these templates to call the SCSI type routines for each type of SCSI device. In
other words, if the SCSI subsystem wishes to attach a SCSI disk device it will
call the SCSI disk type attach routine. The Scsi_Type_Template data
structures are added to the scsi_devicelist list if one or more SCSI
devices of that type have been detected. 
-->
<p>SCSI デバイスには、ディスク、テープ、CD 、汎用の 4 種類のタイプがある。
それらの SCSI タイプの各々が異なるメジャーブロックデバイスタイプとしてカーネル
に独立して登録される。しかし、それらは、その種の SCSI デバイスタイプがひとつ以
上見つかった場合のみ登録がなされる。SCSI ディスクのような個々の SCSI タイプは
独自のデバイステーブルを管理している。そしてそれらのテーブルを利用してカーネル
の(ファイルやバッファキャッシュに対する)ブロック操作ルーチンを正しいデバイス
ドライバや SCSI ホストに導く。
個々の SCSI タイプは <tt><ref id="Scsi_Device_Template" 
name="Scsi_Device_Template"></tt> データ構造体によって表現される。これには、
その SCSI デバイスのタイプと様々なタスクを実行するルーチンのアドレスに関する
情報が含まれる。SCSI サブシステムはそれらのテンプレートを使用して個々の SCSI 
タイプのデバイスに対する SCSI タイプルーチンを呼び出す。言い換えると、もし 
SCSI サブシステムが SCSI ディスクデバイスを追加したい場合、その SCSI ディスク
タイプの追加用ルーチンが呼び出される。ひとつ以上のそのタイプの SCSI デバ
イスが見つかった場合、<tt>Scsi_Type_Template</tt> データ構造体(訳注: <tt><ref 
id="Scsi_Device_Template" name="Scsi_Device_Template"></tt>か？)が <tt>
<ref id="Scsi_Device_Template" name="scsi_devicelist"></tt> リストに付け加え
られる。

<!--
The final phase of the SCSI subsystem initialization is to call the finish
functions for each registered Scsi_Device_Template. For the SCSI disk
type this spins up all of the SCSI disks that were found and then records their
disk geometry. It also adds the gendisk data structure representing all SCSI
disks to the linked list of disks shown in Figure  8.3. 
-->
<p>SCSI サブシステムの初期化における最後のフェーズは、登録された <tt>
<ref id="Scsi_Device_Template" name="Scsi_Device_Template"></tt> の個々に対する
終了用関数を呼び出すことである。SCSI ディスクタイプごとに、その関数が、検出され
た SCSI ディスクすべてをまとめて、それらのディスクジオメトリを記録する。また、
それは、すべての SCSI ディスクを表現している <tt><ref id="gendisk" 
name="gendisk"></tt> データ構造体を<ref id="figure8-3" name="図表(8.3)">で示し
たディスクの連結リストに付け加える。

<!--Delivering Block Device Requests-->
<sect2>ブロックデバイスのリクエストを伝達する<label id="chapter_dd_sect5-5">

<!--
Once Linux has initialized the SCSI subsystem, the SCSI devices may be
used. Each active SCSI device type registers itself with the kernel so that
Linux can direct block device requests to it. There can be buffer cache
requests via blk_dev or file operations via blkdevs. Taking a SCSI disk
driver that has one or more EXT2 filesystem partitions as an example, how do
kernel buffer requests get directed to the right SCSI disk when one of its
EXT2 partitions is mounted? 
-->
<p>Linux が SCSI サブシステムの初期化を完了すると、SCSI デバイスが利用可能に
なる。個々のアクティブな SCSI デバイスのタイプは、Linux がブロックデバイス
リクエストをそれに導けるように、カーネルに登録される。そうしたリクエストには
 <tt><ref id="blk_dev_struct" name="blk_dev"></tt> を経由したバッファキャッシュ
リクエストや <tt><ref id="device_struct" name="blkdevs"></tt> を経由したファイ
ル操作リクエストなどがある。
では、ひとつ以上の数の EXT2 ファイルシステムのパーティションを持つ SCSI ディス
クを例に取ると、その EXT2 パーティションがマウントされているとき、カーネルの
バッファリクエストはどのようにして適切な SCSI ディスクに渡されるのだろうか？

<!--
Each request to read or write a block of data to or from a SCSI disk partition
results in a new request structure being added to the SCSI disks
current_request list in the blk_dev vector. If the request list is being
processed, the buffer cache need not do anything else; otherwise it must
nudge the SCSI disk subsystem to go and process its request queue. Each
SCSI disk in the system is represented by a Scsi_Disk data structure.
These are kept in the rscsi_disks vector that is indexed using part of the
SCSI disk partition's minor device number. For exmaple, /dev/sdb1 has a
major number of 8 and a minor number of 17; this generates an index of 1.
Each Scsi_Disk data structure contains a pointer to the Scsi_Device
data structure representing this device. That in turn points at the Scsi_Host
data structure which ``owns'' it. The request data structures from the buffer
cache are translated into Scsi_Cmd structures describing the SCSI command
that needs to be sent to the SCSI device and this is queued onto the
Scsi_Host structure representing this device. These will be processed by
the individual SCSI device driver once the appropriate data blocks have been
read or written. 
-->
<p>SCSI ディスクパーティションに対するデータブロックの読み書きリクエストが
為されると、<tt><ref id="request" name="request"></tt> 構造体が <tt><ref 
id="blk_dev_struct" name="blk_dev"></tt> 配列内にあるその SCSI ディスクの <tt>
<ref id="request" name="current_request"></tt> リストに付け加えられる。
<tt>request</tt> リストが処理されている場合、バッファキャッシュは何もする必要
がないのだが、そうでない場合は、 SCSI サブシステムを促してそのリクエストキュー
を処理させなければならない。システム上の個々の SCSI ディスクは <tt><ref 
id="Scsi_Disk" name="Scsi_Disk"></tt> データ構造体によって表現されている。
その構造体は <tt><ref id="Scsi_Disk" name="rscsi_disks"></tt> 配列に
保存されていて、その配列は SCSI ディスクパーティションのマイナー番号の
一部を使用してインデックス付けされている。たとえば、<tt>/dev/sdb1</tt> は
メジャー番号 8 とマイナー番号 17 を持っているが、これはインデックス 1 を
生成する。個々の <tt>Scsi_Disk</tt> データ構造体には、このデバイスを表現
する <tt><ref id="Scsi_Device" name="Scsi_Device"></tt> データ構造体へのポイン
タが含まれている。その構造体が次に <tt><ref id="Scsi_Host" name="Scsi_Host">
</tt> 構造体をポイントしており、それがそのデバイスの「オーナー」である。
バッファキャッシュからの <tt>request</tt> データ構造体は、SCSI 
デバイスに送信されるべき SCSI コマンドを記述している <tt><ref id="Scsi_Cmnd" 
name="Scsi_Cmnd"></tt> 構造体に変換され、これがそのデバイスを表す <tt>
Scsi_Host</tt> データ構造体上のキューに置かれる。いったん適切なデータブロックが
書き込まれたり読み出されたりすると、そうしたことが個別の SCSI デバイスドライバ
によって処理される。

<!--8.6  Network Devices-->
<sect1>ネットワークデバイス<label id="chapter_dd_sect6">

<!--
A network device is, so far as Linux's network subsystem is concerned, an
entity that sends and receives packets of data. This is normally a physical
device such as an ethernet card. Some network devices though are software
only such as the loopback device which is used for sending data to yourself.
Each network device is represented by a device data structure. Network
device drivers register the devices that they control with Linux during network
initialization at kernel boot time. The device data structure contains
information about the device and the addresses of functions that allow the
various supported network protocols to use the device's services. These
functions are mostly concerned with transmitting data using the network
device. The device uses standard networking support mechanisms to pass
received data up to the appropriate protocol layer. All network data (packets)
transmitted and received are represented by sk_buff data structures, these
are flexible data structures that allow network protocol headers to be easily
added and removed. How the network protocol layers use the network
devices, how they pass data back and forth using sk_buff data structures is
described in detail in the Networks chapter (Chapter  networks-chapter).
This chapter concentrates on the device data structure and on how network
devices are discovered and initialized. 
-->
<p>Linux のネットワークサブシステムに関する限り、ネットワークデバイスとは、
データパケットを送受信する実体のことである。通常これはイーサネットカードなどの
物理デバイスである。しかし、データを自分に送信するために使用されるループバック
デバイス(loopback device)といったソフトウェアのネットワークデバイスもある。
個々のネットワークデバイスは <tt><ref id="device" name="device"></tt> データ
構造体によって表現される。
<newline>[see: <htmlurl 
url="./The-Linux-Kernel-images/linux/include/linux/netdevice.h" 
name="include/linux/netdevice.h">]<newline>
ネットワークデバイスコントローラは、カーネル起動時のネットワーク初期化過程で、
Linux に制御しようとするデバイスを登録する。<tt>device</tt> データ構造体には、
デバイスに関する情報と、サポートされる多様なプロトコルがデバイスのサービスを
利用する際に使う関数のアドレスとが含まれる。
これらの関数は大部分がネットワークデバイスを使用したデータ転送に関するものであ
る。デバイスは、受信したデータを適切なプロトコル層に渡すために標準的なネット
ワークサポート機能を使用する。送受信されたすべてのデータ(パケット)は、<tt><ref 
id="sk_buff" name="sk_buff"></tt> データ構造体によって表現されるが、それは柔軟
な構造体なので、ネットワークプロトコルのヘッダの簡単な追加や削除を可能にする。
ネットワークプロトコル層がネットワークデバイスを使用する方法、それらが <tt>
sk_buff</tt> データ構造体を使用してデータを受け渡しする方法については、
<ref id="chapter_net" name="「ネットワーク」">の章で詳しく解説する。本章では、
<tt>device</tt> データ構造体とネットワークデバイスが検出され初期化される方法と
に集中する。

<!--
The device data structure contains information about the network device: 
-->
<p><tt><ref id="device" name="device"></tt> データ構造体にはネットワークデバイ
スに関する次のような情報が含まれている。

<!--
Name Unlike block and character devices which have their device special
      files created using the mknod command, network device special files
      appear spontaniously as the system's network devices are discovered
      and initialized. Their names are standard, each name representing the
      type of device that it is. Multiple devices of the same type are
      numbered upwards from 0. Thus the ethernet devices are known as
      /dev/eth0,/dev/eth1,/dev/eth2 and so on. Some common
      network devices are: 

       /dev/ethN 
               Ethernet devices 
       /dev/slN 
               SLIP devices 
       /dev/pppN 
               PPP devices 
       /dev/lo 
               Loopback devices
-->
<descrip>
<tag>名前 (name)</tag>
<tt>mknod</tt> コマンドを使ってデバイススペシャルファイルを作成するブロック
デバイスやキャラクタデバイスとは異なり、ネットワークデバイスのスペシャル
ファイルは、システムのネットワークデバイスが検出され初期化される際に自動的に
出現する。その名前は標準的なもので、個々の名前はそのデバイスのタイプを表して
いる。同タイプのデバイスが複数ある場合は、0 から順に番号付けされる。したがっ
て、複数のイーサネットデバイスは、<tt>/dev/eht0</tt>, <tt>/dev/eth1</tt>, 
<tt>/dev/eth2</tt> 等となる。一般的なネットワークデバイスをいくつか示す。
<verb>
/dev/ethN  イーサネットデバイス

/dev/slN   SLIP デバイス

/dev/pppN  PPP デバイス

/dev/lo    ループバックデバイス
</verb>

<!--
Bus Information
      This is information that the device driver needs in order to control the
      device. The irq number is the interrupt that this device is using. The
      base address is the address of any of the device's control and status
      registers in I/O memory. The DMA channel is the DMA channel
      number that this network device is using. All of this information is set
      at boot time as the device is initialized. 
-->
<tag>バス情報 (bus information)</tag>
これは、デバイスドライバがデバイスを制御するために必要な情報である。<tt><ref 
id="device" name="irq"></tt> 番号はそのデバイスが使用する割り込み番号である。
<tt><ref id="device" name="base_addr"></tt> は I/O メモリ内にあるコントロールレ
ジスタとステータスレジスタのアドレスである。
<tt><ref id="device" name="dma"></tt> はそのネットワークデバイスが使用する DMA 
チャンネルの番号である。これらすべての情報はブート時のデバイスが初期化される際
に設定される。

<!--
Interface Flags
      These describe the characteristics and abilities of the network device:
-->
<tag>インターフェイスフラグ(interface flag)</tag>
これらは、ネットワークデバイスの特徴と能力とを示している。
<!--
       IFF_UP 
                        Interface is up and running, 
       IFF_BROADCAST 
                        Broadcast address in device is valid 
       IFF_DEBUG 
                        Device debugging turned on 
       IFF_LOOPBACK 
                        This is a loopback device 
       IFF_POINTTOPOINT 
                        This is point to point link (SLIP and PPP) 
       IFF_NOTRAILERS 
                        No network trailers 
       IFF_RUNNING 
                        Resources allocated 
       IFF_NOARP 
                        Does not support ARP protocol 
       IFF_PROMISC 
                        Device in promiscuous receive mode, it will
                        receive 
                        all packets no matter who they are
                        addressed to 
       IFF_ALLMULTI 
                        Receive all IP multicast frames 
       IFF_MULTICAST 
                        Can receive IP multicast frames
-->
<verb>
IFF_UP           インターフェイスが起動され実行中である。

IFF_BROADCAST    デバイスのブロードキャストアドレスが有効である。

IFF_DEBUG        デバイスのデバッギングが有効である。

IFF_LOOPBACK     これは、ループバックデバイスである。

IFF_POINTTOPOINT これは、一対一(point to point)のリンクである。(SLIP と PPP)

IFF_NOTRAILER    ネットワークトレイラー(network trailer)なし。(訳注: 用語集)

IFF_RUNNING      リソースが割り当てられた。

IFF_NOARP        ARP プロトコルをサポートしない。

IFF_PROMISC      プロミスク受信モードのデバイスは、パケットの送信先アドレス
                 とは無関係にすべてのパケットを受信する。

IFF_ALLMULTI     IP マルチキャストフレームを受信する。

IFF_MULTICAST    IP マルチキャストフレームの受信が可能。
</verb>

<!--
Protocol Information
      Each device describes how it may be used by the network protocool
      layers: 
      mtu The size of the largest packet that this network can transmit
            not including any link layer headers that it needs to add. This
            maximum is used by the protocol layers, for example IP, to
            select suitable packet sizes to send. 
      Family The family indicates the protocol family that the device can
            support. The family for all Linux network devices is AF_INET,
            the Internet address family. 
      Type The hardware interface type describes the media that this
            network device is attached to. There are many different types
            of media that Linux network devices support. These include
            Ethernet, X.25, Token Ring, Slip, PPP and Apple Localtalk. 
      Addresses
            The device data structure holds a number of addresses that
            are relevent to this network device, including its IP addresses.
-->
<tag>プロトコル情報</tag>
個々のデバイスは、ネットワークプロトコル層によってどのように利用されるのかを
示している。
<descrip>

<tag>最大転送単位 (mtu)</tag>
そのネットワークで送信可能な最大パケットのサイズ。ただし、それに付加される
リンク層のヘッダ部分は含まれない。この最大値は、IP などのプロトコル層が送信
パケットの適正サイズを選択する際に利用される。

<tag>ファミリー (family)</tag>
ファミリーとは、そのデバイスがサポートできるプロトコルファミリーを指す。すべて
の Linux ネットワークデバイスでサポートされるファミリーは、AF_INET、すなわち
インターネットアドレスファミリーである。

<tag>タイプ (type)</tag>
ハードウェアインターフェイスタイプとは、ネットワークデバイスが取り付けられた
メディアを表している。Linux のネットワークデバイスがサポートするメディアの
タイプは多種に渡る。それには、イーサネット、X.25、トークンリング、SLIP、PPP、
アップルローカルトークなどが含まれる。

<tag>アドレス (Address)</tag>
<tt>device</tt> データ構造体は、IP アドレスを含めて、そのネットワークデバイス
に関係するいくつかのアドレスを保持する。
</descrip>

<!--
Packet Queue
      This is the queue of sk_buff packets queued waiting to be
      transmitted on this network device, 
-->
<tag>パケットキュー (Packet Queue)</tag>
これは、ネットワークデバイス上で転送を待っている <tt><ref id="sk_buff" 
name="sk_buff"></tt> パケットのキューである。

<!--
Support Functions
      Each device provides a standard set of routines that protocol layers
      call as part of their interface to this device's link layer. These 
      include setup and frame transmit routines as well as routines to add 
      standard frame headers and collect statistics. These statistics can be 
      seen using the ifconfig command. 
-->
<tag>サポート関数 (Support Functions)</tag>
個々のデバイスは、そのデバイスのリンク層に対するインターフェイスの一部として、
プロトコル層がコールできるルーチンの標準セットを提供する。それには、設定ルーチ
ンやフレーム送信ルーチン以外にも、標準フレームヘッダ付加や統計情報収集のルーチ
ンも含まれる。それらの統計情報は <tt>ifconfig</tt> コマンドを使って見ることが
できる。
</descrip>

<!--8.6.1  Initializing Network Devices-->
<sect2>ネットワークデバイスの初期化<label id="chpter_dd_sect6-1">

<!--
Network device drivers can, like other Linux device drivers, be built into the
Linux kernel. Each potential network device is represented by a device data
structure within the network device list pointed at by dev_base list pointer.
The network layers call one of a number of network device service routines
whose addresses are held in the device data structure if they need device
specific work performing. Initially though, each device data structure holds
only the address of an initialization or probe routine. 
-->
<p>ネットワークデバイスドライバは、他の Linux デバイスドライバ同様、Linux 
カーネルに組み込むことができる。組み込まれた個々のネットワークデバイスは、
<tt><ref id="device" name="device"></tt> データ構造体によって表され、その構造体
は、ポインタのリストである <tt><ref id="dev_base" name="dev_base"></tt> に
よってポイントされたネットワークデバイスのリスト内に置かれる。
ネットワーク層は、デバイス固有の仕事が必要な場合、ネットワークデバイスに関する
多数のサービスルーチンのひとつを呼び出すが、そうしたルーチンのアドレスは <tt>
device</tt> データ構造体内に保持されている。しかし、適切な初期化が済むまでは、 
<tt>device</tt> データ構造体は、初期化もしくは検出ルーチンのアドレスしか保持し
ていない。

<!--
There are two problems to be solved for network device drivers. Firstly, not 
all of the network device drivers built into the Linux kernel will have 
devices to control. Secondly, the ethernet devices in the system are always 
called /dev/eth0, /dev/eth1 and so on, no matter what their underlying device
drivers are. The problem of ``missing'' network devices is easily solved. As
the initialization routine for each network device is called, it returns a 
status indicating whether or not it located an instance of the controller that
it is driving. If the driver could not find any devices, its entry in the 
device list pointed at by dev_base is removed. If the driver could find a 
device it fills out the rest of the device data structure with information 
about the device and the addresses of the support functions within the network
device driver. 
-->
<p>ネットワークデバイスドライバに関して解決すべき問題はふたつある。まず、
Linux カーネルに組み込まれたネットワークデバイスドライバのすべてが制御すべき
デバイスを持っているわけではないことである。もうひとつは、システム上の
イーサネットデバイスは、それらの基礎になるデバイスドライバとは無関係に、
<tt>/dev/eth0</tt>、<tt>/dev/eth1</tt> 等と呼ばれることである。ネットワーク
デバイスが存在しないという問題は、簡単に解決できる。個々のネットワークデバイス
の初期化ルーチンが呼び出された際に、それらのルーチンは、駆動すべき実際のコン
トローラを特定できたかどうかを報告するステータス情報を返す。ドライバがデバイス
を見つけられなかった場合、<tt><ref id="dev_base" name="dev_base"></tt> によって
ポイントされる <tt><ref id="device" name="device"></tt> 構造体のリスト内の
デバイスのエントリは削除される。ドライバがデバイスを検出できた場合、<tt>
device</tt> データ構造体の未設定部分に、そのデバイス情報とネットワークデバイス
ドライバ内のサポート関数のアドレスとを書き込む。

<!--
The second problem, that of dynamically assigning ethernet devices to the
standard /dev/ethN device special files is solved more elegantly. There are
eight standard entries in the devices list; one for eth0, eth1 and so on to
eth7. The initialization routine is the same for all of them, it tries each
ethernet device driver built into the kernel in turn until one finds a device.
When the driver finds its ethernet device it fills out the ethN device data
structure, which it now owns. It is also at this time that the network device
driver initializes the physical hardware that it is controlling and works out
which IRQ it is using, which DMA channel (if any) and so on. A driver may
find several instances of the network device that it is controlling and, in
this case, it will take over several of the /dev/ethN device data structures.
Once all eight standard /dev/ethN have been allocated, no more ethernet 
devices will be probed for.
-->
<p>もうひとつの問題である、イーサネットデバイスに標準的な <tt>/dev/ethN</tt> 
デバイススペシャルファイルを動的に割り当ててしまうという点については、もう少し
手際よく解決される。デバイスリストには 8 個の標準エントリがあり、順に <tt>
eth0, eth1</tt> 等から <tt>eth7</tt> まで並んでいる。初期化ルーチンは全部に
共通であり、カーネルに組み込まれたイーサネットドライバを、合致するデバイスが
見つかるまで順番に試していく。ドライバが該当するイーサネットデバイスを見つけた
とき、ドライバが所有することになった <tt>ethN</tt> <tt><ref id="device" 
name="device"></tt> データ構造体に情報を書き込む。そして、この時同時に、ネット
ワークデバイスドライバは、制御する物理デバイスを初期化し、使用する IRQ や(もし
必要なら) DMA チャンネル等を決定する。ドライバは、制御すべき複数のネットワーク
デバイスを検出することがあり、その場合は、複数の <tt>/dev/ethN device</tt> 
データ構造体を取得することになる。8 個すべての <tt>/dev/ethN devicd</tt> が割り
当てられると、それ以上のイーサネットデバイスの検出は行われない。

<!--
File translated from TEX by TTH, version 1.0. 
-->