---
title: 第77回シェル芸勉強会
tags:  #シェル芸  
author: [Ryuichi Ueda](https://image.docswell.com/user/ryuichiueda)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/87DK6GN6JG.jpg?width=480
description: 2026年10月17日さくらインターネットさんにて  動画: https://www.youtube.com/watch?v=nGCn2cJcsVM
published: October 18, 26
canonical: https://image.docswell.com/s/ryuichiueda/ZMQ8YJ-2026-10-17-shellgei_77
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/87DK6GN6JG.jpg)

jus共催 第77回デバイスシェル芸勉強会
個人情報がクリエイティブコモンズ
上田 隆一
2026年10月17日 © 2026 上田隆一
第77回シェル芸勉強会


# Page. 2

![Page Image](https://bcdn.docswell.com/page/VJPKY3NZE8.jpg)

近況
しぇるげいすきー（招待制シェル芸Misskeyサーバー）
低空飛行
ロボットやさん向けLinuxの本
デバイス難しい・・・本日還元
第77回シェル芸勉強会
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/2EVVG4KMEQ.jpg)

Software Designの連載
「魅惑の自作シェルの世界」
12月号（49回）の原稿を提出したところ
10月号: パターン削除の実装（後編）とパターン置換の実
装（前編）
11月号: パターン置換の実装（後編）とパラメータの空文
字・未定義チェック（前編）
12月号: パラメータの空文字・未定義チェック（後編）
1月号（第50回）予定: 未定
やっと中途半端前編後編が終わった模様
第77回シェル芸勉強会
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/57GL81QXEL.jpg)

シェル芸とは
マウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間もなく、あらゆる
調査・計算・テキスト処理をCLI端末へのコマンド入力一撃で終わらすこと。あるいは
そのときのコマンド入力のこと。
第77回シェル芸勉強会
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/4EQY9DK5JP.jpg)

今回の座学と問題
デバイスについて
まともにやるとすごいことになるので今回はつまみ食い程度（次回もたぶん
デバイス？）
出題
あんまりシェル芸っぽくないかも（と、最初に書いてスライド作ってったら
そうでもなくなった）
第77回シェル芸勉強会
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/KJ4WXZPV71.jpg)

準備
問題用データのダウンロード
https://github.com/ryuichiueda/ShellGeiData
$ git clone https://github.com/ryuichiueda/ShellGeiData.git
$ cd ShellGeiData/vol.77
$ ls
bcm2712-rpi-5-b.dtb
第77回シェル芸勉強会
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/LE1YNR947G.jpg)

計算機とデバイス
計算機にはCPU、DRAM以外にもいろいろ部品がついている
HDD、SSD、NIC、グラフィックカード、ブザー、スピーカー、温度計、PCIe
やUSBのホストとデバイス、・・・
ほとんどがCPUやOSから操作できる
どうやって？
第77回シェル芸勉強会
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/GEWG41QZJ2.jpg)

CPUとデバイスのやりとり（CPU-&gt;デバイス）
メモリマップドI/O（MMIO）がほとんど
ある範囲のメモリの番地が特定のデバイスのレジスタに割り当てられる
メモリ操作と同じ方法でデバイスも操作できる
ポートマップドI/O
専用のアドレス空間と命令
専用めんどいし、ビデオカードなどにでかいメモリがあるともっと面倒
問題1: PCI（PCI Express）バスに挿すデバイス用に確保されている主要なメモリの
番地の範囲と番地の数を調べてみましょう
範囲の上限は「未満」で表現を
必要に応じてkB、MB、GB単位で
よかったら他のデバイスについても
8
第77回シェル芸勉強会


# Page. 9

![Page Image](https://bcdn.docswell.com/page/47ZL2PWLJ3.jpg)

解答例
sudo cat /proc/iomem | grep PCI | sed -ne 1p -e &#039;/^[^ ]/p&#039;
000a0000-000bffff : PCI Bus 0000:00
a0800000-bfffffff : PCI Bus 0000:00
c0000000-cfffffff : PCI ECAM 0000 [bus 00-ff]
2000000000-3fbfffffff : PCI Bus 0000:00
### kB単位 ###
sudo cat /proc/iomem | grep PCI | sed -ne 1p -e &#039;/^[^ ]/p&#039; | sed &#039;s/ *//&#039;| sed &#039;s/-/ 0x/&#039;
| sed &#039;s/^/0x/&#039;| awk &#039;{for(i=1;i&lt;=2;i++)$i=(strtonum($i)+(i-1)%2)/1024;print $0, $2-$1&quot;kB&quot;}&#039;
640 768 : PCI Bus 0000:00 128kB
2629632 3145728 PCI Bus 0000:00 516096kB
3145728 3407872 PCI ECAM 0000 [bus 00-ff] 262144kB
134217728 267386880 PCI Bus 0000:00 133169152kB
### MiB単位 ###
sudo cat /proc/iomem | grep PCI | sed -ne 1p -e &#039;/^[^ ]/p&#039; | sed &#039;s/ *//&#039; | sed &#039;s/-/ 0x/&#039;
| sed &#039;s/^/0x/&#039;| awk &#039;{for(i=1;i&lt;=2;i++)$i=(strtonum($i)+(i-1)%2)/1024**2;print $0, $2-$1&quot;MiB&quot;}&#039;
0.625 0.75 : PCI Bus 0000:00 0.125MiB
2568 3072 PCI Bus 0000:00 504MiB
3072 3328 PCI ECAM 0000 [bus 00-ff] 256MiB
131072 261120 PCI Bus 0000:00 130048MiB
うんちくは次ページ
第77回シェル芸勉強会
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/YJ6WVMGMJV.jpg)

PCIe関係のメモリの範囲（DRAMの割当ではないことに注意）
項目ごとにkB、MiB、GiBを使い分けて整理
640 768 : PCI Bus 0000:00 128kB
2568 3072 PCI Bus 0000:00 504MiB
3072 3328 PCI ECAM 0000 [bus 00-ff] 256MiB
128 255 PCI Bus 0000:00 127GiB
#昔のグラフィック（VRAM）用（PC/ATとかPC-98とかの時代）
#32bit領域
#ECAM: Enhanced Configuration Access Mechanism
#64bit領域
640kB: 昔のある時期のPCでの自由に使えるメモリの上限。邪魔
32bit領域も邪魔（64bit領域も微妙に邪魔だけどたぶん大丈夫）
ECAM: PCIeのデバイスが持つ設定用メモリ（コンフィギュレーション領域）
の範囲に割り当てられる
1デバイス4096バイト（昔のPCIデバイスは256バイト）
バス 個 デバイス上限 個 ファンクション 個 kB MiB
この領域に何か書き込むと飛ぶかも（責任とりませんがどうぞ）
第77回シェル芸勉強会
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/GJ5MDZVQJ4.jpg)

MMIOの番地の情報の所在
x86: ACPI（advanced configuration and power interface）テーブル
どこかのROMにあってBIOS（UEFIのものを含む）が読み出す
ARMなど: デバイスツリー
ラズパイの場合はmicroSDカードのFAT32の領域に
これもブートをつかさどるファームウェアが読みに行く
あとはプラットフォームごとにカーネルに直書きする方法
ボードファイルと言うらしい
第77回シェル芸勉強会
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/9E298R3W7R.jpg)

デバイスツリー
デバイスの配置をツリー状に記述したデータ
データの実物: bcm2712-rpi-5-b.dtb
ラズパイ5から拝借
問題2: データを解析して、Bluetoothがどこにぶら下がっているか、わかりやすく
表示してください
出力の例 a -&gt; b -&gt; c -&gt; bluetooth
コマンドを使ってテキストに変換します
結構わかりやすいデータなのでこれ以上はヒントなしで
第77回シェル芸勉強会
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/D7Y46D19EM.jpg)

解答例
準備
sudo apt install device-tree-compiler
答え
dtc -I dtb -O dts bcm2712-rpi-5-b.dtb 2&gt; /dev/null | grep &#039;{$&#039;
| awk -F &#039;\t&#039; &#039;{for(i=1;i&lt;=3;i++)a[i]=$i==&quot;&quot;?a[i]:$i;for(i=1;i&lt;=3;i++)$i=a[i] ;print}&#039;
| grep blue | sed &#039;s/{/-&gt;/g&#039; | sed &#039;s/-&gt;$//&#039;
/ -&gt; soc -&gt; serial@7d50c000 -&gt; bluetooth
第77回シェル芸勉強会
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/VENYZ62DJ8.jpg)

デバイスツリーに書いてあるメモリの割り当て
64bit、32bit入り乱れてややこしい
dtc -I dtb -O dts bcm2712-rpi-5-b.dtb | less
・・・
/ {
・・・
#address-cells = &lt;0x02&gt;; &lt;-番地は32bitの数値2つで表現（64bit）
#size-cells = &lt;0x01&gt;;
&lt;-メモリのサイズは32bitの数値1つで表現
・・・
soc {
compatible = &quot;simple-bus&quot;;
#address-cells = &lt;0x01&gt;;
#size-cells = &lt;0x01&gt;;
ranges = &lt;0x7c000000 0x10 0x7c000000 0x4000000&gt;;
・・・ # ↑子の番地 ↑2個で親の番地 ↑サイズ
serial@7d50c000 { #↑子の 32bitの番地 0x7c000000 を親の 64bit の番地 0x107c000000 に対応づけ
compatible = &quot;brcm,bcm7271-uart&quot;;
・・・
bluetooth {
・・・
第77回シェル芸勉強会
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/Y79PZL18E3.jpg)

ACPIテーブル
これも木構造でハードウェアのデバイスの構成を記述したもの
様々なテーブルで構成される
RSDT（root system description table）から辿っていく
64bitの場合はXSDT（extended system description table）
ファームウェアやOSが問い合わせるための関数が中心
たぶんLinux的な発想ならもっと静的になってるんじゃなかろうか
電源管理（特にサスペンド機能が重要なノートPC）のためにできた
発起人: Intel（CPU No.1）、東芝（ノートPC No.1）、Microsoft（商用OS
No.1）。1997年当時
第77回シェル芸勉強会
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/G78D1X4Z7D.jpg)

読み出し方
/sys
から持ってくる
ueda@x1gen13:/tmp
sudo apt install acpica-tools #準備
ueda@x1gen13:/tmp
mkdir acpi
ueda@x1gen13:/tmp
cd acpi/
ueda@x1gen13:/tmp/acpi
cp /sys/firmware/acpi/tables/* ./
ueda@x1gen13:/tmp/acpi
sudo rsync -av /sys/firmware/acpi/tables/* ./
ueda@x1gen13:/tmp/acpi
sudo iasl -d *
ueda@x1gen13:/tmp/acpi
ls *.dsl
APIC.dsl DMAR.dsl FACS.dsl MSDM.dsl
SSDT10.dsl SSDT15.dsl SSDT2.dsl
BATB.dsl DSDT.dsl FPDT.dsl NHLT.dsl
SSDT11.dsl SSDT16.dsl SSDT20.dsl
BGRT.dsl DTPR.dsl HPET.dsl PHAT.dsl
SSDT12.dsl SSDT17.dsl SSDT21.dsl
DBG2.dsl ECDT.dsl LPIT.dsl SDEV.dsl
SSDT13.dsl SSDT18.dsl SSDT22.dsl
DBGP.dsl FACP.dsl MCFG.dsl SSDT1.dsl SSDT14.dsl SSDT19.dsl SSDT23.dsl
SSDT24.dsl
SSDT25.dsl
SSDT26.dsl
SSDT3.dsl
SSDT4.dsl
SSDT5.dsl
SSDT6.dsl
SSDT7.dsl
SSDT8.dsl
SSDT9.dsl
TPM2.dsl
UEFI.dsl
WSMT.dsl
他、 acpidump というコマンドを使う方法も
一部のテーブルは出てこない模様
第77回シェル芸勉強会
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/L7LMQ861JR.jpg)

ACPIテーブルの読み方
のようなパス（ACPIパス）
\ : ルート、 PC00 : PCIバス、 XHCI : USBホストコントローラ、 RHUB : ルート
ハブ、 HS06 : USBポート（6番）、 BTTM : Bluetoothモジュール
MMIOの番地の範囲
_CRS （current resource settings）という関数から得られる
番地が関数にベタ書きされていない限りそこだけ読んでも分からない
（つらい）
ACPIテーブルの他のどこかにある（かも。未調査）
問題3: HPET（high precision event timer）というデバイスの番地の範囲と、接続場
所を特定してください
ワンライナーというよりコマンドを使って調査を
\_SB_.PC00.XHCI.RHUB.HS06.BTTM
第77回シェル芸勉強会
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/4EMY1655EW.jpg)

解答例
grep HPET *.dsl
DMAR.dsl:[088h 0136 001h]
Device Scope Type : 04 [Message-capable HPET Device]
DSDT.dsl:
Device (HPET) /* この下にありそう */
・・・
ueda@x1gen13:/tmp/acpi
less DSDT.dsl
・・・
Device (HPET)
{
Name (_HID, EisaId (&quot;PNP0103&quot;) /* HPET System Timer */) // _HID: Hardware ID
Name (_UID, Zero) // _UID: Unique ID
Name (BUF0, ResourceTemplate ()
//BUF0というデータを定義
{
Memory32Fixed (ReadWrite,
0xFED00000,
// Address Base
***番地の始点***
0x00000400,
// Address Length ***長さ***
_Y3E)
})
・・・
Method (_CRS, 0, Serialized) // _CRS: Current Resource Settings
{
If (HPTE)
{
CreateDWordField (BUF0, \_SB.PC00.LPCB.HPET._Y3E._BAS, HPT0) // _BAS: Base Address ***接続の情報（\_SB.PC00.LPCB.HPET）***
HPT0 = HPTB /* \HPTB */
}
Return (BUF0) /* \_SB_.PC00.LPCB.HPET.BUF0 */ //BUF0を返す
}
}
第77回シェル芸勉強会
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/PER9LP3ZJ9.jpg)

MMIOの番地の伝達
OSはメモリをたくさん使う前にデバイスが使う番地を把握しないといけない
データをその番地に置けないので
どうやって早期に把握しているか: BIOSなどからもらう
問題4: 番地の情報をもらっている形跡、そのあと番地をOSがいじっている形
跡を探してください
第77回シェル芸勉強会
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/P7XQW341EX.jpg)

解答例（1/2）
「 BIOS 」で dmesg の出力に検索 先頭のほうにメモリの受け渡しのログ
ueda@x1gen13:~
sudo dmesg | grep BIOS
[
0.000000] BIOS-provided physical RAM map:
[
0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009efff]
[
0.000000] BIOS-e820: [mem 0x000000000009f000-0x00000000000fffff]
[
0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000004f2fefff]
[
0.000000] BIOS-e820: [mem 0x000000004f2ff000-0x0000000051ffffff]
[
0.000000] BIOS-e820: [mem 0x0000000052000000-0x0000000086e2efff]
[
0.000000] BIOS-e820: [mem 0x0000000086e2f000-0x000000008d32efff]
[
0.000000] BIOS-e820: [mem 0x000000008d32f000-0x000000008df2efff]
[
0.000000] BIOS-e820: [mem 0x000000008df2f000-0x000000008dffefff]
[
0.000000] BIOS-e820: [mem 0x000000008dfff000-0x000000008dffffff]
[
0.000000] BIOS-e820: [mem 0x000000008e000000-0x00000000a07fffff]
[
0.000000] BIOS-e820: [gap 0x00000000a0800000-0x00000000bfffffff]
[
0.000000] BIOS-e820: [mem 0x00000000c0000000-0x00000000cfffffff]
[
0.000000] BIOS-e820: [gap 0x00000000d0000000-0x00000000fed1ffff]
[
0.000000] BIOS-e820: [mem 0x00000000fed20000-0x00000000fed7ffff]
[
0.000000] BIOS-e820: [gap 0x00000000fed80000-0x00000000ffffffff]
[
0.000000] BIOS-e820: [mem 0x0000000100000000-0x00000001044fffff]
[
0.000000] BIOS-e820: [mem 0x0000000104500000-0x000000085f7fffff]
[
0.000000] efi: ...
第77回シェル芸勉強会
System RAM
device reserved
System RAM
device reserved
System RAM
device reserved
ACPI NVS
ACPI data
System RAM
device reserved
device reserved
device reserved
device reserved
System RAM
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/37K9VYZM7D.jpg)

解答例（2/2）
その後のOSによるメモリの操作（ [mem で検索をかければおそらく全部出てく
る）
sudo dmesg | grep &#039;\[mem&#039;
[
0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009efff] System RAM
・・・
[
0.000000] e820: remove [mem 0xc0000000-0xcfffffff] device reserved
[
0.000007] e820: update [mem 0x00000000-0x00000fff] System RAM ==&gt; device reserved
[
0.000008] e820: remove [mem 0x000a0000-0x000fffff] System RAM
[
0.004351] e820: update [mem 0x7f0e1000-0x7f0e1fff] System RAM ==&gt; device reserved
・・・
[
1.390688] pci 0000:00:15.0: BAR 0 [mem 0x202c000000-0x202c000fff 64bit]: assigned
[
1.390708] pci 0000:00:15.3: BAR 0 [mem 0x202c001000-0x202c001fff 64bit]: assigned
[
1.390728] pci 0000:00:1f.5: BAR 0 [mem 0xa0800000-0xa0800fff]: assigned
・・・
第77回シェル芸勉強会
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/LJ3WM9D2J5.jpg)

PCI Express（PCIe）
PCIバスの新しいやつ（雑）
バスといってるのにシリアライズされている
1つのデバイスでシリアライズされた線（レーン）を複数使える
PCI Express x1, x2, x4, x8, x16, ...
おじさんすぎてよく分からんけどGPUはx16にささってるらしい
おじさんすぎてよく分からないので速度はネットで調べてくだしあ
CPUのチップ中のルートコンプレックスというところから出ている
CPUとDRAMとPCIeがつながっているところ
昔のノースブリッジ
PCIeにぶら下がっているデバイスはコンピュータからは未知
番地の割当どうする？
第77回シェル芸勉強会
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/8JDK6GP6EG.jpg)

PCIeのデバイスの確認方法
lspci
を使う
lspci -tv
-[0000:00]-+-00.0 Intel Corporation Device 6400
+-02.0 Intel Corporation Lunar Lake [Intel Arc Graphics 130V / 140V]
・・・
+-0d.0 Intel Corporation Lunar Lake-M Thunderbolt 4 USB Controller
・・・
+-1c.0-[1c]-+-1c.4-[04]----00.0 Sandisk Corp SN8000S NVMe SSD
+-1f.0 Intel Corporation Device a807
+-1f.3 Intel Corporation Lunar Lake-M HD Audio Controller
+-1f.4 Intel Corporation Lunar Lake-M SMbus Controller
\-1f.5 Intel Corporation Lunar Lake-M SPI Controller
番号
、 [1c] 、 [04] 、...: ドメイン番号（4桁）とバス番号（2桁）
1c.0 など: デバイス番号とファンクション番号
23
[0000:00]
第77回シェル芸勉強会


# Page. 24

![Page Image](https://bcdn.docswell.com/page/VEPKY31Z78.jpg)

各デバイスの情報
例: WiFiのコントローラー
sudo lspci -v -s 00:14.3
00:14.3 Network controller: Intel Corporation BE201 320MHz (rev 10)
Subsystem: Intel Corporation Device 00e0
Flags: bus master, fast devsel, latency 0, IRQ 18, IOMMU group 10
Memory at 204fd5c000 (64-bit, non-prefetchable) [size=16K]
#番地の割り当て
#non-prefetchable: 普通のメモリのように先読みするとレジスタの状態変わるからヤメロという意味
・・・これ以下はまたあとで・・・
実際の番地の割り当てと一致
sudo cat /proc/iomem | grep 204fd5c000
204fd5c000-204fd5ffff : 0000:00:14.3
204fd5c000-204fd5ffff : iwlwifi
ただしこの番地は最初から決まっているわけではない
仕組みを覗いていきましょう
第77回シェル芸勉強会
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/27VVG4YM7Q.jpg)

コンフィギュレーション領域の観察
でコンフィギュレーション領域の最初の64バイトを出力可能
最初の64バイト: ヘッダーの領域
lspci -x
sudo lspci -x -s 00:14.3
00:14.3 Network controller: Intel Corporation BE201 320MHz (rev 10)
00: 86 80 40 a8 06 04 10 00 10 00 80 02 00 00 80 00
#ベンダIDとか
10: 04 c0 d5 4f 20 00 00 00 00 00 00 00 00 00 00 00
#BAR0〜3
20: 00 00 00 00 00 00 00 00 00 00 00 00 86 80 e0 00
#BAR4〜5他
30: 00 00 00 00 c8 00 00 00 00 00 00 00 ff 03 00 00
から バイト: BAR0〜5
BAR: ベースアドレスレジスタ
64bitの場合は0と1、2と3、4と5をペアで使う
最初から番地が決まっているわけではなく、BIOSやOSが書き込む
0x10
第77回シェル芸勉強会
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/5JGL819X7L.jpg)

問題5
小問1
なにかのデバイス、ファンクションについて、BAR0〜5に記録されている2進
数を次例のように出力してください（リトルエンディアンです）
BAR1 00000020 BAR0 4fd5c004 # 下の桁の余計なデータはフラグです。小問2、3が終わったら調査を
BAR3 00000000 BAR2 00000000
BAR5 00000000 BAR4 00000000
小問2
すべてのPCIeのデバイスについて上記のように出力してください。ただし、各
行の頭にバス、デバイス、ファンクション番号をつけてください
小問3（おまけ）
BARの数値自体には使う番地の範囲の情報がありませんが、コンピュータは
BARから特定できます。どういうことでしょう？
第77回シェル芸勉強会
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/47QY9DW5EP.jpg)

解答例（小問1）
sudo lspci -x -s 00:14.3 | sed -n /[12]0:/p | sed &#039;s/.*: //&#039; | fold -w12 | head -n 6
| awk &#039;{printf &quot;BAR&quot;(NR-1)%6&quot; &quot;; for(i=4;i&gt;=1;i--)printf $i;print &quot;&quot;}&#039; | xargs -n 4
| awk &#039;{print $3,$4,$1,$2}&#039;
BAR1 00000020 BAR0 4fd5c004 #開始の番地: 0x204fd5c000 と読める
BAR3 00000000 BAR2 00000000
BAR5 00000000 BAR4 00000000
末尾の （ 0100 ）: フラグ
0 : プリフェッチ不可 / 10 : 64bit / 0 : MMIOの番地
dmesg の出力から BAR で検索すると設定の状況を確認できる
[
sudo dmesg | grep BAR | grep 14.3
0.269733] pci 0000:00:14.3: BAR 0 [mem 0x204fd5c000-0x204fd5ffff 64bit]
第77回シェル芸勉強会
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/KE4WXZKVJ1.jpg)

解答例（小問2）
lspci | awk &#039;{print $1}&#039; | while read d ; do sudo lspci -x -s $d | sed -n /[12]0:/p | sed &#039;s/.*: //&#039;
| fold -w12 | head -n 6 |awk &#039;{printf &quot;BAR&quot;(NR-1)%6&quot; &quot;; for(i=4;i&gt;=1;i--)printf $i;print &quot;&quot;}&#039;
| xargs -n 4 | awk &#039;{print &quot;&#039;$d&#039;&quot;,$3,$4,$1,$2}&#039; ; done
00:02.0 BAR1 00000020 BAR0 4e00000c #フラグ: 1100（先頭の1はプリフェッチ可の意味）
00:02.0 BAR3 00000020 BAR2 0000000c
00:02.0 BAR5 00000000 BAR4 00000000
・・・
00:07.0 BAR1 00000000 BAR0 00000000 #ブリッジなのでメモリを持たない（別の情報が書いてある）
00:07.0 BAR3 00002020 BAR2 00492000
00:07.0 BAR5 2bf11001 BAR4 bc10b000
・・・
00:1f.4 BAR1 00000020 BAR0 4fd60004
00:1f.4 BAR3 00000000 BAR2 00000000
00:1f.4 BAR5 00000000 BAR4 0000efa1 #ポートマップI/Oの番地指定（0xEFA0）
00:1f.5 BAR1 00000000 BAR0 a0800000 #0000: プリフェッチ不可、32bit、MMIO
00:1f.5 BAR3 00000000 BAR2 00000000
00:1f.5 BAR5 00000000 BAR4 00000000
・・・
第77回シェル芸勉強会
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/L71YNRX4JG.jpg)

PCIデバイスへの番地の割り当て（小問3）
BIOSなどがデバイスを列挙し、対応するコンフィグレーション領域のBARに開始
の番地を書き込む
OSもBARをいじれる
番地の範囲の要求方法（メモリがデバイス側にあるからできる芸当）
実はBARのいくつかのビットは書き込み禁止で0に固定してある
BIOSなどがBARに1を埋めて読み出す 0の場所で範囲が分かる
ビット目からフラグ直前の ビット目: バイト分の幅が必要
参考: https://osdev.jp/wiki/PCI-Memo
第77回シェル芸勉強会
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/G7WG41NZE2.jpg)

割り込み
基本的にCPUが割り込みピンから受付
基本は「割り込みたい」という信号しか受け付
けない
データはMMIOやポートマップドI/Oで
割り込みピン（基本）
マイコン: CPUから直接何本が出ている
PC/AT互換機: 割り込みコントローラが代理で何
本も持っている（例: 右図）
最近: CPU多い。デバイスもたくさん&amp;抜き差し
とりあえず最近のx86について次ページからお
さえていきましょう
第77回シェル芸勉強会
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/4JZL2P3LE3.jpg)

割り込みの観察
/proc/interrupts
cat /proc/interrupts
CPU0
CPU1
1:
0
0
8:
0
0
9:
82149
0
12:
0
0
14:
0
0
27:
0
0
30:
0
0
・・・
にカウンタ
CPU2
0
0
0
0
0
0
19117577
CPU3
0
0
0
1745040
0
0
0
...
...
...
...
...
...
...
...
CPU7
0 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
638653 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
1-edge
8-edge
9-fasteoi
12-edge
14-fasteoi
27-fasteoi
30-fasteoi
i8042
rtc0
acpi
i8042
INTC105D:00, INTC105D:01, （略）
idma64.0, i2c_designware.0
idma64.1, i2c_designware.1
問題6: /proc/interrupts の特定の行の割り込みについて、割り込みの秒速の回
数を出力してください（計測は3秒ほど）
ワンライナーで生じる割り込みについては気にしないことにします
第77回シェル芸勉強会
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/YE6WVMXMEV.jpg)

解答例
IRQ=LOC ; cat &lt;( cat /proc/interrupts | awk &#039;$1==&quot;&#039;$IRQ&#039;:&quot;&#039;
| awk &#039;{for(i=2;i&lt;=9;i++)s+=$i; print s}&#039; ) &lt;( sleep 3 ;cat /proc/interrupts
| awk &#039;$1==&quot;&#039;$IRQ&#039;:&quot;&#039; | awk &#039;{for(i=2;i&lt;=9;i++){s+=$i;$i=&quot;&quot;}; print s, $0}&#039; )
| xargs | awk &#039;{print ($2-$1)/3&quot;回/s&quot;, $0}&#039;
1639.67回/s 225869280 225874199 LOC: Local timer interrupts
第77回シェル芸勉強会
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/GE5MDZXQE4.jpg)

割り込みの方式（1/2）
番号の小さいほうはI/O APICが受け付ける割り込み
cat /proc/interrupts
CPU0
CPU1
1:
0
0
8:
0
0
9:
82149
0
12:
0
0
14:
0
0
27:
0
0
30:
0
0
・・・
CPU2
0
0
0
0
0
0
19117577
CPU3
0
0
0
1745040
0
0
0
...
...
...
...
...
...
...
...
CPU7
0 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
638653 IR-IO-APIC
0 IR-IO-APIC
0 IR-IO-APIC
1-edge
8-edge
9-fasteoi
12-edge
14-fasteoi
27-fasteoi
30-fasteoi
i8042 #キーボード
rtc0 #時計
acpi #なんだっけ？
i8042 #↓たぶん古いPCIの割り込み機能
INTC105D:00, INTC105D:01, （略）
idma64.0, i2c_designware.0
idma64.1, i2c_designware.1
APIC: advanced programmable interrupt controller
現行の割り込みコントローラ
IO-APIC: I/O APIC
昔ながらの割り込みを受け付ける部分（詳しい記事）
IR: interrupt remapping
仮想化の仕組みが間にいてリマッピングしているという意味
第77回シェル芸勉強会
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/97298RXWJR.jpg)

割り込みの方式（2/2）
そのあとはPCIe関係の割り込み
120:
・・・
130:
138:
146:
147:
・・・
163:
164:
179:
180:
181:
・・・
0
0
0
0
0
... 0 DMAR-MSI
1-edge
dmar1
0
0
5317
0
0
0
0
5303
0
0
0
0
0
77769
0
0
0
0
0
0
... 0 IR-PCI-MSI-0000:00:0d.0
... 0 IR-PCI-MSI-0000:00:14.0
... 0 IR-PCI-MSIX-0000:00:0d.2
... 0 IR-PCI-MSIX-0000:00:0d.2
0-edge
0-edge
0-edge
1-edge
xhci_hcd
xhci_hcd
thunderbolt
thunderbolt
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
5325
0
34
0
39811
0
5300
0
0
0
... 0 IR-PCI-MSIX-0000:00:0d.3
... 0 IR-PCI-MSIX-0000:00:0d.3
... 0 IR-PCI-MSI-0000:00:16.0
... 0 IR-PCI-MSIX-0000:04:00.0
... 0 IR-PCI-MSIX-0000:04:00.0
0-edge
1-edge
0-edge
0-edge
1-edge
thunderbolt
thunderbolt
mei_me
nvme0q0
nvme0q1
MSI / MSI-X: message signaled interrupt
MMIOされたレジスタの特定の番地にフラグを立てることで割り込みを入
れる方式
I/O APICではなく、各CPU（にあるlocal APIC）に直接届く
lspci での確認方法）
設定はコンフィグレーション領域に（次ページに
34
第77回シェル芸勉強会


# Page. 35

![Page Image](https://bcdn.docswell.com/page/DJY46D897M.jpg)

MSI / MSI-Xの確認方法
コンフィグレーション領域の「ケイパビリティー」に記述される
sudo lspci -vvv -s 00:14.3
00:14.3 Network controller: Intel Corporation BE201 320MHz (rev 10)
・・・
Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
#使われてない
Address: 0000000000000000 Data: 0000
・・・
Capabilities: [80] MSI-X: Enable+ Count=32 Masked- #最大32個（/proc/interruptsを見るとコアに1つずつ割り当てしている）
Vector table: BAR=0 offset=00002000
#割り込みベクタテーブル（割り込み時の処理のポインタ）の場所
PBA: BAR=0 offset=00003000
・・・
Kernel driver in use: iwlwifi
Kernel modules: iwlwifi
第77回シェル芸勉強会
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/V7NYZ6QDE8.jpg)

まとめ
デバイスについてちょっと齧った
おもにMMIOまわりと割り込みちょっと
新しい（特にUEFIまわりの）情報が少なく勉強が難しい
カーネルが立ち上がる前のログがわずか
本が少ない・仕様書読むしかない
勉強方法？
OS自作、デバイスドライバ作成の本を読む
技術評論社から今度出る自作OS本の改訂版が参考になりそう
https://www.amazon.co.jp/dp/429715921X
Kindleの自費出版のも探したけどやっぱり出版社通さないと・・・
LLMに聞く（検証が必要だが結構むずかしい）
第77回シェル芸勉強会
36


