「/ dev」Linuxファイルはどのように作成されますか?


112

Linuxには、実際にはファイルではない特別なファイルがあります。

これらの最も注目すべき明確な例は、次のdevような「ファイル」フォルダーにあります。

  • /dev/null -ファイルに書き込んだものはすべて無視します
  • /dev/random -ファイルの内容の代わりにランダムなデータを出力します
  • /dev/tcp -ネットワーク経由でこのファイルに書き込むデータを送信します

まず第一に、これらの種類の「ファイル」の名前は何ですか?実際には何らかのスクリプトまたはバイナリの変装です。

第二に、それらはどのように作成されますか?これらのファイルはカーネルレベルでシステムに組み込まれていますか、それとも自分で「マジックファイル」を作成する方法はありますか(どう/dev/rickrollですか?)。


1
特に探しているものの名​​前がわからないので、この質問にタグを付ける方法がわかりませんでした。関連するタグを自由に編集してください。
IQAndreas

15
ところで、これは、unixおよびunixライクなオペレーティングシステムの設計の基本的な部分です。(ほとんど)すべてがファイルであるか、ファイルのように見えるようにすることができます。
cas

5
参照:mknod(2) man 2 mknod
RobertL

4
これらは「デバイスノード」です。ただし、ディスク、キーボード、マウス、オーディオカード、およびその他のデバイスに関連するものとは異なり、あなたが言及したものはいわゆる「擬似デバイス」です。「実際の」デバイスではなく、カーネルにのみ存在します。適切なデバイスドライバーを作成してカーネルに追加することにより、新しいものを作成することができます(たとえば、コンピューター上のアクティビティを監視するための擬似デバイス)。/ dev-ディレクトリがディスクに存在する前-最近では、カーネルによって作成された(devfsタイプの)仮想ファイルシステムです。
バールドコッペルード

10
「実際の」ファイルであっても、すべてのファイルはソフトウェア成果物です。まだ発明されるあらゆるデバイス、ファイル、ソケット、特殊ファイル、または何かの背後にあるソフトウェアが処理する機能のテーブルを提供しopen()read()close()それはソフトウェア次第です、その後など、
waltinator

回答:


101

/dev/zero「特別なファイル」、特に「デバイスノード」の例です。通常、これらはディストリビューションのインストールプロセスによって作成されますが、必要に応じて完全に作成することもできます。

あなたが頼めばlsについて/dev/zero

# ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5  Nov 5 09:34 /dev/zero

先頭の「c」は、これが「キャラクターデバイス」であることを示しています。もう1つのタイプは「ブロックデバイス」です(ls「b」と表示されます)。大まかに言って、ハードディスクのようなランダムアクセスデバイスはブロックデバイスである傾向がありますが、テープドライブやサウンドカードのようなシーケンシャルなデバイスはキャラクターデバイスである傾向があります。

「1、5」の部分は「主要なデバイス番号」と「マイナーなデバイス番号」です。

この情報を使用して、mknodコマンドを使用して独自のデバイスノードを作成できます。

# mknod foobar c 1 5

これは、という名前の新しいファイルを作成foobarし、現在のフォルダ内に、正確に同じことを/dev/zero。(もちろん、必要に応じて異なるアクセス許可を設定できます。)この「ファイル」に実際に含まれるのは、デバイスタイプ、メジャー番号、マイナー番号の3つの項目のみです。ls他のデバイスのコードを検索し、それらを再作成するために使用できます。退屈したら、使用rmして、作成したばかりのデバイスノードを削除します。

基本的に、メジャー番号はLinuxカーネルにどのデバイスドライバーと通信するかを示し、マイナー番号はデバイスドライバーにどのデバイスについて話しているかを示します。(たとえば、おそらく1つのSATAコントローラーがありますが、複数のハードディスクが接続されている可能性があります。)

何か新しいことをする新しいデバイスを発明したい場合は、Linuxカーネルのソースコードを編集し、独自のカスタムカーネルをコンパイルする必要があります。そんなことはやめましょう!:-)しかし、あなたはすでにあなたがすでにうまくいったものを複製するデバイスファイルを追加することができます。udevのような自動化されたシステムは、基本的にデバイスイベントを監視し、自動的にmknod/ rmを呼び出します。それ以上の魔法はありません。

他の種類の特別なファイルがまだあります:

  • Linuxは、ディレクトリを特別な種類のファイルと見なします。(通常、ディレクトリを直接開くことはできませんが、可能であれば、特別な形式のデータを含む通常のファイルであり、そのディレクトリ内のすべてのファイルの場所をカーネルに指示します。)

  • シンボリックリンクは特別なファイルです。(ただし、ハードリンクはそうではありません。)ln -sコマンドを使用してシンボリックリンクを作成できます。(マンページをご覧ください。)

  • 「名前付きパイプ」または「FIFO」(先入れ先出しキュー)と呼ばれるものもあります。で作成できますmkfifo。FIFOは、1つの読み取りと1つの書き込みという2つのプログラムで同時に開くことができる魔法のファイルです。これが発生すると、通常のシェルパイプのように機能します。ただし、各プログラムを個別に起動できます...

決して「特別」ではないファイルは、「通常のファイル」と呼ばれます。これについては、Unixのドキュメントで時々言及されます。それが意味するものです。デバイスノードまたはシンボリックリンクなどではないファイル。魔法の特性のない、通常の毎日のファイル。


4
もう1つのタイプの特殊ファイル、ファイルシステムにバインドされたUnixドメインソケットもあります。
ブライアンBi

8
で遊ぶ場合は、すべてのドライバーのメジャー番号を確認mknodするcat /proc/devicesために実行します。これにより、/procファイルシステムの別の種類の特別なファイルに移動できます(この回答では、それについて説明しています)。
ウゴレン

8
他のUnicesは独自の特殊ファイルを発明しました。たとえば、Solarisにはドアがありました
ケビン

6
ちょっとした注意:新しいキャラクター/ブロックデバイスを作成するためにカーネルを再コンパイルする必要はありません:) crashcourse.ca/introduction-linux-kernel-programming / ...そうでなければ、これは本当に良い答えです、+ 1!
コリアンダーサンショウウオ司令官

1
@MathematicalOrchid:返信が欠落している(または少なくとも暗黙的に述べている)ステップは、それらの特殊ファイルが(質問が暗示するように)偽装シェルスクリプトまたはバイナリではなく、存在する機能にアクセスするためのインターフェースであるという事実ですOSカーネル内。
ドリーマー

34

ほとんどの/devエントリは、ブロックデバイスのiノードまたはキャラクターデバイスのiノードです。ウィキペディアにはそれについて多くの詳細がありますが、これについては繰り返しません。

しかし/dev/tcp、あなたの質問で言及されていることは、既存の答えのいずれによっても説明されていません。他のほとんどのエントリ/dev/tcp/dev/udpは異なり/devます。ブロックと文字のデバイスは、カーネルで実装されますが、/dev/tcpおよび/dev/udpユーザーモードで実装されています。

bashシェルは、/dev/tcpおよび/dev/udp(からコピーksh93)の実装を持つ1つのプログラムです。bashリダイレクト演算子でパスの下にパスを開こうとすると、通常のopenシステムコールは実行されません。代わりに、bashはTCPソケットを作成し、指定されたポートに接続します。

これは、ユーザーモードで実装され、一部のプログラムでのみ実行されます。次の例では、letting bashcatopenの試行の違いを示しています。/dev/tcp/::1/22

$ cat /dev/tcp/::1/22
cat: /dev/tcp/::1/22: No such file or directory
$ cat < /dev/tcp/::1/22
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3

との違いksh93は、bashリダイレクション演算子を使用してこれらのTCP接続のみを実行し、他の場所source.ビルトインなどのファイルを開く場所では実行しないことです。


また、GNU awk は2010年頃のどこかからgawk同様に特殊なケースを扱って/inet{,4,6}/{tcp,udp}/$port/$remote/$rportいます(正確には思い出せず、リリースノートは見つかりません)。
-dave_thompson_085

6
IMO、ポイントを述べるより良い方法/dev/tcpは、それがファイルではないということです。これというファイルはありません。ソケットを開くためのBashの構文/dev/tcp/addressはファイル名のような文字列を使用しますが、「ユーザー空間に実装されたファイル」と呼ぶのは奇妙に聞こえます。興味深いのは、kshリダイレクトだけでなく、すべてのファイル名をフックすることです。それは「ファイルの実装」に近いです。
ピーターコーデス

@PeterCordes UWINはこれらを実際のファイルとして設定すると信じています。そして、私は3dfsが同じことをすると思います。覚えておいてください、bashこの動作をコピーしただけですが、それは他の場所で発生します。
mikeserv

19

デバイスノードの他に(で作成した他の回答で説明したのmknod(2)一部または供給devfsの)、Linuxは特別なことで提供される他、「魔法」のファイルがある仮想ファイルシステム内の特定の中を、/proc/(参照(5)PROCを、読んprocfsの)およびin /sys/sysfsについて読む)。

これらの疑似ファイル(たとえば、stat(2)には -デバイスではなく通常のファイルとして表示されます)は、カーネルによって提供される仮想ビューです。特に、/proc/(たとえば、プログラムでopen(2) -ingを使用してからの読み取りにはcat /proc/$$/maps、通常、ディスクまたはネットワークからの物理I / Oは含まれないため、非常に高速です。/proc/self/status

いくつかの追加の疑似ファイルを作成/proc/するには、通常、独自のカーネルモジュールを記述してロードする必要があります(たとえば、これを参照)。


3
/ procの拡張に関する情報は古くなっています。技術的には可能ですが、/ proc(またはprocfs)は実行中のプロセスに関する情報のみを保持する必要があります。カーネルのランタイム情報または構成オプションを含むものを含む他のすべての擬似ファイルは、/ sys(sysfs)に移動する必要があります。互換性の理由から、/ procにはプロセスに関連しないいくつかの疑似ファイル(例:meminfo、cpuinfo)がまだありますが、新しい疑似ファイルはsysfsに入れる必要があります。
ドリーマー

13

これらはデバイスノードと呼ばれ、で手動で作成されるか、でmknod自動的に作成されますudev。これらは通常、カーネル内にドライバーを備えたキャラクターまたはブロックデバイスへのファイルのようなインターフェイスです。たとえば、ディスクはブロックデバイス、ttyおよびシリアルポートなどはキャラクターデバイスです。

名前付きパイプ、FIFO、ソケットなど、他の「特別な」ファイルタイプもあります。


9

他のユーザーがすでに詳細に説明しているように、特別なファイルにはそれらをバックアップするためのコードが必要です。しかし、Linuxがユーザー空間にそのコードを書くためのいくつかの方法を提供していることについて誰も言及していないようです。

A. FUSE(USErspaceのファイルシステム)を使用すると/proc、カーネルをクラッシュさせずに、GoNode.jsPerlPHPPythonRubyRustなどの選択した言語/ランタイムで実行できます。など

また、FUSEファイルシステムは、マウントをsudo行うユーザーとして実行されるため、マウントせずにマウントできるという利点もあります。

FUSEを使用して書いたものの例を次に示します。

  • mp3fs(FLACファイルをMP3ファイルとして表示し、MP3プレーヤーにコピー/クリックしてドラッグすると、オンザフライで作成されます)
  • PyTagsFS(メタデータタグから構築された仮想フォルダーのツリーでメディアを表示)
  • fuse-zip(Zipファイルをフォルダーとしてマウント)
  • FuseISO(ルート権限なしでISOをマウント)
  • iFUSEiDeviceのマウント)
  • FuseDAV(WebDAV共有のマウント)
  • fuse-exfat(exFAT形式のファイルシステムのマウント)
  • ntfs-3gを(LinuxのNTFSドライバ)

B.キーボード、マウス、ジョイスティックなどの仮想入力デバイスを作成する場合(たとえば、使用しているUSBデバイス用のユーザースペースドライバーを作成する場合libusb)、uinputがあります。

バインディングは見つけるのが難しいですが、Go(キーボードのみ)、PythonRuby (2)に存在することは知っています。

実際のuinputの使用例は次のとおりです。

  • G15Daemon(Logitech G15ゲーミングキーボードのLCDおよびゲーミングキー用のLinuxドライバー)
  • ds4drv(Sony DualShock 4コントローラーのドライバー)
  • xboxdrv(代替のXBox 360コントローラードライバーとRunner2のようなひどく設計されたx360ceに相当するLinux :Future Legend of Rhythm Alienは、実際のXBoxコントローラーと話していないと考えることができる)
  • cwiidのような古いWiimoteドライバーは、誰かが最終的にカーネルWiimoteドライバーを作成する前に必要だったため、デフォルトでサポートが利用可能になりました。

C.汎用キャラクターデバイスには、CUSE(USErspaceのキャラクターデバイス)があります。ただし、あまり人気はありません。

私が個人的に知っているCUSE APIの唯一のユーザーは、その作成を促した同じプログラムです。osspdは、ユーザー空間に、、および(OSSオーディオAPI)を実装し/dev/dsp、PulseAudioまたはdmix経由でルーティングできるようにします。/dev/adsp/dev/mixer

私が見つけることができた唯一のCUSEバインディングはcusepyで、2010年以降は更新されていません。

D.新しい特別なファイルはまったく必要ないかもしれません。

たとえば、libusb(ページ上のバインディングのリスト)を使用して任意のUSBデバイスとの生の通信を開き、他のメカニズム(TCP / UDPソケット、stdin / stdoutまたはディスク上の通常ファイルの読み取り/書き込み)を介して他のプログラムと通信できます。など)。


1
cusepyはしばらく更新されていない可能性があります(実際、更新されたことはありません;コミットは1つしかありません!)が、数週間前にcusepyを使用してキャラクターデバイスを作成したばかりで、正常に動作することを確認できます。実装pollに関連するいくつかの関数が欠落していましたが、cusepyはctypesを使用し、バインディングはCヘッダーファイルに基づいて自動生成されるため、欠落している関数を修正するには、のエクスポート関数のリストに目的の関数名を追加するだけsetup.pyです。
アレクシトルハモ

1
FUSEのもう1つの興味深い使用例はsshfsです。下にあるSSH接続を使用して、あたかもローカルであるかのようにリモートファイルシステムを参照できます。
ミスター・デスレス

@ Mr.Deathlessうん。私は実際にそれを使用し、言及するつもりでしたが、私は忘れていました。
-ssokolow

6

ブックLinuxのデバイスドライバは(強く推奨)これを詳細に説明し、も、あなたは一例としてこれを行い、カーネルモジュールを作成していますが、一言で言えば、各デバイスドライバは、ファイルが開かれたときに呼び出される特定の機能を持っている、閉じました、読み取り、書き込みなど。「特別な」ファイルは、ディスク上のストレージハードウェアにアクセスする代わりに、それらの関数内で何か特別なことを行います。

たとえば、書き込み関数/dev/nullは何もせず、バイトを無視します。の読み取り関数/dev/randomは、乱数を返します。


1

mount -t devtmpfs

また、最新のシステムで/devは、通常、どこにでもマウントできるファイルシステムタイプであることがわかります。Ubuntu 16.04:

mkdir d
sudo mount -t devtmpfs none d
head -c 10 d/random
sudo umount d

これはによって有効にされCONFIG_DEVTMPFS=y、カーネル自体が必要に応じてデバイスファイルを作成および破棄できるようにします。

CONFIG_DEVTMPFS_MOUNT=y

このオプションにより、カーネルはdevtmpfsを自動マウントし/devます。

drivers/base/Kconfig 文書:

config DEVTMPFS_MOUNT
    bool "Automount devtmpfs at /dev, after the kernel mounted the rootfs"
    depends on DEVTMPFS
    help
      This will instruct the kernel to automatically mount the
      devtmpfs filesystem at /dev, directly after the kernel has
      mounted the root filesystem. The behavior can be overridden
      with the commandline parameter: devtmpfs.mount=0|1.
      This option does not affect initramfs based booting, here
      the devtmpfs filesystem always needs to be mounted manually
      after the rootfs is mounted.
      With this option enabled, it allows to bring up a system in
      rescue mode with init=/bin/sh, even when the /dev directory
      on the rootfs is completely empty.

file_operations

最後に、独自のキャラクターデバイスカーネルモジュールを作成して、何が起こっているのかを正確に確認する必要があります。

最小限の実行可能な例を次に示します。キャラクターデバイス(またはキャラクタースペシャル)ファイルについて

最も重要なステップは、file_operations構造体を設定することです。例:

static const struct file_operations fops = {
    .owner = THIS_MODULE,
    .read = read,
    .open = open,
};

static int myinit(void)
{
    major = register_chrdev(0, NAME, &fops);
    return 0;
}

ファイル関連のシステムコールごとに呼び出される関数ポインタが含まれています。

その後、これらのファイル関連のシステムコールをオーバーライドして、必要な処理を実行することが明らかになるため、カーネルはのようなデバイスを実装します/dev/zero

/devで自動的にエントリを作成しますmknod

最後の謎は、カーネルが/devエントリを自動的に作成する方法です。

メカニズムは、https//stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module-に示されているように、自分でそれを行うカーネルモジュールを作成することで確認できます。 code-of-a-linux-kernel-module / 45531867#45531867device_create呼び出します。


OpenBSDには、これを少し簡略化するスクリプトMAKEDEVがあります。man.openbsd.org/ MAKEDEV.8を参照してください。Linux がそれを持たない理由は、それがもっと複​​雑なことを除けばわかりません。たぶん部品を適合させることができます。たとえば、MKNOD ttyと言うと、詳細を処理します。
アランコーリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.