Slide 1

Slide 1 text

Linuxカーネルソースの減量 Mar. 24, 2018 Satoru Takeuchi Twitter id: satoru_takeuchi 1

Slide 2

Slide 2 text

背景 ● Linuxカーネル屋さんを増やしたい ● 新規参入障壁の1つ: ソースがデカい ○ v4.15の場合、.cファイルだけで1775.8万行 ● ソースの減量によって壁を低くする ○ コア機能(ブートしてshellが立ち上がる程度)以外のソースを削除 2

Slide 3

Slide 3 text

減量方法 ● 第一段階: 設定項目の最小化&不要ソースの削除 ● 第二段階: 残ったソースの直接編集 3

Slide 4

Slide 4 text

第一段階: 設定項目の最小化&不要ソースの削除(by @liva_jy) 1. コア部分以外の設定項目を全て無効化 2. ビルド 3. .cファイルのうち、ビルド後に対応する.oファイルが無いものを削除 ○ 「foo.cをビルドしてたらfoo.oがあるはず」理論 4. 再ビルド 5. 全エラーについて、誤って消したソースを復元 4

Slide 5

Slide 5 text

どこから手を付けるか 5 サブディレクトリ名 役割 総行数 [万行] 全体に占める割合 [%] drivers デバイスドライバ 1199.0 67.5 arch アーキテクチャ依存部分 169.3 9.5 fs ファイルシステム 111.3 6.2 net ネットワークスタック 93.9 5.2 sound サウンド関連 86.9 4.8 その他 --- 115.3 6.4 上から順が効率的

Slide 6

Slide 6 text

デバイスドライバ(drivers/)の減量 ● 最小限のドライバ以外すべて削除 ● 残ったもの ○ 端末ドライバ: 入出力に必要 ○ 時刻関連ドライバ: タイマー処理に必要 ○ その他少々 6 96%カット

Slide 7

Slide 7 text

アーキテクチャ依存部分(arch/)の減量 ● 32個中31個のアーキテクチャを削除 ● 残るはx86/x86_64のみ 7 95%カット

Slide 8

Slide 8 text

ファイルシステム(fs/)の減量 ● 72個中71個のファイルシステムを削除 ● 残るはramfsのみ ○ メモリベース。rootfsに使用 8 97%カット

Slide 9

Slide 9 text

その他に抹殺した主なコード ● ネットワークスタック(net/) ● サウンド関連(sound/) ● ブロックデバイス共通処理(block/) ● 仮想化(virt/) ● セキュリティ(security/) ● System V プロセス間通信(ipc/) ● SMP, cgroupsなど 9 70%カット

Slide 10

Slide 10 text

減量後カーネルができること ● DEMO 10

Slide 11

Slide 11 text

第二段階: 残ったソースの直接編集(筋肉プレイ) A. 「無くても動く」機能用のコード断片を削除 ○ Cソースを行数の多い順番に並べて、削れそうな箇所を適当に選ぶ B. 無効にした設定項目に関する#ifdef内のコード断片を削除 ○ 設定項目”FOO”に対して”CONFIG_FOO”マクロが存在 ○ “#ifdef COFIG_*”を登場回数が多い順に並べて優先順位をつける 11

Slide 12

Slide 12 text

性能測定用コード(2.9万行)の減量 ● 明らかに必須ではない ● x86には問答無用で組み込まれている 12

Slide 13

Slide 13 text

性能測定用コード(2.9万行)の減量 ● 明らかに必須ではない ● x86には問答無用で組み込まれている 13 a. 関連コードを全削除 b. ビルド c. ptrace()周りのコードをコンパイルできなくなった d. ptrace()がENOSYSを返すよう手作業で改造 e. ptrace()周りを含めて合計3.1万行減量!

Slide 14

Slide 14 text

プロセススケジューラ用コード(2.5万行)の減量 ● 各プロセスは1つのスケジューリングクラスに属する ○ fair_sched_class: 通常のプロセス ○ rt_sched_class: 通常のプロセスより常に優先動作するプロセス ○ dl_sched_class: デッドライン付き処理用のプロセス 14

Slide 15

Slide 15 text

プロセススケジューラ用コード(2.5万行)の減量 ● 各プロセスは1つのスケジューリングクラスに属する ○ fair_sched_class: 通常のプロセス ○ rt_sched_class: 通常のプロセスより常に優先動作するプロセス ○ dl_sched_class: デッドライン付き処理用のプロセス 15 a. Fair_sched_classを除くクラスのコードを全削除 b. ビルド c. スケジューラ共通コードがコンパイルできなくなった d. sched_setscheduler()がENOSYSを返すよう手作業で改造 e. 1.3万行減量!

Slide 16

Slide 16 text

“#ifdef CONFIG_*”内のコードを削除 ● 減量対象は残るコード中再頻出(117箇所)のCONFIG_SMP 16

Slide 17

Slide 17 text

“#ifdef CONFIG_*”内のコードを削除 ● 減量対象は残るコード中再頻出(117箇所)のCONFIG_SMP 17 a. 該当コードを手作業で削除 ■ #ifdefのネスト、#elifの存在等を考えると自動化しづらい b. 1.2万行減量!

Slide 18

Slide 18 text

ここで心が折れたので終了 ● 以後の筋肉プレイで減らせる行数は一回ごとに高々1000行程度 ● 1プレイに数十分以上かかる 18

Slide 19

Slide 19 text

最終結果 19 設定項目削減 筋肉プレイ 総行数 [万行] 98%カット 1776万行 34万行

Slide 20

Slide 20 text

組成 20

Slide 21

Slide 21 text

おわりに ● 「Linuxカーネルはデカ過ぎて怖い」 -> 「思ってたより怖くない」 ● 各種ソース読解技術を組み合わせるとさらに怖くない ○ 単一機能の理解に絞る ○ エラー処理などの枝葉のコードはとりあえず無視 ○ デバッガ、トレーサ、プロファイラなどを使った動作確認 ● 具体的にどうすれば上記技術を得られる? ○ 現状は慣れ、および経験者のアドバイスに頼ることが多い => スケールしない ○ 記事/同人誌執筆ネタ? 21

Slide 22

Slide 22 text

参考 ● 本取り組みの成果物 ○ https://github.com/satoru-takeuchi/minimal-linux ● 第一段階の詳しい流れ ○ http://raphine.hatenablog.com/entry/2018/02/09/153356 ● 「小さいLinux環境の作り方」 by @fadis_ ○ ソース行数ではなくバイナリサイズ削減が目的 ○ https://speakerdeck.com/fadis/xiao-sailinuxhuan-jing-falsezuo-rifang 22