私はどのようにしてLinuxカーネルを学んだかゆたかさんの技術書

【最新 – Linuxを学ぶおすすめ本 – 入門から応用までリストアップ!】も確認する

OSを俯瞰的に学ぼう

OSの全体像がわかる教科書のような1冊です。本書だけでカーネルが読めるようになるわけではありませんが、今後の勉強の方向性を示してくれます。他の書籍と比べて対象バージョンが新しく、解説もわかりやすいです。

平田豊 (著), MBビジネス研究班 (著, 編集)
出版社: まんがびと (2019/7/26)、出典:出版社HP

 

はじめに

普段 Linux を使っているなかで、「Linux カーネルのしくみを知りたいけれど、どうやって学習していけばいいか分からない」と悩んでいる人は多いのではないでしょうか?本書を読むこ とで、その学び方を知ることができます。
筆者が Linux と出会ったのは18年前(2001年)です。ただ使うだけではなく、オペレーティングシステム(OS)のしくみを理解したくてLinux カーネルを学ぼうとしましたが、長い間ちん ぷんかんぷんでした。
Linuxカーネルの学び方は誰も教えてくれない、どこかに書いてあるわけでもないので、とにかく試行錯誤の連続でした。長い年月がかかりましたが、今ならやっと「Linuxカーネルが分 かる」と自信をもって言えます。時間をかけて少しずつ学習していっても、ゼロベースの理解度が続きましたが、必要な基礎知識がそろった時、一気に視界が開けました。本書には、そんな筆者の苦労話と習得したノウハウを書き下ろしています。
Linuxカーネルをどうやって学んでいけばよいのか、そのためにどんな知識が必要かについてお話しします。単なる体験談だけではなく、Linuxカーネルの基礎についても丁寧に解説しています。本書を読了してもいきなり Linux カーネルを理解できるわけではありませんが、Linuxカーネルという題材に対してどう学んでいけばいいか、その道筋を知ることができます。 読者の皆様は筆者よりも効率的に学習を進めていけることでしょう。
リナックスチョットデキルようになるまでの道のりは決して易しくはありません。しかし、本書を読むことで、読者の皆様が Linux カーネルの世界への記念すべき第一歩を踏み出せれば幸 いです。
なお、本書に登場する Linux カーネルのソースコードはバージョン 5.0 をベースとしています。Linux ディストリビューションは Ubuntu 19.04(2019/4/18 リリース版)を使用しています。
2019年5月 平田豊

平田豊 (著), MBビジネス研究班 (著, 編集)
出版社: まんがびと (2019/7/26)、出典:出版社HP

目次

第1章 Linux カーネルを学ぼうとしたきっかけ
1.1 HP-UX 開発でのモヤモヤ
1.2 Linux との出会い
1.3 プロプライエタリとオープンソースのどちらが幸せか
1.4 生涯かけて Linuxカーネルを習得したい

第2章 学びの失敗と試行錯誤
2.1 圧倒的なスキル不足
2.2 学習資料の活用に失敗
2.3 ハードウェアの理解不足
2.4 ソースコードの理解不足

第3章 効率のよい学習方法
3.1 コンピュータアーキテクチャを知る
3.2 システムプログラミングを知る
3.3 C言語の拡張機能を知る
3.4 ユーザ空間とカーネル空間の違いを知る
3.5 とにかく動かして見る

第4章 C言語の学び方
4.1 Linux カーネルは C 言語でできている
4.2 C言語の何を習得すればよいのか
4.2.1 C 言語の基本文法
4.2.2 C 言語の歴史と規格
4.2.3 C 言語を使う上でのルール
4.2.4 コメント文
4.2.5 long long
4.3 gcc の拡張機能を知る
4.3.1 マクロの丸括弧
4.3.2 条件演算子
4.3.3 128 ビット整数
4.3.4 空の構造体
4.4 マクロの嵐に立ち向かうには
4.4.1 条件コンパイル文
4.4.2 マクロの読み方

第5章 Linux の動作フロー
5.1 Linux カーネルは Linux のコア
5.2 パワーオンリセット
5.3 BIOS の起動
5.4 Linux カーネルの起動
5.4.1 ブートローダーの役割
5.4.2 ブートメッセージ
5.5 initデーモンの起動

第6章 Linux カーネルの役割
6.1 すべてはユーザプロセスのために
6.2 自発的に動くことはない
6.3 タスク管理
6.4 仮想メモリ
6.4.1 ページングとスワップ
6.4.2 ページテーブルのサイズ計算
6.4.3 ページテーブル作成の問題点
6.4.4 32bitの仮想アドレス変換
6.4.5 64bit の仮想アドレス変換
6.4.6 メモリマップ

第7章 Linuxカーネルの作りとライセンス
7.1 モノリシックカーネルとは
7.2 ライセンスの話

第8章 ソースコードを読む
8.1 タグジャンプを覚えよう
8.2 キーワード検索
8.3 動かしながら読む
8.4 読み進めるコツ
エルクアーノ

第1章 Linux カーネルを
学ぼうとしたきっかけ
本章では、筆者が Linuxカーネルを学ぼうとしたきっかけについてお話しします。
1.1 HP-UX 開発でのモヤモヤ
筆者が新人として IT 企業に入ったのは1998年(平成 10年)なので、今から 20年以上前のことです。平成が2019年4月末で終わり、令和という新しい元号が始まった今では、遠い昔の思 い出になりつつあります。
当時は Windows95ブームにより一般家庭にPC が普及し、Windows98のリリースと自作PCブームによって活気が溢れていました。インターネットはまだそれほど流行っておらず、まだダイヤルアップ接続の時代です。電話と同じで、インターネット通信をすればするほどお金がかかる従量課金です。使っていた PC の性能は、CPU が PentiumIII 533MHz、メモリが 256MB とい ったスペックでした。現在使っているPCは CPU が Core i5 3.4GHz、メモリが16GBなので、スペックも桁違いです。
今はたくさんのプログラミング言語が現場で使われていますが、当時はC言語が主流で、Java とPerl がブームでした。C言語に関しては学生時代に学んでいて、新人の時点で基本文法は 習得できていました。しかし、後から振り返って分かったことですが、プロとしての開発経験がないためプログラミングは我流に近く、業務として品質の高い設計とコーディングができて いたわけではありませんでした。それでも、MS-DOS や UNIX 向けのちょっとしたアプリケーションが作れるくらいのスキルはありました。
新人としての最初の仕事は、HP-UX※1という商用 OS でのデバイスドライバ開発でした。学生時代にワークステーション (SGI の Indy) や SunOS(後の Solaris)を使ったことはありましたが、HPUXを使うのは初めてのことでした。また、デバイスドライバ開発も当然ながら初めての経験だったのです。開発言語はC言語なのですが、アプリケーションとはまったくの別物で、慣れるまでに3年はかかりました。なかなか芽が出ず、一生懸命頑張っているのに仕事で成果が出せないので、上司から「今の仕事は向いていないのではないか。他の仕事にアサインを変えるか?」と打診されたこともあり、当時はとてもショックでした。
結果としてデバイスドライバ開発の業務は5年間やったのですが、入社3年目が一番つらい時期でした。プログラミングが好きで、将来プログラマになりたくて努力をしてきたはずなの に、自分には今の仕事が向いていないのか、そもそもスキルが足りないのか、とにかく分からないことが分からないという状態でした。C言語は分かるのに、デバイスドライバのソースコード※2が理解できないのです。
プログラミング言語は話し言葉とは違い、言語を知っているだけでプログラムのソースコードが読めるようになるわけではありません。むしろ、読めないプログラムの方が多いくらいで す。そのプログラムを理解するための前提知識が必要となるからです。例えば、フーリエ変換を行うプログラムがC言語で書かれていたとして、数学の知識がゼロだとプログラムの意味が 理解できないのと同じことです。また、プログラムの規模が大きくなってくると、一人で見きれるボリュームの範疇を超えます。特に、プログラマとしての経験が浅いうちは巨大なソース コードを読み解くスキルが低いので、プログラムの全体像が見えてこず、理解が進みません。
最初の仕事がいきなりデバイスドライバ開発というのもすごいことですが、デバイスドライバというのはカーネルと一心同体となって動作するソフトウェアです。カーネル(Kernel)というのは中心部・核心という意味の単語で、OS(オペレーティングシステム)のコア部分という意味合いで使われます。

※1: 旧 HP 社(現 HPE 社)が開発した UNIX OSHewlett-Packard UNIX の略。
HP社は2015年にHP Inc.とHPE(HP Enterprise)に会社分割した。
※2:ソース(Source)は源泉や元という意味で、ソフトウェアの設計図のようなもの。
ソースコードやソースプログラム、略してコードやプログラムと呼ばれることもある。
ソースコードを作ることをプログラミング、コーディング、実装などと呼ぶ。

【デバイスドライバとカーネルの関係】
図 1-1 デバイスドライバとカーネルの関係

図 1-1 は HP-UX のデバイスドライバとカーネルの関係を示したものですが、Linux や Windowsもしくみとしては同じです。デバイスドライバをカーネルに組み込む方式として、静的リンクと動的リンクの2種類が存在します。カーネルとデバイスドライバはカーネル空間という特別な領域で動作するのが特徴です。
デバイスドライバはカーネルに不足している機能を追加することができるしくみであり、機能を追加することがデバイスドライバを作る目的でもあります。デバイスドライバを作るには、 カーネルとどのようにして連携させるかということを知る必要があるため、OSベンダー(OS の開発元)が開発者向けに情報を提供しています。HP-UX の場合は、DDG(Driver Development Guide)やDDR(Driver Development Reference)というドキュメントで、HPE 社のWebサイトで配布されています。Windowsの場合は、WDK(Windows Driver Kit)というデバイスドライバ開発キットにドキュメントが含まれています。以前はWDKのことを DDK(Driver Development Kit)と呼んでいました。
HP-UX デバイスドライバを開発する上で、まず困ったのが、情報が少ないということでした。前述したドキュメントがお世辞にも充実しているといえる内容ではなかったのです。Microsoft のドキュメントは分かりにくいと言う人もいますが、筆者は Microsoftの提供するドキュメントは一番充実していると思っています。Windowsはオープンソースではなくプロプライエタリ※3なので、ビジネス戦略上ソースコードを出さない分、ドキュメントを充実させるというのはあるべき姿といえます。
当たり前のことですが、世の中で使用人口が多いプラットフォームほど情報量も多くなります。何か分からないことにぶっかった時に解決する確率が高くなります。言い換えると、技術 者としてのスキル不足を情報量(先人の知恵)でカバーすることができるということです。裏を返せば、豊富な情報量がないと問題解決ができないということは、自分自身にスキルがないと いうこと。若かった頃の筆者はまさにITエンジニアとして駆け出しだったので、自分のスキルのなさを情報不足のせいにしていたのです。
いずれにしても、HP-UX でのデバイスドライバ開発は情報量 が少なく、カーネルがプロプライエタリであることから、まさにブラックボックスとの闘いでした。デバイスドライバはカーネルの動作や仕様に合わせて実装する必要があり、その通りに作ってあるはずなのですが、実際にテストしてみると期待通りに動作せず、障害対応※4が大変でした。カーネルのソースコードを見ることができないので、カーネルの動きがよく分からなかったからです。
過去を振り返ると、当時は貴重な業務経験をさせてもらっていたと改めて思います。HP-UX デバイスドライバ開発という仕事を悪戦苦闘しながらも5年も続けられたことで、その後の Linuxの低レイヤを理解する足がかりとなりました。何事も経験であり、独学では到達することができなかったでしょう。しかし、若い頃はそのような悟りの境地に至ることはできません でした。

※3:プロプライエタリ (Proprietary)は所有者・独占所有物という意味で、 略して
プロプラとも呼ばれる。ソースコードが一般に開示されていないという意味合いで
使われ、オープンソースの対語。
※4:ソフトウェアのバグの原因を調べること。トラブルシュートや問題調査、
デバッグと呼ぶこともある。

【1.2 Linux との出会い】
2000年から2001年にかけて、日本に Linuxブームが到来します。この時に初めて LinuxというOSの存在を知りました。当時は Windows2005※5が登場し、PCで使うOSといえば Windows 一択でした。また、2001 年にADSLが登場し、インターネット常時接続時代に移行していきます。コンピュータのプラットフォームが Microsoft※6一色であることに難色を示す人たちがいて、「Windows だけを使っていていいのか」という風潮もありました。そんななか、Linux が「第2のOS」としてメディアに取り上げられたのです。
図 1-2 リーナス氏の自伝
2001年にLinuxの第一人者であるリーナス・トーバルズ氏が来日し、自伝書籍『それがぼくには楽しかったから全世界を巻き込んだリナックス革命の真実』(図 1-2)が出版されたこともあり、Linuxブームが加速しました。
新聞にもニュースとして掲載され、国内におけるLinuxの読み方もこの時に「リナックス」に決まりました。それまではリヌックスやライナックスなど発音が国内で統一されていなかった のです。なお、リーナス氏本人も発音はなんでもよいと公言しており、氏の録音を聞くとリラックスに近い発音になっています。
当時はインターネットがまだそれほど普及していなかったこともあり、コンピュータ雑誌が多数発行されていた時代でした。当然のことながらLinuxに関する特集が組まれ、Linux専門誌 も刊行されました。書籍も多数出版されました。今も昔もIT 業界では何らかのブームが起こると、それに関連する本が雨後の筍のように発売されるという現象があります。
ITエンジニアとしてブームになっている技術にはひとまず飛びついておく、というのは基本中の基本です。ブームの最中は情報量が格段に増えるからです。つまり、自己学習に最適な状態になるということです。ブームになれば周りにもやっている人が増えるので、分からないことがあれば聞くこともできます。ご多分に漏れず、筆者もLinuxに注目することにしました。
そして、この時に初めてオープンソース※7という言葉を知りました。オープンソースはソフトウェアのソースコードが一般公開されており、ライセンス※8に準拠すれば誰でも自由にソースコードを利用できます。当時の日本には存在しなかった文化です。
商用ソフトウェアやシェアウェア※9はソースコードが非公開であるのが一般的ですが、フリーソフトでもソースコードが開示されているものは多くありませんでした。また、フリーソフ トは個人で開発するものであり、ソースコードをインターネット上に置き、不特定多数の人たちで開発を行うという形態ではありませんでした。
筆者はこの時、「Linux というOSはオープンソースであり、すべてのソースコードが公開されている」ということに大変驚き、雷に打たれたような衝撃を受けました。巷にある雑誌や書籍でもLinuxのソースコードの解説が載るようになり、「カーネルを学ぶ」という絶好の機会が来たのだと確信しました。
一介のプログラマとしてアプリケーションしか分からない技術者で終わりたくはない。カーネルも分かるようになれば技術者として一段と上に行くことができるかもしれない。HP-UXデバイスドライバ開発でモヤモヤしていたことが解消されるかもしれない。そう強く感じました。
こうして、筆者はLinuxの世界へ足を踏み入れることになったのです。なお、この時点ではあくまで趣味の範囲内です。当時はLinuxブームとはいえ、業務の製品に使えるレベルではない とされていたので、現場の人からは「Linux なんておもちゃ」「クラッシュダンプも採取できないOS」と揶揄されていました。しかしながら、Linuxを仕事でやるのか、やらないのかということはどうでもよいことでした。OSのしくみを理解することで、自分自身の技術力を引き上げることが筆者の目的だったからです。

【1.3 プロプライエタリとオープンソースのどちらが幸せか】
筆者はプロのプログラマとして20年以上、開発の仕事をしてきました。そのなかで、プロプライエタリ(HP-UXとWindows)とオープンソース(Linux)の両方の環境を経験しました。どちらも 一長一短ですが、個人的な見解としてはLinuxの仕事が一番やりやすかったです。どのプラットフォームの仕事も楽しくて、あれが好き、これは嫌いというつもりはまったくありません。 プロなのですから、どんなプラットフォームでも仕事が楽しめることが大切です。

※5:WindowsNT5.0 として開発されていたOSがWindows2000(略してW2K)となり、
Windows98 の後継として一般向けに普及した。NTカーネルベースなので安定性は抜群。Windows10はNT10 とも言われる。
※6:当時はオープンソースを目の敵にする人もいた。
※7:オープンソースソフトウェア(Open Source Software)は略してOSSとも呼ばれる。
※8:オープンソースのソースコードには著作権が含まれるため、ソースコードの取り扱いに
ついて規定されている。著作権を放棄したソフトウェアをPDS(Public Domain Software)と呼ぶ。
※9:試用期間は無償で使用してよいが、継続使用は対価を支払う必要がある。
秀丸エディタが定番。

平田豊 (著), MBビジネス研究班 (著, 編集)
出版社: まんがびと (2019/7/26)、出典:出版社HP