低レイヤーの歩き方
この記事は Kobe University Advent Calendar25日目の記事です。
低レイヤー技術(後述)をこれから学びたい人向けの入門記事です。 自身の経験を踏まえ、より多くの人達にこのレイヤーに興味を持ってほしくて書きました。
決して卒論がやばくてAdvent calendarのネタが作れなかったわけでは(ry
なぜこんな記事を書いたか
いわゆるシステムプログラミングのような低レイヤー(と言って差し支えない)ジャンルって一体何から始めれば良いのかいまいちピンと来ないし、何が面白いのかも分からないと思われている事が多いと思います。
にもかかわらず低レイヤーの魅力や学び方の指針みたいな物を示した、いわゆる入門記事ってかなり少ないんですよね。
本記事はこれからシステムプログラミングを始めたい方や、既にかじってみたが中々先が見えてこない、将来何の役に立つのか不安という方達に読んでいただけると幸いです。
とは言え私自身も真面目に勉強し始めてまだ2年程の若造です。こういう記事を書くには時期尚早かなとも思いましたが、
まあ、ポエムってその気になった時しか書けないんです...
緩い目で、こういう学習方法もあるのか〜程度で見ていただければと。
1. 目次
本記事では以下のようなテーマについて、参考資料などを掲示しながら学習方法(の一例)を示していきます。
(どこからが"低"レイヤーなのかについては人それぞれ違った意見があると思いますが、とりあえず今回は以下に示すようなジャンルを低レイヤーと呼ぶことにします)
技術的な入門記事ではない事に注意してください。
※目次の欄をクリックすると各章に飛ぶこともできます。
2. そもそもハマるきっかけは
システムソフトウェアを初め、低レイヤー技術というのはいわゆる縁の下の力持ち的存在であり際立って目立つようなシステムではありません。
まあ最初は誰もOSとかコンパイラなんて自力で作れる物なんて思ってもいないし、Linuxとかgccみたいなバカでかい複雑プロジェクトなんて携わろうとも
思わないわけですが、どういうきっかけでこの道に引きずり込まれるかというと、多くの場合は既に引きずり込まれた人達が
作った物や、書いた書籍、ページなどを見てつられてハマるケースが多いのかなぁと思います。(ああ簡単なOSぐらいなら案外サクッと作れちゃうのかと拍子抜けしたりとか)
私の場合は2年前にセキュリティキャンプという所に行って、OSやらVMやら作っている人達を見てハマりました。当時は辛うじてC言語が書ける程度でintelのCore i7とか第4世代とか聞いても何それ状態だったので、
まあ何をやってるのかはさっぱり分かりませんでしたが、衝撃は大きかったですね。そういう意味ではこの記事も学習の方針決めの参考にして頂いても良いですし、
起爆剤として何らかの刺激になって頂くだけでも嬉しいです
あとこの記事はロードマップ的な物ではなく、辞書的に引いて頂くことを想定しています。
つまりこれから書いていく参考文献やら資料やらは、自分がやりたい事に必要になったその時に適時参考にしていただければと思います。
(愚直に頭から順番にやっていくのはあまりよくなくて、この記事は私がその時々で、何となくやりたいと思ったり研究で必要になったりした際に読みこんだ資料を掲示しているだけです。)
3. 大雑把な学習方法
学習方法といっても人それぞれなので自分に合うやり方で良いと思うんですが、まあどのジャンルをやるにせよとにかく手を動かして自分で作ってみるのが一番良いと思います。
システムソフトウェアって、例えばOSとか仮想マシンがどういう仕組みで動いていて...という基礎知識も必要ですが、それ以上に"実際にそれを自力で作れるか"、"既存技術に手を入れてハックできるか"
という部分が技能としては一番重視されると思います。言うは易し、行うは難し と言いますが、低レイヤーの世界はまさにこの言葉を痛感するジャンルで、理屈の上ではこれでいけるはずだと言うのは簡単ですが、
実際に実装して物にするまでが非常に大変です。ただいきなり手を動かしてガリガリ作り始めるのも難しいので、基本的には
既存のプロジェクトを解析してみる -> (改造して遊んで見る) -> 自分で書いてみる
の繰り返しになると思います。
ただし世の中には既存プロジェクトなんて解析しなくても、最低限のハードウェアの仕様書だけでいきなり大規模なコードを錬成できる人もいるので、そういう人達は最後のステップだけで良いのかなぁ。
4. OS(Operating System)
本節はOSの自作やハック手法について述べます。
OSというと通常は個人用のデスクトップやサーバーなどにインストールされる物を思い浮かべますが、組み込みの世界だと例えばゲーム機だったりスマートフォンを始めとする各種端末であったり
ルーターであったり、結構活躍の場は広いジャンルです。
もう少し具体例として、例えばPlaystation4はOrbis OSというFreeBSDベースの独自OSがSony Computer Entertainment(今はSIE)の手によって開発されてたり、
GoogleのAndroidはLinuxをベース(と言うとちょっと怒られそうですが)にしていたりと、まあ完全に独自な物からforkまでいろいろとあります。
ただいきなり、既存のOSをハックするのは少し難しいかもしれないですし、いや俺は自分でOSを作りたいんだという人もいるでしょう。
いずれにせよ最初は川合先生の30日OS本を読んで、小さなOSを作ってみることをおすすめします。
■ 4-1.「30日でできる! OS自作入門」
30日OS本はintelのCPUでセグメントやTSSを活用してOSを作っていきます。
■ 4-2. 「12ステップで作る 組込みOS自作入門」
これでOSの基本構造みたいなのは何となく分かると思うんですが、例えばMMUによるページング機構だったりAPICだったりACPIだったりと重要なハードウェア機構は
まだまだあります。現実世界のOSを探検して行く段階でこれらはほぼ必須となってくるので、仕様を学んで動かしてみる事をおすすめします。
まあintelのマニュアルを見れば全て載っているのですが、いきなり1から読むのはしんどいかもしれないのでまずは以下のサイトなどでこれらのハードウェアの設定方法や動かし方を学んでみるのがおすすめです。
■ 4-3. 「0から作るOS開発」
■ 4-4. 「OSDev\.org」
Expanded Main Page - OSDev Wiki
で、OSの開発にだんだん慣れてくると、今度は既存のOSの実装を真似してみたりハックしてみたくなるかもしれません。
いきなりLinuxや*BSDを読んでみても良いとは思いますが、ワンクッション置く目的で以下の書籍もおすすめします。
■ 4-5. 「はじめてのOSコードリーディング ――UNIX V6で学ぶカーネルのしくみ」
UNIX V6という非常に簡単なカーネルを解読してみようという物で、UNIXと言えど意外と単純に実装されている事を実感できますし(まあ初期バージョンだからですが)、
これぐらいなら自分で作れるかもとOSに対する見方ががらっと変わってくる書籍です。すごく良い本だと思います。
なんとなくOSにも慣れきたかなと思ったらいよいよLinuxや*BSDをハックしてみたりドライバを書いたりするのも面白いでしょう。
Linuxの解読だと以下がおすすめです。
■ 4-8. 「Linux Kernel Hack Japan (LKH-jp)」
LKH-jpの概要 - LinuxKernelHackJapan
だいたいこの3つでLinux2.6は読むことができます。(あとLinuxカーネル解析入門という書籍もあるそうですが、私は読んだことありません)
2.6ってかなり古いですが、最近のバージョンにも適応可能な基本的な設計思想やアーキテクチャが多く載っており、非常に役に立ちます。
またもう少し新しいバージョンのLinuxを解析する資料もあります。
■ 4-9. 「新装改訂版 Linuxのブートプロセスをみる」
tatsu-zine.com
この本はLinux3.3.4の64bitバージョンのコードのうち、主にgrubからカーネルローダーを通してLinuxがブートし、初期化を行う所までを
追っていく物です。
grubのコード解説まで載っていてブートプロセスを事細かに追うことができます。
■ 4-10. 「Linuxカーネル「ソースコード」を読み解く」(未発売)
書籍『Linuxカーネル「ソースコード」を読み解く』(工学社)の見本誌が届きました。出版不況のご時世にも関わらず、紙での本になります。ぜひ書店で手に取ってみて、中身を見てもらえるとよいかなと思います。購入特典としてダウンロードサービスもあります。#工学社 #io40th pic.twitter.com/tiGVKaD2HB
— Yutaka Hirata (@yutakakn) December 16, 2016
帯を見れば分かるのですが、なんとこの書籍4.x系に対応しているんですね。
現段階ではまだ発売していないので内容に関しては分かりませんが、最新の4.x系の資料はすごく貴重です。
あとはLinuxに慣れてくると組み込みボードとか自作のハードなんかに移植したりすると面白いかもしれないです。
そういう時はデバドラ本が役に立ちます。
■ 4-11. 「Linuxデバイスドライバ」
Linuxや*BSDのカーネルプログラミングに慣れてきたら、さらに興味のある人はモノリシックカーネルでないアーキテクチャのカーネルをハックしてみるのも面白いかもしれません。
モノリシック以外にどんな設計があるのか、OSの理論や実装方法をしっかり俯瞰してみたい方にはお馴染みタネンバウム本をおすすめします。
■ 4-12. Modern Operating Systems (4th Edition)
Tanenbaum & Bos, Modern Operating Systems, 4th Edition
邦訳は3版までしか無いのですが、原書だと4版があり仮想化やセキュリティなど結構ナウいテーマまで触れているようです。
(私はまだ4版は読めてないので内容の詳細は分かりませんが...)
5. 仮想マシンモニター(Hypervisor)
本節では仮想化技術、ハイパーバイザ、エミュレータといったシステムの自作、ハック方法について述べます。
仮想化技術といえばまずクラウドや分散システムの話から始めるのが定石なのかもしれませんが、しかしクラウドのようなバカでかいコンピュータリソースを前提としたシステムを
個人でハックするのは現実味がなさすぎます。そうではなく、もっと手軽に楽しめる仮想化技術の使い方を例に挙げてみます。
まず一つはエミュレータ開発です。汎用PCアーキテクチャ向けの自作エミュレータを作ってLinuxなりWindowsを動かしてみても面白いでしょうが、
世の中にはゲーム機や端末のエミュレータも多く存在します。せっかくエミュレータを作るなら普段使い慣れたintelチップセット,PCI,ISA,IDEみたいなアーキテクチャでなく(ちょっと古い?)、
もっと変わったアーキテクチャの物を作って見ると良いかもしれないです。
フルスクラッチで自作するのも良いですし、QEMUやBochsに手を入れても良いでしょう。
例えばxqemuというプロジェクトはQEMUをベースに開発されたXBoxエミュレータです。
XQEMU An experimental emulator for the original Xbox
http://xqemu.com/
後はlibretroとかも見てみるとあまりの凄さに衝撃を受けるはずです。(ゲームエミュ界隈は実装モンスターみたいな人達がたくさんいて毎度腰を抜かします)
Libretro – A crossplatform application API, powering the crossplatform gaming platform RetroArch
(ただし当然ですが法律には触れないように気をつけてください。エミュレータ開発自体は基本的に合法ですが、他のプロセスで法にひっかかる場合もあります)
後は、KVMやXenといったハイパーバイザのハック、自作ですがこれについては趣味を通り越して少し学術寄りな目的になることが多いためここでは詳しくは述べません。
まあ最近関係ある話題だとBash on Windowsがハイパーバイザ技術を使って実現されていたり、今年の未踏プロジェクトに採択されているNoah(Bash on Ubuntu on Mac OS X)という物も同じくハイパーバイザ技術で
ELFバイナリをOS X上で動かしているみたいです。興味のある方はぜひ調べてみてください。
さて、ではエミュレータやハイパーバイザのハック、自作の始め方ですが、まずは以下の資料を読むことを強くおすすめします。
■ 5-1. 「ハイパーバイザの作り方」
VT-xの仕様から、実際のハイパーバイザ(bhyve)の実装まで網羅的に触れられており、仮想化技術の基礎を効率的に学べます。
非常におすすめです。
基礎を学んだら後は実際にエミュやハイパーバイザをハック,自作してみましょう。ただこの辺は本当に参考書籍が少なく、基本的にはネットの情報
に頼るしかありません。(割と最近に「自作エミュレータで学ぶx86アーキテクチャ」という本が出てたみたいですが、私自身が読めておらず内容が確認できておりません...)
ただ一応少しエミュレータの実装に触れている書籍が私にの知る範囲でありまして、
■ 5-2. 「熱血! アセンブラ入門」
それがこの熱血! アセンブラ入門です。この本は多様なアセンブラを比較しながらコンピュータアーキテクチャ(主にISAですが)を学ぶという本で、
最後の方にgdbシミュレータを解析,改造している所があってエミュレータの基本構造を学ぶ事ができます。
こういった断片的な情報やネットの記事を頼りに簡単なエミュレータを自作できたら、今度はQEMUやKVM,Xenをハックしてみると面白いです。
QEMUとKVMの実装に関しては以下の記事をおすすめします。(自分の記事を薦めるのはちょっとアレですが、他を検索しても日本語記事はおろか英語ですら資料が無いのです...)
6. コンパイラ,言語ランタイム
本節はコンパイラ,言語ランタイムの自作,ハックについてです。
コンパイラと言うと、オレオレ言語を作って動かすというのもロマンがあって楽しいですが、本節ではどちらかというとコード生成やリンクといった
いわゆるバックエンド部分を中心に述べます。
例えばSonyはPlaystation4を開発する際、clang/llvmを採用しましたがその際自社独自のPS4 SDKやプロプラリンカをそれらに移植し、
ゲーム機のアーキテクチャにチューニングされたバックエンドを開発したと言われています。
LLVM Conferenceで実際にSCEの人が話している発表などを見てみると分かります。
"Developer Toolchain for PS4"
http://llvm.org/devmtg/2013-11/slides/Robinson-PS4Toolchain.pdf
(ところでさっきからゲーム機の話ばかり出てくるな...と思われるかもしれませんが、よりわかりやすい例を挙げているのと、私の趣味です(ェ )
新しいハードを作れば、当然そのアーキテクチャに適したコンパイラツールチェーンを開発する必要があるわけです。
各社のコンパイラへの取り組み方や実装例は、サムスンの人達による以下の資料を見るとわかりやすいです。
"Where is LLVM being used today?"
http://llvm.org/devmtg/2016-01/slides/fosdem-2016-llvm.pdf
まあこういったツールチェーン移植の魅力としては、やはり普段当たり前のように使っているgccやclangが、独自のハード上で動く圧巻の光景ではないでしょうか。
自作ハード用にコンパイラを移植してみたりするとその感動を味わえるかと思います。
(正直私はまだ独自ハード用のコンパイラ移植はやった事がないのですが、他の人から聞いた話では非常に達成感があるとの事でした)
さて、ではまず簡単なコンパイラやインタプリタを自作してみましょう。それには以下がおすすめです。
■ 6-1. 「言語実装パターン: コンパイラ技術によるテキスト処理から言語実装まで」
この本は主にコンパイラの構文解析やAST生成に焦点をあてており、コンパイラのフロントエンドを知るには非常に良い書籍です。
ただ実際にコンパイラを作るとなると、肝心のバックエンド(主にコード生成)が必要になってきますが、それには以下を参照すると良いと思います。
■ 6-4. 「ガベージコレクション 自動的メモリ管理を構成する理論と実装」
あとはGC(Garbage Collection)についても知見を持っておくと、コンパイラツールの移植でも役立つでしょうが効率の良いメモリページ回収アルゴリズムについて学ぶことができ、
他のジャンルでも役立てられると思います。ブラウザの実装に興味がある人などにもGCは必須です。
さて、コンパイラのハックにおいて欠かせないのがLLVMです。こいつはコンパイラのバックエンド処理を担うというだけでなく、
例えばバイナリ中の命令トレース,フックやメモリ保護などにも利用でき、非常に柔軟な代物です。
LLVMの概要、使い方については以下を見ると良いでしょう。
■ 6-7. 「Random LLVM Notes」
それからコンパイラだけでなくリンカやオブジェクトファイルの仕組みを学ぶ必要が出てくる場合もあるかもしれません。
そういう時は坂井先生のリンカローダ本がとても参考になります。
■ 6-8. 「リンカ・ローダ実践開発テクニック: 実行ファイルを作成するために必須の技術」
標準ライブラリなどのランタイムを移植や改造をする必要が出てきた場合は坂井先生のこちらの書籍もおすすめです。
7. CPU,周辺機器
本節ではCPU,周辺機器の設計について"少しだけ"述べます。
(少しだけというのは私自身このジャンルは最近ようやく手をつけ始めた程度なので、良さそうな資料をちょろっと紹介する程度で....)
既存のチップセットやCPUに関しては、それぞれベンダーの仕様書を見れば良いのですが、一度ぐらい自分でハードも設計してみたいと思った方には、以下がおすすめです。
■ 7-2. 「独自CPU開発で学ぶ コンピュータのしくみ」
実際にHDLをガリガリ書いてCPUを設計したり、その上にコンパイラ移植したりする書籍です。
自作CPUを考えている方にはおすすめです。(アカデミック価格なら評価ボードもそれなりの値段で手に入れられます)
8. 慣れてきたら
さて、全体的に(もしくは局所的にでも良いのですが)基礎が固まってくると、システムプログラミングはさらに面白くなってくる(はずです)。
実は世の中には意外とハックできるネタというのがたくさん転がっていて、それに気づき始めるともう沼から抜けられなくなります。
じゃあそういうハックネタってどういう所から見つけるのかというと、大体はRSSフィードによるニュース(HackerNews, Phoronix....)や、有名なハッカー達のSNS、研究論文、ML等から得られます。
そうして得た情報を元に、自分はそれらにどのように貢献できるかもしくは新たなハックを生み出せるかを考え、実際に手を動かし、完成した暁には彼らにコンタクト(パッチ,メール...)を取ってみたりするわけです。
そうなってくれば毎日がハック漬けの非常に刺激的な日々をおくれるでしょう。
まあ今言ったような野良ハッカー(?)的な楽しみ方も良いでしょうし、何らかのジャンルのエキスパートとして研究者を志す人達もいるみたいです。
例えばマルウェア解析だったり、分散システムだったり、データベースだったりネットワークだったりとそのジャンルは多種多様です。
ざっとこんな感じです。急ぎ足で書いたので若干文章構成がおかしかったりするかもしれませんがゆるして。
結局長々と書き連ねましたが、とにかく自分のその時やりたいと思った事をどんどん進めていくのが良いと思います。
その際、本記事が学習の手助けになれば幸いです。