xv6のuserland側を拡張しようと、最近musl(https://www.musl-libc.org/)のsourceを読んでいて、なかなか美しいので、備忘録的に何回かに分けてlogを残しておく。
先ず、musl自体なんだけど、軽量glibcの一種で,特徴として
1.単一のshared libraryになる.
->glibcやbionicだとlibc.soの他に,ld.so,libm.so...に分割され、必要に応じてdlopen()されるが、muslの場合,libc.soに纏めてくれる。 なお、静的linkも可能な様で、その場合は、単一にするメリットもないので、数個生成される.
2.docker向けcontainerのalpine linuxで採用.
->alpine imageのcontainer上でbuildして簡単にhack
3.source code量が少ない.
->buildが速い.
つまりsource code readingには良い教材という意味.
自分は以下の様なcycleでやってる。
sourceのclone
docker run --privileged -v /source_full_path:/root -it alpine /bin/sh
(host側にsourceを残し,container上にbind mount)apk add gcc make
(必要library install)cd ./root && make
(muslをbuild)/root/lib/libc.so 実行file名(e.g. a.out)
(buildしたmuslのlibc.soでprogramをexec)(libraryまたはprogramをhost側で任意に変更し,4 or 5に戻る)
5の共有libraryを直接実行することにより,defaultのmuslではなく,buildしたmuslで引数で与えたprogramの実行が可能.また、組み込みcommand(e.g. /bin/ls)もmuslを利用しているので、実行fileはそれらでもよし.
共有libraryの直接実行は,通常実行と一部sequenceが異なるが,便利なdebug optionもある(glibcのものよりは少なめ).詳しくは、
/root/lib/libc.so --help
を参照して下さい.
基本,読者が一緒にdebugしてくれながら読むことを想定して書きます.
とはいっても、あまり真面目に連載するつもりはないのだけれど..
libcは、細かいネタの集合と見えがち(sys/..を除いたheaderだけでも117個)なので,入り口の使い方から入るのではなく、 src以下のdir(https://github.com/bminor/musl/tree/master/src)42個(でもまだ多いのだけれど..),或いはsystem callを見出しにして、なんとなくまとめていくつもり.
とりあえずsrc/から書くべしテーマを推察してみる. majorどころだと,
- ldso/(start up routine , dynamic linkのお話)
- malloc/(別mallocとの比較/performance分析)
- thread/(tlsとかthread_attrとかfutexとか)
- signal/(あまり知られてない諸々細かいこと)
- ipc/(kernel実装と絡めたお話)
その他だと、今の自分の知識だと、こんなの知ってる!?的な投稿になってしまいがちなのだが、できるだけ統合的に書くつもり. なお、投稿はあくまで自分の備忘録(勉強log)なので、読者の理解に最適化されているかはあまり考えてません.