livaの雑記帳

minimalなlinuxを作りたい、と思ったんだ

以下のツイートが結構反響があったので、どんな事をやったのかまとめておく。

 

元ネタはsatさんのこのツイート。

 

僕はカーネルには詳しくはないので、中のソースを弄って素朴な実装にリプレースする、みたいな事はできないのだけど、kernel configでminimalな構成にして、不要なファイルを消しまくる、みたいな筋肉プレーならできる。

不要なファイルを消しただけと言えばそうなんだけど、ある程度の意味はあると思っていて、

  • ソースが少ないから検索とかもしやすいし、
  • ファイル数が減ってると取扱いやすいし、
  • 無数のファイルを見て「自分にはOSを理解するのなんて到底無理なんじゃないか」と落ち込む事もなくなるし、
  • とりあえず片っ端から全部コードを読む、みたいな筋肉プレーもやりやすくなる。

 

というわけで、やってみた。

 

まずminimalなconfigはこれを参考に少し機能を削ってる。カーネル4.15

qiita.com

デバドラはシリアルのみ。単純!

 

rootfsはbusyboxで。これは以下を参考にした。

nullpo-head.hateblo.jp

 

あとは使ってないディレクトリやファイルを削除していく。

分かりやすいのだとdriversの中で片っ端から消していける。

注意点としては、MakefileやKconfigでサブディレクトリを掘ろうとするので、それを消す。

 

これはテクニック的な話になるのだけど、修正前のをgitでコミットしておいて、適当にディレクトリを消した後、コンパイルエラーが出たらgit checkout HEAD <dir>で復活させる、みたいなのを繰り返すと簡単にできる。

 

次に、ディレクトリをまるごと消す事はできないけど、中の.cファイルは消せる、みたいなのを消していく。

 

一回コンパイルしてオブジェクトを作った後で、以下のスクリプトを対象ディレクトリの中で走らせる。

#!/bin/sh

for file in `\find . -maxdepth 1 -type f -name "*.c"`; do

    if [ ! -e `echo $file | sed 's/\.[^\.]*$/\.o/'` ]; then

        echo $file

        rm $file

    fi

done

 *.cファイルを眺めて、 その*.oが存在しなければ削除してしまう、というだけ。

linuxは時々.cファイルをインクルードしているので、これだと余計に削除してしまう事もあるが、その時もgit checkout HEAD <file>すればよろし。

 

とまあそんな感じでダイエットしたのが、最初のツイート内にもリンクを貼ったこのリポジトリ

 

github.com

 

READMEにも書いてあるけど、

 

 

制約は、

  • x86_64 QEMUでしか動かない
  • デバドラもシリアルしかない。
  • ネットワークやFS(ramfs以外)もない

 

future workは、

  • *.hファイルはまだ整理してないし、configのチューニングもまだ改善の余地がある。
  • 中のコードはまだあんまり弄れてないので、中をちゃんと読めばもっと削れるし、素朴な実装にリプレースしてもっとダイエットしていかないといけない。

 

みたいな感じ。

これからチマチマコードを書き換えてlinuxの勉強したいな、と思いたったので、やってみたのでした。