デバイスドライバ(略称:ドライバ、ドライバー)とは、ディスプレイモニター、プリンターやイーサネットボード、拡張カードやその他周辺機器など、パソコンに接続されているハードウェアなどをオペレーティングシステム (OS) によって制御可能にするために用意されたソフトウェアである。
デバイスドライバはカーネルモジュールの一部として提供されています(デバイスドライバを抽象化したファイルがデバイスファイル)。
新しいデバイスをインストールすることをロードと呼びます(コマンドはmodprobe ドライバ名
)。
lsmod
によってインストール済みのカーネルモジュールを表示できます。
Linuxではデバイスドライバを抽象化したインターフェースをデバイスファイルと呼びファイルとして扱います。
デバイスファイル(英: Device file)またはスペシャルファイル(英: Special file)とは、ファイルシステム上であたかも通常のファイルのような形で提示されるデバイスドライバのインタフェースである。これにより、ソフトウェアが入出力システムコールを通してデバイスドライバを使うことができ、作業が単純化される。
デバイスファイルは、プリンターなどの周辺機器への単純なインタフェースを提供する。また、ディスクパーティションなどの機器上の特定のリソースへのアクセスにも使える。さらに、/dev/nullや擬似乱数生成器といった特定の機器とは対応しないリソースへのアクセスにも使われる。
Linuxでは、デバイスドライバを抽象化してデバイスファイルとして扱います。
デバイスファイルは/dev
ディレクトリに配置されています。
現在OSが認識しているデバイス情報は/proc
にあります。proc
ディレクトリは実体のない仮想ファイルです。
$ ll /proc | grep -E "(cpuinfo|meminfo)"
-r--r--r-- 1 root root 0 Jul 15 03:06 cpuinfo
-r--r--r-- 1 root root 0 Jul 15 03:06 meminfo
それぞれのデバイス情報を表示するlscpu
、lsmem
、lspci
、lsusb
などのコマンドがあります。
(※ PCI:拡張スロット Peripheral Components Connection、Peripheral 周辺の)
v
オプション:詳細表示vv
:さらに詳細に表示Udev(Userspace Device management)はデバイスファイルを管理します。
/sys
ディレクトリにデバイス情報を作成/sys
ディレクトリのデバイス情報を参照して/dev
ディレクトリにデバイスファイルを作成udevd
が/dev
にどのような名前でデバイスファイルを作成するかといった情報は/etc/udevd/rules.d
で設定します。
※ /sys
ディレクトリのファイルも/proc
ディレクトリ同様に仮想ファイルです。
BIOS/UEFI
起動SysVinit
(init
)/systemd
プロセス実行boot loader
)を読み出した後にブートローダーに制御を移しますinit
(またはsystemd
)プロセスを実行しますinit
またはsystemd
は必要なサービスを順次起動していき最後に、ログインプロンプトを起動します以上で起動処理が完了します。
[^bios]:「BIOS(Basic Input Output System:入出力基本システム)はキーボードやハードディスクなどのデバイスを制御するもっとも基本的な制御プログラムです。」(Linux教科書 LPIC1 p17) BIOSはフラッシュROMに書き込まれています。
// display message
// カーネルバッファを出力
$ dmesg
// systemdを使用している場合
$ journal -kb
現在はsystemd
が多く採用されています。
どちらもLinuxで最初に実行されるプロセス(PIDが1)です。
SysVinit
は/etc/init.d/
のスクリプトを実行しますSysVinit
はランレベルによって実行するスクリプトが異なります(/etc/rcN.d
※ Nはランレベル)/etc/rcN.d
のファイルは/etc/init.d/
へのシンボリックリンクが多いです例としてApacheをインストールした場合の挙動を記載します。
$ sudo apt install apache2
/etc/init.d
にapache
の起動スクリプトが作成されます。
また/etc/rc5.d
に↑へのシンボリックリンクが作成されます。
$ ll /etc/rc5.d
total 8
// ...
lrwxrwxrwx 1 root root 17 Jul 15 04:32 S01apache2 -> ../init.d/apache2*
// ...
よって/etc/init.d/apache2 start
起動できるようになります。
systemd
を採用しているUbuntuではsudo systemd start apache2.service
を使うことを推奨します。
以下はSysVinit経由でも実行できることを例示しているだけです。
$ sudo /etc/init.d/apache2 start
$ systemctl status apache2.service
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-07-15 04:45:40 UTC; 1min 3s ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 3008 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
Main PID: 3012 (apache2)
Tasks: 55 (limit: 1146)
Memory: 4.7M
CPU: 27ms
CGroup: /system.slice/apache2.service
├─3012 /usr/sbin/apache2 -k start
├─3018 /usr/sbin/apache2 -k start
└─3019 /usr/sbin/apache2 -k start
Jul 15 04:45:40 ip-10-2-1-95 systemd[1]: Starting The Apache HTTP Server...
Jul 15 04:45:40 ip-10-2-1-95 systemd[1]: Started The Apache HTTP Server.
SysVinit
に代わって主流になっています。Systemd
は、init
ではなくsystemd
プロセスが最初に起動(PIDが1)して各種サービスを管理します。
(つまりsystemd
プロセスがルートプロセスになります。)
例)自動起動を停止
cron
の自動起動を停止します。
$ sudo systemctl disable cron.service
EC2を再起動して確認するとcronは起動していません。
$ sudo systemctl status cron.service
○ cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:cron(8)
自動で起動するサービスにcronがないことを以下コマンドで確認できます。
$ sudo systemctl list-unit-files -t service --state=enabled | grep cron
// なし
cronの自動起動を有効化します。
$ sudo systemctl enable cron.service
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install
.
Executing: /lib/systemd/systemd-sysv-install enable cron
Created symlink /etc/systemd/system/multi-user.target.wants/cron.service → /lib/systemd/system/cron
.service.
自動で起動するサービスにcronが追加されています。
$ sudo systemctl list-unit-files -t service --state=enabled | grep cron
cron.service
この時点ではまだサービスは起動されません。
$ sudo systemctl status cron.service
○ cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:cron(8)
sudo systemctl start cron.service
を実行するかLinuxを再起動します。
Cプログラムで利用するライブラリは以下のものがあります。
静的ライブラリ
動的ライブラリ
(共有ライブラリ
)動的ライブラリを共有ライブラリ
と呼びます。
共有ライブラリは以下の特徴を持ちます。
lib〜.so〜
というファイル名/lib
または/usr/lib
に配置実行ファイルに必要な共有ライブラリはldd
(list dynamic dependecies)コマンドで調べることができます。
コマンドは絶対パスで指定します。
$ sudo ldd /bin/ls
linux-vdso.so.1 (0x00007fff88eb1000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f8c55e8d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c55c65000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f8c55bce000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8c55ee4000)
最低2つのパーティションが必要です。
[^swap]:仮想メモリ領域。スワップ領域の目安サイズは物理メモリの1から2倍(Linux教科書 LPIC1 p51)。
ボリュームを追加して3つのパーティションを作成します
/data1
にマウント/data2
にマウントボリュームがnvme1n1
として追加されたとします。
$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 squashfs 4.0 0 100% /snap/amazon-ssm-agent/5656
// ...
nvme0n1
├─nvme0n1p1 ext4 1.0 cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f 6.1G 19% /
├─nvme0n1p14
└─nvme0n1p15 vfat FAT32 UEFI 83EA-FFE2 99.1M 5% /boot/efi
nvme1n1 // <============= ブロックデバイスを追加
$ ll /dev | grep nvme1n1
brw-rw---- 1 root disk 259, 4 Jul 16 05:26 nvme1n1
$ sudo gdisk /dev/nvme1n1
// インタラクティブにパーティションを作成
// 3回繰り返して3つのパーティションを作成
sudo lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 squashfs 4.0 0 100% /snap/amazon-ssm-agent/5656
loop1 squashfs 4.0 0 100% /snap/core18/2409
loop2 squashfs 4.0 0 100% /snap/core20/1518
loop3 squashfs 4.0 0 100% /snap/snapd/16010
loop4 squashfs 4.0 0 100% /snap/lxd/22923
nvme0n1
├─nvme0n1p1 ext4 1.0 cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f 6.1G 19% /
├─nvme0n1p14
└─nvme0n1p15 vfat FAT32 UEFI 83EA-FFE2 99.1M 5% /boot/efi
nvme1n1
├─nvme1n1p1 <========== 追加されたパーティション
├─nvme1n1p2 <========== 追加されたパーティション
└─nvme1n1p3 <========== 追加されたパーティション
/data1
、/data2
にマウントするパーティション(nvme1n1p1, nvme1n1p2)のファイルシステムを構築します(この処理をフォーマットと呼ぶことがあります)。
スワップ領域に割り当てるパーティションnvme1n1p3
にはファイルシステムを構築しません。
// ext4でファイルシステムを構築
$ sudo mkfs -t ext4 /dev/nvme1n1p1
$ sudo mkfs -t ext4 /dev/nvme1n1p2
ファイルシステムが構築されたことを確認します。
lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 squashfs 4.0 0 100% /snap/amazon-ssm-agent/5656
// ...
nvme0n1
├─nvme0n1p1 ext4 1.0 cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f 6.1G 19% /
├─nvme0n1p14
└─nvme0n1p15 vfat FAT32 UEFI 83EA-FFE2 99.1M 5% /boot/efi
nvme1n1
├─nvme1n1p1 ext4 1.0 7bf0b8f6-3fdb-4942-b0df-c681c0065f29
├─nvme1n1p2 ext4 1.0 b1255df1-26ee-4af5-b274-989c73cdb4b9
└─nvme1n1p3
// data1にマウント
$ sudo mount /dev/nvme1n1p1 /data1
// data2にマウント
$ sudo mount /dev/nvme1n1p2 /data2
スワップ領域にマウントするパーティションにはファイルシステムを構築しないことに注意してください。
$ sudo mkswap /dev/nvme1n1p3
マウントを確認します。
lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0 squashfs 4.0 0 100% /snap/amazon-ssm-agent/5656
loop1 squashfs 4.0 0 100% /snap/core18/2409
loop2 squashfs 4.0 0 100% /snap/core20/1518
loop3 squashfs 4.0 0 100% /snap/snapd/16010
loop4 squashfs 4.0 0 100% /snap/lxd/22923
nvme0n1
├─nvme0n1p1 ext4 1.0 cloudimg-rootfs 767f2b75-d030-4999-951c-d4ab6b37f31f 6.1G 19% /
├─nvme0n1p14
└─nvme0n1p15 vfat FAT32 UEFI 83EA-FFE2 99.1M 5% /boot/efi
nvme1n1
├─nvme1n1p1 ext4 1.0 7bf0b8f6-3fdb-4942-b0df-c681c0065f29 416.9M 0% /data1
├─nvme1n1p2 ext4 1.0 b1255df1-26ee-4af5-b274-989c73cdb4b9 205.8M 0% /data2
└─nvme1n1p3 swap 1 0ddfdd2a-d70a-48ce-b327-12f510cf2f76
パーティションを操作するコマンドは、fdisk
、gdisk
、parted
があります。
fdisk
:MBRパーティションテーブルに対応(MBR:マスターブートレコード)gdisk
:GPTパーティションテーブルに対応(GPT:GUIDパーティションテーブル)parted
:MBR、GPT両方に対応$ sudo parted /dev/nvme0n1
GNU Parted 3.4
Using /dev/nvme0n1 <=============== ブロックデバイスを表示
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p // <==================== パーティションテーブルを表示
Model: Amazon Elastic Block Store (nvme)
Disk /dev/nvme0n1: 8590MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
15 5243kB 116MB 111MB fat32 boot, esp
1 116MB 8590MB 8474MB ext4
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 25.1M 1 loop /snap/amazon-ssm-agent/5656
// ...
nvme0n1 259:0 0 8G 0 disk
├─nvme0n1p1 259:1 0 7.9G 0 part / <======= 1
├─nvme0n1p14 259:2 0 4M 0 part <======= blos_grb
└─nvme0n1p15 259:3 0 106M 0 part /boot/efi <======= boot
nvme1n1 259:4 0 1G 0 disk /data
└─nvme1n1p1 259:5 0 512B 0 part
パーティションを作成してマウントしているボリュームを前提にします。
dmesg
:display messageuname
:unix namedepmod
:dependence modulesgrub-mkconfig
:grub make configldd
:list dynamic dependeciesdpkg
:Debian Packageref. https://tech.pjin.jp/blog/2017/01/12/lpicyokuarushitsumonsyudai2kaikomandoyuraihensono3/
fdisk
:format diskmke2fs
:make ext2 filesystemfsck
:filesystem checkref. https://tech.pjin.jp/blog/2017/02/06/the-questions-of-lpic-part2-the-origin-of-commands-no6/
df
:disk free(ディスクの空き容量)du
:disk usage(ディスク使用量)ref. https://tech.pjin.jp/blog/2017/02/07/the-questions-of-lpic-part2-the-origin-of-commands-no7/