SlideShare a Scribd company logo
1 of 38
「ゼロからのOS自作入門」
の執筆を支える技術
2021年5月29日
OSC2021 Online/Nagoya
@uchan_nos
自己紹介
内田公太 @uchan_nos
サイボウズ・ラボ株式会社でOSと言語処理系の研究開発
自作OSもくもく会コアメンバー
校正協力 執筆 執筆
「ゼロからのOS自作入門」の紹介
「OS」を自分で作る過程を解説する書籍
他のOSに頼らず「Hello, world」を出力するアプリから始め、
30章で本格的なOSを作成
64ビット動作、メモリ管理、マルチタスク、ファイルシステム……
本書で作成する「MikanOS」上で様々なアプリが動く様子
執筆に使ったツール
Re:VIEW
太字指定などの各種マークアップ、索引指定、PDF化
review-text-imager
アスキーアートで書いた図をPNGに変換する
Git
MikanOSの開発にも使用
git-extract-tags
引用するソースコードをGitリポジトリから取得する
もちろん、全部OSSです!
Re:VIEW
書籍用マークアップ言語
書籍用マークアップ
書籍原稿には様々な指定が必要
太字、等幅フォント
図、表、リスト、コマンドラインの
スタイル
図、表、リストの参照
章構成
執筆途中で紙面を確認したい
手軽にPDFを生成したい
書籍にはRe:VIEWがおすすめ!
書籍執筆用だけあり、必要な機能が
揃っている
リストの例
ハローワールドプログラムの本体は@<tt>
{Main.c}ファイルです。@<list>{day02
a_Main.c}にその全体を示します。ぱっと
見て@<chapref>{day01}で作った@<tt>
{hello.c}よりすっきりしていることが分
かると思います。
Re:VIEWソースコードの例
Re:VIEW
https://github.com/kmuto/review
書籍用のマークアップ言語+ビルドシステム
Re:VIEW記法の原稿から、PDF、EPUB、HTML等に変換できる
日本人が開発の主体なので、日本語サポートがばっちり
2015年頃から開発され、最新が5.1.1
「ゼロからのOS自作入門」の原稿を書いていたころはバージョン3系
1年でメジャーバージョンが1上がるほど、開発が活発
技術書典で回を経る毎に使う人が増加していった(肌感)
Re:VIEW記法
「ゼロからのOS自作入門」で使った記法を一部紹介
等幅フォント @<tt>{Main.c}
画像参照 @<img>{event-propagation}
画像埋め込み
//image[event-propagation][イベントの伝搬][scale=0.8]{
//}
索引登録 @<idx>{タイマ}
脚注参照 @<fn>{heavy-task}
脚注
//footnote[heavy-task][脚注本文]
ユーザ定義タグも作れる
 等幅フォント化+索引登録 @<codeidx>{SendMouseMessage()}
ラフ図案を手軽に描く
ラフ図案
本文を執筆中に図を入れたくなることがある
その場で本格的な作図をしたくない
本格的な作図により、本文用の脳内メモリが奪われる
ASCIIアートで本文中に描いて、それを図の代用としたい
//image[layering][レイヤによる画面描画][scale=0.9]{
マウスのレイヤ --> --------------------
\ ---- \
デスクトップの --> - \ \ ↑ \ <---\--- マウスのウィンドウ
レイヤ \ \ ---- \
\ --------------------
\ \
--------------------
//}
コメントを抽出してPNG化する
Re:VIEWの「//image{…}」は、コメントが埋め込める
→コメントを抽出してPNG化して埋め込めばいいかも?
専用ツールpngnize-image-bodyを作りました
https://github.com/uchan-nos/review-text-imager
先ほどのコメントをPNG化した結果
ImageMagick
+
IPAゴシック
でPNG生成
本文でMikanOSのソースコー
ドを引用する
「ゼロからのOS自作入門」の特性
MikanOS自体の開発の歴史と、本文の執筆の歴史がある
本文でMikanOSのソースコードを引用する
MikanOSの過去のバージョンを直したくなることがある
本文の説明をストレートにするため
MikanOSの
Gitリポジトリ
本文の
Gitリポジトリ
day01 day02 day03
コードの引用
2つの歴史
MikanOSは大規模なソフトウェア
→専用のリポジトリが欲しい
https://github.com/uchan-nos/mikanos
本文も大規模になるので、バージョン管理したい
https://github.com/uchan-nos/legacy-free-os-book
MikanOSの実装を進めつつ本文を執筆
2つのGitリポジトリが、並行に進展
MikanOSのソースコードを引用する
MikanOSのソースコードを解説するために、本文に引用したい
手動でコピペするとミスが出る
Re:VIEWのファイル埋め込み機能が使えそう!
#@mapfile(ファイル名)~#@end
と書くと、そのファイルの内容を展開してくれる
//list[list_tag][リストタイトル]{
#@mapfile(foo.c)
#@end
//}
プリプロセッサが
ソースコード
を展開する
masterブランチから引用する?
問題:最新版のソースコードを引用するので大丈夫?
答え:ダメ。章ごとに機能を追加していくから。
特定のバージョンを引用したい
//list[main][MikanOSのメイン関数]{
#@mapfile(../mikanos/kernel/main.cpp)
#@end
//}
MikanOSの
Gitリポジトリ
day03 master
day04
引用するバージョンを固定したい
タグ
ブランチ
main.cppの内容の変遷
extern "C" void KernelMain() {
while (1) __asm__("hlt");
}
osbook_day03aのmain.cpp
#include <cstdint>
extern "C" void KernelMain(uint64_t frame_buffer_base,
uint64_t frame_buffer_size) {
uint8_t* frame_buffer = reinterpret_cast<uint8_t*>(frame_buffer_base);
for (uint64_t i = 0; i < frame_buffer_size; ++i) {
frame_buffer[i] = i % 256;
}
while (1) __asm__("hlt");
}
osbook_day03cのmain.cpp
タグXのmain.cppを引用する
main.cppを引用する
タグを指定して引用したい
タグ毎にファイルを配置したディレクトリを用意すればできる
実際に、こんなディレクトリ構成にしてみた
text/
images/
dayN.re
…
distrib/
dayN/
MikanLoaderPkg/Main.c
kernel/main.cpp
…
…
タグを指定して引用する
タグ毎にファイルを配置したディレクトリを用意すればできる
実際に、こんなディレクトリ構成にしてみた
text/
images/
dayN.re
…
distrib/
dayN/
MikanLoaderPkg/Main.c
kernel/main.cpp
…
…
希望のタグから
ソースコードを引用する
osbook_dayN
タグに対応
タグを指定して引用する
//list[day02a_Main.c][EDK IIを使ったハローワールドアプリ(Main.c)][c]{
#@mapfile(../distrib/day02a/MikanLoaderPkg/Main.c)
#include <Uefi.h>
#include <Library/UefiLib.h>
EFI_STATUS EFIAPI UefiMain(
EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *system_table) {
Print(L"Hello, Mikan World!n");
while (1);
return EFI_SUCCESS;
}
#@end
//}
ハローワールドプログラムの本体は@<tt>{Main.c}ファイルです。
@<list>{day02a_Main.c}にその全体を示します。
Re:VIEWを使った本文の例
タグ内容を抽出するツール
osbook_dayNというタグに対応するソースコードを取得し
distrib/dayNディレクトリに展開したい
専用ツールgit-extract-tagsを作りました
https://github.com/uchan-nos/git-extract-tags
使い方
$ git extract-tags -s distrib 
osbook_ ../mikanos
プレフィクスが「osbook_」であるタグから
ファイルを抽出してdistribに書き出す
legacy-free-os-book/
text/
images/
dayN.re
…
distrib/
dayN/
…
mikanos/
MikanLoaderPkg/
kernel/
…
想定するディレクトリ構成
MikanOSの過去のバージョン
を直したくなることがある
ソフトウェアにはバグがある
執筆中にOSのバグを見つけることがよくある
解説文を書いていると、コードの動作を深く考えるから、余計に。
osbook_day06cでバグを入れてしまったことに
第20章を執筆中に気付くと、大変辛い。
6c、20という数字はただの例。後で見つかれば見つかるほど辛い
選択肢1:第20章に「osbook_day06cの実装にバグがあったので、
直します」みたいな解説文を書き、osbook_day20xを修正する
選択肢2:osbook_day06cに修正を加え、何事も無かったかのよう
に執筆を進める
MikanOSの歴史を綺麗に保つ
やはり「選択肢2」を取りたい
選択肢1の方がリアルな開発姿勢だが、解説がごちゃごちゃする
ただでさえ大変なOS自作なので、解説くらいは綺麗にしたい
Gitで過去のバージョンを修正するには?
→リベース!
MikanOSの
Gitリポジトリ
本文の
Gitリポジトリ
day06b day06c master
…
…
master
リベース
A B C
day06b
D
day06c master
X
…
a バグ修正コミット
リベース:Cのベースをaに付け替える
A B C
day06b
D
day06c
master
X
…
a …
C’ D’ X’
1. バグ修正を
コミットする
2. リベースする
リベースの問題点
MikanOSの利用者が困惑する
公開されたブランチをリベースするのは混乱の元
MikanOSでは、しばらくはリベースがたくさん発生するよ、とREADME
に書いた
タグが付け変わらない
day06cがCを指したまま
C’を指して欲しい
タグを手動で付け替えるのは大変
BからXまでの、全タグを付け替える必要あり
リベース作業はバグ発見のたびに何度も発生
B C D
day06c
master
X
…
a …
C’ D’ X’
タグを付け替えるツール
元のブランチからリベース先のブランチへ各タグを移動したい
専用ツールgit-retagを作りました
https://github.com/uchan-nos/git-extract-tags
使い方
$ git retag osbook_ old new
プレフィクスが「osbook_」であるタグを、oldからnewへ付け替える
A B C
tag1
new
E
a B’ C’ E’
old
D
D’
tag2
タグ付け替えの例
「handle close button」と「exit
task on window close」の間に修
正を挿入する例
 挿入した修正「hoge-fix」
「osbook_dayX」というタグす
べてを、「new-day30f」ブラン
チに移動したい
git-retag使用例
git retag
--dry-run
osbook_
osbook_day30f
new-day30f
指定した2つのブラン
チの共通の祖先を見つ
け、
プレフィクスが
「osbook_」であるタ
グを移動する
Git rebase入門
コミットグラフを理解しよう
リベース操作は複雑で分かりにくい?
コミットグラフの変化が想像できるようになれば、怖くない!
コミット:ワークツリー全体のスナップショット
 Diffではない
ブランチ:コミットを指すラベル
 コミットの列、ではない
A B C D
master
コミット
ブランチ
コミットはDiffではない
コミットは、親に対する差分、ではない
コミットは、ワークツリー全体のスナップショットである
1つのコミットは、管理対象の全ファイルの完全な内容を持つ
もちろん、無変更のファイルの内容は持たない、などの最適化はある
Diffではないので、自由に組み替え可能
A B C
リベース
A B C D
master
a
$ git checkout -b fix-bug B
《ワークツリーを修正》
$ git commit -a
$ git rebase fix-bug master
fix-bug
A B
master
a
fix-bug
C’ D’
リベース(interactiveモード)
非常に多用途な git rebase -i
コミットの順番を入れ替える、
不要なコミットを捨てる、
コミットメッセージを修正する、など
A B C D
master
ここを入れ替えたいなあ……
$ git checkout master
$ git rebase -i A
行を入れ替えて保存
git rebase -iのその他の機能
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
#
# These lines can be re-ordered; they are executed from top to bottom.
「pick」を希望のコマンドに書き換える
コミットグラフを理解する便利なコマンド
$ git log --graph --all
ここで枝分かれして
ここでマージされた
間違ったリベースを無かったことにする
Git reflog
「ブランチやタグ等が、過去何を指していたか」が
コミットやリベース等、Gitの操作をするたびに記録される
リベースなどでミスしてもデータが失われるわけではないので、
安心して実験しましょう
ブランチを任意のコミットに付け直すには
$ git checkout <branch>
$ git reset --hard <commit>
まとめ
「ゼロからのOS自作入門」の執筆に様々なOSSを使った
Re:VIEW、review-text-imager、Git、git-extract-tags
ラフ図案をASCIIアートで→pngnize-image-body
「ゼロからのOS自作入門」は2本のGitリポジトリで構成される
タグを指定したソースコード引用を行いたい→git-extract-tags
引用プログラムのバグを直したい→git-retag
リベースを使いこなそう

More Related Content

More from uchan_nos

USB3.0ドライバ開発の道
USB3.0ドライバ開発の道USB3.0ドライバ開発の道
USB3.0ドライバ開発の道uchan_nos
 
Security Nextcamp remote mob programming
Security Nextcamp remote mob programmingSecurity Nextcamp remote mob programming
Security Nextcamp remote mob programminguchan_nos
 
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPSLangsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPSuchan_nos
 
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作uchan_nos
 
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装uchan_nos
 
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPGuchan_nos
 
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free osレガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free osuchan_nos
 
Building libc++ for toy OS
Building libc++ for toy OSBuilding libc++ for toy OS
Building libc++ for toy OSuchan_nos
 
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019プランクトンサミットの歴史2019
プランクトンサミットの歴史2019uchan_nos
 
Introduction of security camp 2019
Introduction of security camp 2019Introduction of security camp 2019
Introduction of security camp 2019uchan_nos
 
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.230分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2uchan_nos
 
USB3 host driver program structure
USB3 host driver program structureUSB3 host driver program structure
USB3 host driver program structureuchan_nos
 
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)uchan_nos
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方uchan_nos
 
1TB/dayのログを収集・蓄積する技術
1TB/dayのログを収集・蓄積する技術1TB/dayのログを収集・蓄積する技術
1TB/dayのログを収集・蓄積する技術uchan_nos
 
WalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block DevicesWalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block Devicesuchan_nos
 
5分で分かるサイボウズのSRE
5分で分かるサイボウズのSRE5分で分かるサイボウズのSRE
5分で分かるサイボウズのSREuchan_nos
 
UEFIによるELFバイナリの起動
UEFIによるELFバイナリの起動UEFIによるELFバイナリの起動
UEFIによるELFバイナリの起動uchan_nos
 
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイント
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイントLinuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイント
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイントuchan_nos
 

More from uchan_nos (20)

USB3.0ドライバ開発の道
USB3.0ドライバ開発の道USB3.0ドライバ開発の道
USB3.0ドライバ開発の道
 
Security Nextcamp remote mob programming
Security Nextcamp remote mob programmingSecurity Nextcamp remote mob programming
Security Nextcamp remote mob programming
 
Langsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPSLangsmith OpeLa handmade self-hosted OS and LPS
Langsmith OpeLa handmade self-hosted OS and LPS
 
OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作OpeLa セルフホストなOSと言語処理系の自作
OpeLa セルフホストなOSと言語処理系の自作
 
自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装自動でバグを見つける!プログラム解析と動的バイナリ計装
自動でバグを見つける!プログラム解析と動的バイナリ計装
 
1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG1を書いても0が読める!?隠れた重要命令INVLPG
1を書いても0が読める!?隠れた重要命令INVLPG
 
レガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free osレガシーフリーOSに必要な要素技術 legacy free os
レガシーフリーOSに必要な要素技術 legacy free os
 
Building libc++ for toy OS
Building libc++ for toy OSBuilding libc++ for toy OS
Building libc++ for toy OS
 
プランクトンサミットの歴史2019
プランクトンサミットの歴史2019プランクトンサミットの歴史2019
プランクトンサミットの歴史2019
 
Introduction of security camp 2019
Introduction of security camp 2019Introduction of security camp 2019
Introduction of security camp 2019
 
30分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.230分で分かる!OSの作り方 ver.2
30分で分かる!OSの作り方 ver.2
 
Timers
TimersTimers
Timers
 
USB3 host driver program structure
USB3 host driver program structureUSB3 host driver program structure
USB3 host driver program structure
 
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
業務時間で書いたパッチは誰のもの?OSS活動にまつわる罠 (builderscon tokyo 2018)
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方
 
1TB/dayのログを収集・蓄積する技術
1TB/dayのログを収集・蓄積する技術1TB/dayのログを収集・蓄積する技術
1TB/dayのログを収集・蓄積する技術
 
WalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block DevicesWalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block Devices
 
5分で分かるサイボウズのSRE
5分で分かるサイボウズのSRE5分で分かるサイボウズのSRE
5分で分かるサイボウズのSRE
 
UEFIによるELFバイナリの起動
UEFIによるELFバイナリの起動UEFIによるELFバイナリの起動
UEFIによるELFバイナリの起動
 
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイント
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイントLinuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイント
Linuxカーネルモジュール自作入門 kprobesでカーネル空間ブレークポイント
 

OSC2021 Nagoya 「ゼロからのOS自作入門」の執筆を支える技術