本記事の信頼性
- リアルタイムシステムの研究歴12年.
- 東大教員の時に,英語でOS(Linuxカーネル)の授業.
- 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
- プログラミング歴15年以上,習得している言語: C/C++,Python,Solidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
- 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」をGitHubにオープンソースとして公開.
- 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
- 最近は自然言語処理AIとイーサリアムに関する有益な情報発信に従事.
- (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
- (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
こういった私から学べます.
Linuxカーネルの記事一覧はこちらからどうぞ.
LinuxカーネルはC言語で書かれています.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
目次
Linuxカーネルとは
Linuxカーネルとは,Operating System(OS)のカーネル(OSと中核となる部分)の一つです.
例えば,Windows,Mac OS X,FreeBSD等が挙げられます.
OSは以下の役割を担います.
- 利便性や移植性の向上するためにハードウェアの抽象化(ユーザがハードウェアの機能を関数呼び出しで(暗黙的に)利用できること)
- 複数のアプリケーション間のハードウェアの多重化(どのアプリケーションがどのハードウェアを利用しているかを関数呼び出しで(暗黙的に)利用できること)
- バグを含むアプリケーションのアイソレーション(分離して独立で実行すること)
- アプリケーション間でのデータ等の共有の許可
また,コンピュータは以下の3つの階層から構成されています.
- ユーザ:アプリケーション(例:emacs,gcc)
- カーネル:ファイルシステム,プロセス等
- ハードウェア:CPU,メモリ,ストレージ等
カーネルはユーザとハードウェアをつなぐためのインターフェースの役割を担います.
カーネルのコア機能として,以下が挙げられます.
- プロセス(スケジューリング)
- メモリ管理
- ファイルシステム(ディレクトリ,ファイル名)
- セキュリティ
- その他のコア機能(ユーザ管理,Inter Process Communication(IPC),ネットワーク,時刻管理,端末等)
これらのコア機能により,アプリケーションを抽象化できます.
システムコールは,OSとコミュニケーションするアプリケーションのインターフェースです.
下記のソースコードの例では,open,write,fork関数は,プロセスやファイルディスクリプタをシステムコールにより抽象化できます.
1 2 3 |
fd = open("out", 1); write(fd, "hello\n", 6); pid = fork(); |
なぜLinuxカーネルが面白いのか?
OSデザインは,以下の相反する目標とトレードオフを扱うからです.
- 高効率的かつ高移植性
- パワフルかつシンプル
- アイソレーションかつインタラクティブ
- 汎用的かつ高性能
OSの主な未解決の課題は,マルチコア対応とセキュリティです.
最先端のOSは,上記の課題にどのように対処しているのでしょうか?
Linuxカーネルをハック(プログラムを分析)して学びましょう!
Linuxカーネルは,とても大規模なソフトウェアプロジェクトです.
Linuxカーネルは,1991年に生みの親のリーナス・トーバルズ(Linus Torvalds)が一人で1万行ほどC言語プログラムを書いてオープンソースに公開して始まったプロジェクトです.
※Linuxの名前は,生みの親のLinusの名前から取って「Linux」になりました.
最初のLinuxカーネルのバージョン0.01は,こちらからダウンロードできます.
2017年にはLinuxカーネルは2,500万行になり,2022年1月16日のバージョン5.15.0では約2,833万行になりました(.cファイルと.hファイルのコードのみ計測).
毎日約7,500行のコードが追加されています.
下図に,Linuxカーネルの合計ソースコード行数の推移を示します.
ソースコードの行数を数えたいあなたはclocコマンドを利用しましょう.
まずは,以下のコマンドでclocをインストールします.
1 |
$ sudo apt-get install cloc |
次に,以下のように実行してLinuxカーネルのバージョン5.15のコードの行数を計測します.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$ cd linux-5.15 $ cloc . 73568 text files. 73082 unique files. 10734 files ignored. github.com/AlDanial/cloc v 1.90 T=108.41 s (579.9 files/s, 276997.1 lines/s) --------------------------------------------------------------------------------------- Language files blank comment code --------------------------------------------------------------------------------------- C 30410 3063333 2456987 15626226 C/C++ Header 22021 622642 1126091 5432655 reStructuredText 2956 147014 59109 404268 Assembly 1285 46007 98193 223171 JSON 357 2 0 183332 YAML 2000 35042 9130 158100 Bourne Shell 753 21851 15039 85581 make 2657 10198 11266 45998 SVG 59 78 1159 37555 Perl 65 7103 4967 35850 Python 139 5758 5453 29333 yacc 9 693 355 4761 PO File 5 791 918 3077 lex 9 345 303 2104 C++ 10 349 138 1935 Bourne Again Shell 51 297 248 1305 awk 11 155 126 1111 Glade 1 58 0 603 NAnt script 2 147 0 585 CSV 7 73 0 540 Cucumber 1 30 50 182 TNSDL 2 33 0 140 Clojure 42 7 0 127 Windows Module Definition 2 15 0 109 m4 1 15 1 95 CSS 1 28 29 80 XSLT 5 13 26 61 vim script 1 3 12 27 Ruby 1 4 0 25 INI 1 1 0 6 sed 1 2 5 5 --------------------------------------------------------------------------------------- SUM: 62865 3962087 3789605 22278947 --------------------------------------------------------------------------------------- |
Linuxカーネルの開発サイクルはとても速いです.
約70日毎にリリースし,リリース毎に約250社の企業(約1,600人の開発者)が13,000個のパッチ(ソースコードの一部)を提供しています.
したがって,Linuxカーネルは最もよく書かれた/設計された/保守されたCコードの1つです.
Linuxカーネル開発の詳細は,2017 Linux Kernel Development Reportに記載してありますので,興味があるあなたは是非読み進めて下さい!
スマートフォンやタブレットの85.1%はLinux(Android)で動作しています.(iOSは14.9%です.)
トップ100万台のWebサーバの98%,スーパーコンピュータの99%はLinuxで動作しています.
2020年6月に,SpaceXがLinuxを採用したニュースで話題になりました.
無償のLinuxカーネル開発者からの貢献は減少傾向です.
2012年は全体の14.4%だったのが,2013年では13.6%,2014年では11.8%,2015年では7.7%になっています.
この減少には多くの理由が考えられますが,一番の理由はLinuxカーネル開発者が不足していることです.
Linuxカーネルのメインラインにコードを入れる能力を証明すれば,誰でも仕事の依頼に困ることはないでしょう.
世界レベルのソフトウェアエンジニアとして働きたいあなたは,是非Linuxカーネルを学びましょう!
Linuxの歴史
上図にUNIXの歴史を示します.
Linuxは図の左から2番目にあり,1991年から開発されたUNIX-likeなOSであることがわかります.
1991年にLinuxのバージョン0.01がリリースして現在まで開発が続いています.
※図中にはないですが,2022年1月16日にバージョン5.15.0がリリースしました.
Linuxの開発はLinusがcomp.os.minixに投稿した以下のメールから始まりました.日本語訳も追加しています.
From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds)
Newsgroups: comp.os.minix
Subject: What would you like to see most in minix?
Summary: small poll for my new operating system
Message-ID: 1991Aug25.205708.9541@klaava.Helsinki.FI
Date: 25 Aug 91 20:57:08 GMT
Organization: University of Helsinki
Hello everybody out there using minix –
Minixを使っている皆さん,こんにちは.
I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready.
私は386(486) AT互換の(フリーの)オペレーティングシステム(OS)(単なる趣味で,GNUのように大きくてプロフェッショナルなものではありません)を作っています.
このOSは4月から開発していて,準備を始めています.
I'd like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons) among other things).
私のOSがMINIXに似ているので(ファイルシステムの物理的なレイアウトが同じなので(特に実用的な理由で)),Minixの好き嫌いがある人の意見が欲しいです.
I've currently ported bash(1.08) and gcc(1.40), and things seem to work.
現在,bash(バージョン1.08)とGCC(バージョン1.40)を移植していますが,うまくいっているようです.
This implies that I'll get something practical within a few months, and Id like to know what features most people would want.
これは,私が数ヶ月以内に実用的になることを意味しており,ほとんどの人が望む機能を知りたいと思っています.
Any suggestions are welcome, but I won't promise I'll implement them 🙂
どんな提案でも歓迎しますが,実装することを約束するつもりはありません .🙂
Linus (torvalds@kruuna.helsinki.fi)
PS. Yes – it's free of any minix code, and it has a multi-threaded fs.
PS. はい - MINIXのコードは一切ありませんし,マルチスレッドのファイルシステムを持っています.
It is NOT portable (uses 386 task switching etc), and it probably never will support anything other than AT-harddisks, as that's all I have :-(.
(386のタスク切り替え等を使っているので)ポータブルではないし,おそらくAT互換のハードディスク以外はサポートしません.
https://groups.google.com/g/comp.os.minix/c/dlNtH7RRrGA/m/SwRavCzVE7gJ
Linuxの歴史は以下になります.
- 1991年:リーナス・トーバルズによる最初のLinuxバージョン0.01登場
- 1992年:GPLライセンスの下,最初のLinux配布
- 1994年:バージョン1.0リリース,i386向けシングルCPU対応,次にAlpha,Sparc,MIPSも対応
- 1996年:バージョン2.0リリース,マルチプロセッサ(SMP:Symmetric MultiProcessing)サポート
- 1999年:バージョン2.2リリース,ビッグカーネルロック(SMP対応のための単一の大域的なロック)の除去
- 2001年:バージョン2.4リリース,USB,RAID,Bluetooth等のサポート
- 2003年:バージョン2.6リリース,物理アドレス拡張(PAE:Physical Address Expansion ),新アーキテクチャのサポート等
- 2011年:バージョン3.0リリース,バージョン2.6からのインクリメンタルなリリースに変更.
- 2015年:バージョン4.0リリース,ライブパッチのサポート.
- 2019年:バージョン5.0リリース(4.21からの繰り上がり),グラフィックスドライバのサポートや改善.
- 2022年:バージョン5.15.0リリース,未来へと続く...
Linuxのオープンソースモデル
LinuxはオープンソースとしてThe Linux Kernel Archivesで配布されています.
また,GitHubのLinusのアカウントにあるLinuxカーネルのリポジトリで開発が行われています.
興味があるあなたは,GitHubにあるLinuxカーネルのリポジトリを読みましょう!
LinuxはGNU General Public License version 2(GPLv2)でライセンスされています
※明示的なsyscall例外と他のライセンスも適用可能な場合があることに注意して下さい.
GPLv2の条項の一部と日本語訳を以下に示します.
You may copy, distribute and modify the software as long as you track changes/dates in source files.
ソースファイルの変更/日付を追跡する限り,ソフトウェアをコピー,配布,変更できます.
Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions.
(コンパイラを介した)GPLライセンスのコードを含む改変やソフトウェアは,ビルドとインストールの指示とともにGPLの下で利用可能にしなければなりません.
https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
リーナスが書いた本「伽藍とバザール」(The Cathedral and the Bazaar)に記載されているリーナスの法則によると,オープンソースモデルであるバザール方式の主なメリットは以下になります.
※Windowsや伽藍方式,Linuxはバザール方式で開発されています.
Given enough eyeballs, all bugs are shallow
十分な目ん玉があれば,全てのバグは洗い出される.
Given a large enough beta-test and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone.
十分なベータテスターと共同開発者の基盤があれば,大半の問題はすぐに特定されて誰かが直す.
https://books.google.co.jp/books?id=F6qgFtLwpJgC&pg=PA30&redir_esc=y#v=onepage&q&f=false
Linuxカーネルのリリースサイクル
Linuxカーネルのリリースサイクルを説明します.
Linuxカーネルのバージョンは「(major).(minor).(stable)」と表記し,例えばバージョン5.10.7と表記します.
上図にLinuxカーネルの開発サイクルを示します.
バージョン5.9がリリースされた後,マージウィンドウが2週間,プリリリースの安定化期間が2ヶ月以内あり,その後に次のバージョン5.10がリリースされます.
また,Linuxカーネルには以下の4種類のリリースがあります.
- プリパッチ(Prepatch)(もしくはリリース候補(RC:Release Candidate)カーネル)リリース:メインラインリリース前にテストするため
- メインライン(mainline)リリース:全ての新しい機能を利用してリーナスによりメンテナンス
- 安定版(stable)リリース:メインラインカーネルのリリース後に追加のバグ修正
- 長期サポート版リリース(LTS:Long Term Support):いくつかのリリース毎にリリース(例:バージョン4.4,4.9,4.14,4.19,5.4,5.10,5.15,...)
ここで,Ubuntu 22.04 LTSではLinuxカーネルのバージョンは5.15.0-30のような記載になります.
これは,Linuxカーネルのバージョン5.15をベースに30回の修正を加えたパッチ番号という意味になります.
このソースコードが欲しい場合は,以下のコマンドを入力しましょう.
1 2 3 4 |
$ grep '^deb ' /etc/apt/sources.list | sed 's/^deb /deb-src /g' | sudo tee /etc/apt/sources.list.d/deb-src.list $ sudo apt update $ sudo apt install dpkg-dev $ apt source linux |
lsコマンドを入力すると,以下のファイルがダウンロードできていることがわかります.
※動作しているカーネルのバージョンにより数字が異なります.
1 2 |
$ ls linux_5.15.0-30.31.diff.gz linux_5.15.0-30.31.dsc linux_5.15.0.orig.tar.gz |
Linuxカーネルの概要
上図にOSの概要を示します.
最初に説明した通り,ユーザ,カーネル,ハードウェアの3層において,OSの役割はユーザのアプリケーションとハードウェア(CPU,メモリ等)をつなぐためのインターフェースになります.
CPUはユーザ空間かカーネル空間のどちらかで実行します.
カーネルのみCPUやIOデバイスを制御するような特権操作を実行できます.
ユーザ空間のアプリケーションはシステムコール(例:open(),read(),write(),close())によりカーネル空間とコミュニケーションします.
下表に,アーキテクチャ毎のユーザ空間のアプリケーションとOSのカーネルの関係を示します.
CPU | ユーザ空間のアプリケーション | OSのカーネル |
---|---|---|
x64(64ビットx86)アーキテクチャのリングプロテクション | リング3 | リング0 |
AArch64(64ビットARM)アーキテクチャの例外レベル | 例外レベル0 | 例外レベル1 |
上図に,readシステムコールの例を示します.
Python言語のコードmyfile.readlines()がCpython InterpreterによりC言語に翻訳され,C言語のライブラリにあるreadシステムコールを呼びます.
readシステムコールを呼び出したカーネル空間では,sys_read(),vfs_read(),ext2_readpage(),submit_bio()関数を呼び出してハードディスクドライブ(HDD:Hard Disk Drive)にアクセスします.
Linuxはモノリシックカーネル(単一のカーネル)です.
モノリシックカーネル伝統的なデザインで,OSの全ての機能がカーネルの特権モードで動作し,同じアドレス空間を共有します.
カーネルのインターフェースはほぼ全てシステムコールになります.
モノリシックカーネルの利点は,サブシステムとの連携がとりやすく,ファイルシステムや仮想メモリにより1つのキャッシュデータを共有できることです.
モノリシックカーネルの欠点は,相互作用が複雑になり,カーネルのアイソレーションができずにバグにつながることです.
これに対して,マイクロカーネルというOSのデザイン手法があります.
マイクロカーネルは,多くのOSのサービス(例:ファイルサーバのファイルシステム)が通常ユーザプログラムとして動作することです.
カーネルには,ユーザ空間でサービスを実行するための最低限の機構(例:IPC,仮想メモリ,スレッド)が実装されています.
カーネルのインターフェースはシステムコールではありません.
ユーザ空間のアプリケーションはIPCを介してサーバとコミュニケーションします.
マイクロカーネルの利点は,よりアイソレーションできることです.
マイクロカーネルの欠点は,IPCにより動作が遅くなることです.
有名なアンドリュー・タネンバウム(マイクロカーネル「MINIX」の生みの親)とリーナス・トーバルズ(モノリシックカーネル「Linux」の生みの親)の議論では,マイクロカーネルとモノリシックカーネルのどちらが優れているかで白熱したとのことです.
上図にLinuxカーネルの概要を示します.
これらの機能を今後説明していますので,楽しみにして下さい!
まとめ
今回は,Linuxカーネルの概要について紹介しました.
具体的には,以下の内容を解説しました.
- Linuxカーネルとは
- Linuxの歴史
- Linuxのオープンソースモデル
- Linuxカーネルのリリースサイクル
- Linuxカーネルの概要
LinuxカーネルはC言語で書かれています.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
次回はこちらからどうぞ.