>開発>Linux>[Linux]カーネル関連のトラブル

カーネル関連のトラブル

カーネルの関連のトラブルの多くはデバイス関連のものが多いため、トラブルが発生した場合、まずudevなどについて確認する。

“/proc”ディレクトリ以下のファイル

“/proc”は、カーネル内のデータのインターフェースとなるような擬似ファイルシステム。カーネルが認識しているデバイス、実行中のプロセス、システムのリソース情報などが格納されている。”/proc”以下のファイルはほとんどASCIIのテキストであるため、catコマンドで読出しが可能。

パス内容
/proc/数値PID毎のプロセスの情報
/proc/acpiACPI(Advanced Configuration & power Interface)に関する情報を格納
/proc/asoundALSA(Advanced Linux Sound Architecture)関連の情報を格納
/proc/bootconfigブート時のカーネル設定に関する情報を提供
/proc/buddyinfoメモリのフラグメンテーション(断片化)状況を表示
/proc/busシステムバス(PCI、USBなど)に関する情報を格納
/proc/cgroupsコントロールグループ(cgroups)の情報を表示
/proc/cmdlineカーネルに渡されたブートコマンドラインオプションを表示
/proc/consolesシステムで利用可能なコンソールに関する情報を表示
/proc/cpuinfoモデル、クロック周波数、コア数などのCPU情報を表示
/proc/cryptoカーネルで利用可能な暗号化モジュールの情報を表示
/proc/devicesディスク、ネットワークなどのデバイス情報の一覧を表示
/proc/diskstats各ディスクのI/O統計情報を表示
/proc/dmaDMA(ダイレクトメモリアクセス)チャネルの情報を表示
/proc/driverドライバに関する情報を格納
/proc/dynamic_debugカーネルのデバッグメッセージに関する設定を格納
/proc/execdomainsカーネルのデバッグメッセージに関する設定を表示
/proc/fbフレームバッファデバイスに関する情報を表示
/proc/filesystemsカーネルでサポートされているファイルシステムの情報を表示
/proc/fs各種ファイルシステムの詳細情報を格納
/proc/interruptsハードウェアとソフトウェアの割り込みカウントといったシステムの割り込み情報を表示
/proc/iomemシステムのメモリマップ情報を表示
/proc/ioportsI/Oポートのアドレス空間を表示
/proc/irqIRQ(Interrupt Request)に関する情報を格納
/proc/kallsymsカーネルシンボルテーブルを表示
/proc/kcoreカーネルメモリイメージ(仮想的なコアダンプファイル)を表示
/proc/keysキー管理の情報を表示
/proc/key-usersキーの使用状況に関する情報を表示
/proc/kmsgカーネルメッセージバッファを表示
/proc/kpagecgroup各ページのcgroup情報を表示
/proc/kpagecountページフレームのリファレンスカウント情報を表示
/proc/kpageflagsメモリページに関連するフラグ情報を表示
/proc/latency_statsシステムのレイテンシに関する情報を表示
/proc/loadavgシステムのロードアベレージを表示
/proc/locksカーネルのロック情報を表示
/proc/mdstatRAIDアレイのステータスを表示
/proc/meminfo物理メモリ、スワップメモリなどのメモリの使用状況を表示
/proc/miscデバイス番号などの主要なデバイスに登録されているその他のドライバーを一覧表示
/proc/modulesロードされたカーネルモジュールの情報を表示
/proc/mountsマウントポイントのリストを表示
/proc/mtrrCPUによるメモリ範囲へのアクセスをキャッシュする方法の制御をシステムであるMTRR(Memory Type Range Registers)の情報を表示
/proc/netネットワーク設定とステータスに関する情報を格納
/proc/pagetypeinfoページの種類に関する情報を表示
/proc/partitionsシステム上のパーティション情報を表示
/proc/pressureメモリ、CPU、I/Oなどのシステムのリソースに関する情報を格納
/proc/schedstatスケジューラの統計情報を表示
/proc/scsiSCSIデバイスに関する情報を格納
/proc/selfカレントプロセスのプロセスIDに対応するディレクトリ
/proc/slabinfoカーネルのスラブアロケータ(メモリ管理)の情報を表示
/proc/softirqsソフトウェア割り込みの統計情報を表示
/proc/statCPU使用率、割り込み、コンテキストスイッチなどといったシステム全体の統計情報を表示
/proc/swapsスワップ領域の情報を表示
/proc/sysシステム設定とパラメータにアクセスするためのディレクトリ
/proc/sysrq-triggerSysRqコマンドをトリガーするためのインターフェース
/proc/sysvipcSystem V IPC(プロセス間通信)に関する情報を格納
/proc/thread-self現在のスレッドのプロセスIDに対応するディレクトリ
/proc/timer_listカーネルのタイマーリストの情報を表示
/proc/tty端末デバイスに関する情報を格納
/proc/uptimeシステムの起動時間を表示
/proc/versionカーネルのバージョン情報を表示
/proc/version_signatureカーネルのバージョンサイン情報を表示
/proc/vmallocinfovmallocで割り当てられたメモリの情報を表示
/proc/vmstat仮想メモリの統計情報を表示
/proc/zoneinfoメモリゾーンに関する情報を表示

“/proc”以下のパスの情報はコマンドでも確認することができる。

lsdevコマンド

デバイスごとのDMA、IRQ、I/Oアドレスなどを一覧表示するコマンド。DMAは、CPUを経由せず直接メモリにアクセスできる仕組み。IRQ(Interrupt Request)は、ハードウェアがCPUに割り込み要求を送るための割り込み要請のこと。I/Oポートは、CPUがデバイスとやり取りするために使用する特定のメモリアドレス。

lsdevコマンドを利用するにはprocinfoをインストールする必要がある。

$ sudo apt install procinfo

lsdevコマンドを実行する。

$ lsdev
Device            DMA   IRQ  I/O Ports
------------------------------------------------
0000:00:01.1                   0000-0000   0000-0000   0000-0000   0000-0000   0000-0000
0000:00:02.0                   0000-0000
0000:00:03.0                   0000-0000
0000:00:04.0                   0000-0000
0000:00:05.0                   0000-0000   0000-0000
0000:00:07.0                   0000-0000   0000-0000
0000:00:0d.0                   0000-0000   0000-0000   0000-0000   0000-0000   0000-0000
ACPI                             0000-0000     0000-0000     0000-0000     0000-0000
acpi                      9
ahci                             0000-0000     0000-0000     0000-0000     0000-0000     0000-0000
ata_piix              14 15      0000-0000     0000-0000     0000-0000     0000-0000     0000-0000
cascade             4
dma                            0000-0000
dma1                           0000-0000
dma2                           0000-0000
e1000                            0000-0000
enp0s3                   19
fpu                            0000-0000
i8042                  1 12
Intel                            0000-0000     0000-0000
keyboard                       0000-0000   0000-0000
ohci_hcd:usb1            22
PCI                          0000-0000 0000-0000 0000-0000
pic1                           0000-0000
pic2                           0000-0000
piix4_smbus                      0000-0000
rtc0                      8      0000-0000
rtc_cmos                       0000-0000
snd_intel8x0             21
timer                     0
timer0                         0000-0000
timer1                         0000-0000
vboxguest                20      0000-0000
vga+                           0000-0000
vmwgfx                   18      0000-0000

lspciコマンド

システムのすべてのPCIバスと接続されているPCIデバイス情報を表示する。

オプション内容
-mm機械で処理しやすい書式で表示
-tデバイスツリーを表示
-v詳細を表示(-vv または-vvv はより詳細)
-k各デバイスを扱うカーネルドライバーを表示
-xPCI設定空間の先頭(標準部分)をダンプ
-xxxPCI設定空間全体のダンプ(rootのみ実行可)
-xxxxPCI設定空間を拡張してダンプ(rootのみ実行可)
-bPCIバスから見たアドレスとIRQといった情報を表示
-D常にドメイン番号を表示
-Pバスおよびデバイス番号に加えて、ブリッジパスを表示する。
-PPバスおよびデバイス番号に加えてバスパスを表示
-nベンダーとデバイスのIDを数字で表示
-nnベンダ0とデバイスを文字と数字の両方のIDで表示
-q認識できないデバイスをDNS経由でPCI IDデータベースに問い合わせる
-qq-qオプションと同様だが、ローカルにキャッシュされたエントリーを再照会する
-s [ドメイン]:[バス]:[スロット].[関数]ドメイン、バス、スロットとその関数で選択したスロットのデバイスのみを表示
-d [ベンダー]:[デバイス]ベンダー、デバイスで指定したIDのデバイスのみ表示
-iPCI ID データベースを指定
-pデフォルトの”modules.pcimap”でなく、指定されたファイルでカーネルモジュールを検索
-Mバスマッピングモードを有効にする (rootのみ実行可)
-APCIアクセス方法を指定 (アクセス方法の一覧は”-A help”を参照)
-O パラメータ名=設定値PCIアクセスパラメータを設定(パラメータの一覧は”-O help”を参照)
-GPCIアクセスのデバッグを有効にする
-H1 or -H2直接ハードウェアにアクセスを使う (構成は1か2)
-F-xオプションで得たファイルをPCIを設定
$ lspci
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
00:01.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
00:02.0 VGA compatible controller: VMware SVGA II Adapter
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
00:04.0 System peripheral: InnoTek Systemberatung GmbH VirtualBox Guest Service
00:05.0 Multimedia audio controller: Intel Corporation 82801AA AC'97 Audio Controller (rev 01)
00:06.0 USB controller: Apple Inc. KeyLargo/Intrepid USB
00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
00:0b.0 USB controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller
00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)

0番目のバスの3番目のスロットについての情報を表示する。

$ lspci -v -s 00:03
00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
	Subsystem: Intel Corporation PRO/1000 MT Desktop Adapter
	Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 19
	Memory at f0200000 (32-bit, non-prefetchable) [size=128K]
	I/O ports at d020 [size=8]
	Capabilities: <access denied>
	Kernel driver in use: e1000
	Kernel modules: e1000

lsusbコマンド

接続されているUSBデバイスの一覧を表示する。

オプション内容
-v, –verbose詳細を表示
-s [バス]:[DEVNUM]バスとDEVNUMで指定されたデバイスを表示
-d [ベンダー]:[PRODUCT]指定されたベンダー番号とプロダクトID番号 (16 進数) を持つデバイスのみを表示
-D デバイス指定したデバイスの情報を表示
-t, –treeUSBデバイスの階層をツリーで表示

現在接続されているデバイスを表示する。

$ lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

詳細な情報を表示してみる。

$ lsusb -v

Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            9 Hub
  bDeviceSubClass         0 [unknown]
  bDeviceProtocol         0 Full speed (or root) hub
  bMaxPacketSize0        64
  idVendor           0x1d6b Linux Foundation
  idProduct          0x0001 1.1 root hub
  bcdDevice            6.08
  iManufacturer           3 Linux 6.8.0-45-generic ohci_hcd
  iProduct                2 OHCI PCI host controller
  iSerial                 1 0000:00:06.0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0019
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                0mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         9 Hub
      bInterfaceSubClass      0 [unknown]
      bInterfaceProtocol      0 Full speed (or root) hub
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255
・
・
・

デバイスファイル

“\dev”ディレクトリ以下は、デバイスファイルがある。デバイスファイルには、ブロックデバイスファイルとキャラクタデバイスがあり、ブロックデバイスファイルのファイルタイプは”b”、キャラクタデバイスのファイルタイプは”c”となる。ブロックデバイスは、バッファを持ち、ランダムアクセスが可能なデバイスで、ブロック単位でアクセスできる。ハードウェアやRAMディスクなどがこれに当たる。キャラクタデバイスは、バッファがなく、ランダムアクセスができないデバイス。キーボードやマウスなどの入力デバイスがこれにあたる。

デバイスのファイルタイプを確認する

ファイルタイプを確認してみる。左端の値が”b”の場合はブロックデバイスファイルのファイルタイプ、”c”の場合はキャラクタデバイスのファイルタイプとなる。

$ ls -l /dev/
・
・
・
brw------- 1 root root   1,   7 Sep  3 09:52 ram7
brw------- 1 root root   1,   8 Sep  3 09:52 ram8
brw------- 1 root root   1,   9 Sep  3 09:52 ram9
crw-rw-rw- 1 root root   1,   8 Sep  3 09:52 random
crw------- 1 root root 251,   0 Sep  3 09:52 rtc0
brw------- 1 root root   8,   0 Sep  3 09:52 sda
brw------- 1 root root   8,  16 Sep  3 09:52 sdb
brw------- 1 root root   8,  32 Sep  3 09:52 sdc
・
・
・

カーネルが認識しているデバイスは、”/proc/devices”以下のファイルを参照することで確認できる。

$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
5 ttyprintk
6 lp
・
・
・

Block devices:
7 loop
8 sd
9 md
11 sr
65 sd
・
・
・

udev

udevが登場する以前は、あらかじめコンピュータに接続する可能性のあるすべてのデバイスに対してデバイスファイルを作成し、たくさんのデバイスファイルを”/dev”以下に格納されていたが、現在は必要に応じてudevとsysfsとが連携し、動的にデバイスファイルを管理する。ハードウェアに接続されると、カーネルが検知し、カーネル情報を監視しているudevdデーモンが必要なデバイスファイルを動的に作成する。従って、カーネルが認識しているデバイスに対応するデバイスファイルのみ用意される。また、udevはユーザー空間で動作するプロセスで、ユーザー空間とカーネル空間は分離されているため、アプリケーションはカーネル内部の情報に直接アクセスできない。そのため、uedv、sysfsから情報を取得し、sysfsがカーネル内部情報をファイルシステムとして反映させる。”/sys”以下からシステムに接続されているデバイスの情報を得ることができる。

udevの動作

  1. デバイスを接続し、Linux カーネルはデバイスを検知
  2. カーネルが仮想ファイルシステム sysfs(/sys)にデバイス情報を作成。
  3. カーネルがudevdにデバイス情報を通知。(uevent)
  4. udevdが/sysのデバイス情報を確認。
  5. udevが/devにデバイスファイルを作成。

設定ファイル

新しいデバイスをカーネルが認識すると、udevdはsysfsの情報を基に、必要なデバイスファイルを作成する。その際に参照される設定ファイルは、メインの設定ファイルが“/etc/udev/udev.conf”、個別の設定ファイル(ルールファイル)が“/etc/udev/rule.d”にある。”/etc/udev/rule.d”の中の設定ファイルは、番号の若いファイルから順に適用される。ファイル名は、数字で始まり、番号の若いファイルから適用される。

Virtual Boxの環境で見てみる。

$ ls /etc/udev/rules.d/
60-vboxadd.rules  70-snap.firefox.rules  70-snap.snapd-desktop-integration.rules  70-snap.snapd.rules  70-snap.snap-store.rules

設定ファイルの書式

設定ファイルの書式は下記の通り。識別キーは、カーネルが認識した情報をマッチさせる情報を記載する。この情報は、udevadm infoコマンドなどで当該デバイスを調査した結果に基づいて記述する。キーと値のセットは”,”で区切って列挙し、デバイスを識別するために利用される。1つ以上の識別キーと値がマッチすれば、指定したルールが適用され、デバイスファイルが作成される。その際に利用されるのが、代入キーに指定された値。

識別キー==値、代入キー=値

Virtual Boxのrulesを確認してみると、デバイス名と所有者、権限の値がセットされている。

$ cat /etc/udev/rules.d/60-vboxadd.rules
KERNEL=="vboxguest", NAME="vboxguest", OWNER="vboxadd", MODE="0660"
KERNEL=="vboxuser", NAME="vboxuser", OWNER="vboxadd", MODE="0666"

デバイスファイルを確認すると、設定ファイルに基づいて所有者とパーミッションが設定されている。

$ ls /dev/
・
・
・
crw-rw----   1 vboxadd root     10, 122 Oct  2 10:22 vboxguest
crw-rw-rw-   1 vboxadd root     10, 121 Oct  2 10:22 vboxuser
・
・
・

udevadm infoコマンド

特定のデバイスに関する詳細な情報を表示できるコマンド。デバイスの検知や設定を自動化するために使われる。

udevadm info [オプション]
オプション内容
-q –query=タイプデバイス情報を問い合わせる。タイプは表示する情報を種類を指定する(env:udevイベントの環境変数、name:デバイスノード名、symlink:ノードへのポインティング、path:sysfsデバイスパス、property:デバイスのプロパティ、all:すべての値)
-p –path=パスsysfsパスを指定してデバイス情報を表示
-n –name=デバイスノードデバイスノードを指定して情報を表示
-r –root/(root)からデバイスパスを表示
-a –attribute-walk指定されたデバイスとその親デバイスの属性の一覧を表示
-t –treeデバイスのツリーを表示
-d –device-id-of-file=ファイル指定されたファイルが属するデバイスの情報を取得

sysfasが”/dev/sda”をどのように扱っているか確認してみる。

$ udevadm info -q env -n /dev/sda
DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/ACPI0004:00/VMBUS:00/fd1d2cbd-ce7c-535c-966b-eb5f811c95f0/host0/target0:0:0/0:0:0:0/block/sda
DEVNAME=/dev/sda
DEVTYPE=disk
DISKSEQ=25
MAJOR=8
MINOR=0
・
・
・

属性の一覧を表示する。

$ udevadm info -a /dev/sda

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:0d.0/ata3/host2/target2:0:0/2:0:0:0/block/sd>
    KERNEL=="sda"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{alignment_offset}=="0"
    ATTR{capability}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{diskseq}=="11"
    ATTR{events}==""
    ATTR{events_async}==""
    ATTR{events_poll_msecs}=="-1"
    ATTR{ext_range}=="256"
    ATTR{hidden}=="0"
    ATTR{inflight}=="       0        0"
    ATTR{integrity/device_is_integrity_capable}=="0"
    ATTR{integrity/format}=="none"
    ATTR{integrity/protection_interval_bytes}=="0"
    ATTR{integrity/read_verify}=="0"
    ATTR{integrity/tag_size}=="0"
    ATTR{integrity/write_generate}=="0"
    ATTR{mq/0/cpu_list}=="0, 1"
    ATTR{mq/0/nr_reserved_tags}=="0"
    ATTR{mq/0/nr_tags}=="32"
    ATTR{partscan}=="1"
    ATTR{power/async}=="disabled"
    ATTR{power/control}=="auto"
    ATTR{power/runtime_active_kids}=="0"
    ATTR{power/runtime_active_time}=="0"
    ATTR{power/runtime_enabled}=="disabled"
・
・
・

ubuntu

記事を読んでいただきありがとうございました。

Page Top