ゼロからのOS自作入門 書籍への質問を分析

2.6K Views

November 26, 23

スライド概要

ゼロからのOS自作入門サポートサイト(GitHub)に寄せられた質問を分析し、カテゴリ分類を試みます。読者がどんな疑問を持つのか、どこに躓きやすいのかを知り、今後の改善方針の参考になればいいなと思います。

profile-image

サイボウズ・ラボ株式会社で教育向けのOSやCPU、コンパイラなどの研究開発をしています。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

ゼロからのOS自作入門 書籍への質問を分析 2023年11月26日 第36回 自作OSもくもく会 サイボウズ・ラボ @uchan_nos 1

2.

自己紹介 ⚫内田公太 @uchan_nos ⚫サイボウズ・ラボ株式会社 ◼ OSと言語処理系の研究開発 ◼ ComProc ⚫自作OSコミュニティ「osdev-jp」の運営 ⚫著書: ◼ ゼロからのOS自作入門 ◼ 自作エミュレータで学ぶx86アーキテクチャ 2

3.

発表概要 ⚫ゼロからのOS自作入門サポー 質問件数の割合 トサイト(GitHub)に寄せら れた質問を分析 ⚫カテゴリ分類 ⚫何件か中身を紹介 ⚫読者がどんな疑問を持つのか ⚫どこに躓きやすいのか ⚫今後の改善方針の参考に 誤植・表現修正提案 環境特有の問題 MikanOSのバグ 写経ミス Linuxコマンド操作 EDKII環境 lldバージョン10での挙動変更 質問者の勘違い コードや内容の疑問 パスとlnコマンド ブートローダーリビルド忘れ mikanos-buildの特殊性 UEFIプログラミング Ubuntuバージョン不整合 USBメモリのフォーマット その他 3

4.

サポートサイト ⚫「ゼロからのOS自作入門」のサポートはGitHub ◼ https://github.com/uchan-nos/os-from-zero/ ⚫正誤情報を得たり、質疑応答したりできる ⚫質疑応答はGitHub Issuesを使用 ⚫今までに145件の質疑が解決済み (Issueがクローズ済み) ⚫今回、この145件を分析した ◼ mikanos、mikanos-buildリポジトリ のIssueは分析対象外(間に合わず) 4

5.

Issueをカテゴリに分類 分類 件数 割合 誤植・表現修正提案 44 31.0% 環境特有の問題 16 11.3% MikanOSのバグ 11 7.7% 写経ミス 11 7.7% Linuxコマンド操作 11 7.7% EDKII環境 11 7.7% lldバージョン10での挙動変更 6 4.2% 質問者の勘違い 6 4.2% コードや内容の疑問 5 3.5% パスとlnコマンド 4 2.8% ブートローダーリビルド忘れ 4 2.8% mikanos-buildの特殊性 4 2.8% UEFIプログラミング 3 2.1% Ubuntuバージョン不整合 3 2.1% USBメモリのフォーマット 2 1.4% その他 1 0.7% 142 ⚫カテゴリ分けは筆者による ⚫そのIssueの真の原因によって 分類 ◼ 質問者が推測した原因ではなく、 筆者が推測した原因 ◼ Closedだが未解決のIssueについ ては、原因を推測して分類 5

6.

カテゴリ紹介 各カテゴリの説明、カテゴリに属するIssueの実例 6

7.

誤植・表現修正提案(31.0%) カテゴリ説明 本文やサポートサイトに関する誤植・表現修正提案 Issue実例 7

8.

環境特有の問題(11.3%) 1/2 カテゴリ説明 原因が質問者の環境に依存すると思われるIssue Issue実例 8

9.

環境特有の問題(11.3%) 2/2 9

10.

MikanOSのバグ(7.7%) カテゴリ説明 MikanOSのソースコードのバグ Issue実例 10

11.

写経ミス(7.7%) 1/2 カテゴリ説明 ソースコードやコマンドの入力間違い Issue実例 #41は lldバージョン10 での挙動変更 11

12.

写経ミス(7.7%) 2/2 12

13.

Linuxコマンド操作(7.7%) カテゴリ説明 LinuxやWSLでのコマンド操作に関連するIssue Issue実例 13

14.

EDKⅡ環境(7.7%) カテゴリ説明 EDKⅡに関連するIssue Issue実例 14

15.

lldバージョン10での挙動変更(4.2%) カテゴリ説明 リンカlldのバージョン10で導入された変更の影響によるIssue Issue実例 16

16.

lldのバージョン10で導入された変更 ⚫lld-10は、書籍執筆時に使ったlld-7と挙動が異なる ⚫👌変更により、コンパクトなバイナリが出力される ⚫😞MikanOSのブートローダーが想定しないバイナリになる ld.lld-7の 出力バイナリ ld.lld-10の 出力バイナリ Type Offset VirtAddr FileSiz MemSiz Flags Align PHDR 0x00000040 0x00100040 0x00e0 0x00e0 R 0x8 LAOD 0x00000000 0x00100000 0x01b0 0x01b0 R 0x1000 LOAD 0x00001000 0x00101000 0x1000 0x1000 RE 0x1000 Type Offset VirtAddr FileSiz MemSiz Flags Align PHDR 0x00000040 0x00100040 0x00e0 0x00e0 R 0x8 LAOD 0x00000000 0x00100000 0x01b0 0x01b0 R 0x1000 LOAD 0x000001b0 0x001011b0 0x0183 0x0183 RE 0x1000 17

17.

ld.lld-7のバイナリのロード メモリ上での配置 ld.lld-7の出力バイナリ メモリへロード 0x0000 0x0040 プログラムヘッダ 0x0120 .rodata 0x01b0 0x1000 1つ目の LOAD セグメント 0xccパディング 0x100040 ELFヘッダ プログラムヘッダ 0x100120 .rodata 0x1001b0 0x00パディング .text 0x2000 0x100000 ELFヘッダ 0x101000 2つ目の LOAD セグメント .text 0x102000 1ページ(4KiB=0x1000B)ずつコピーできる 0xccパディング 18

18.

ld.lld-10のバイナリのロード メモリ上での配置 ld.lld-10の出力バイナリ メモリへロード 0x0000 0x0040 0x100000 ELFヘッダ プログラムヘッダ 0x0120 .rodata 0x01b0 .text 1つ目の LOAD セグメント 0x100040 2つ目の LOAD セグメント 0x1001b0 ELFヘッダ プログラムヘッダ 0x100120 .rodata 0x101000 0x1011b0 0x101333 1ページずつのコピーでは上手く行かない! .text 19

19.

-z separate-code ⚫lldの新しいバージョンでも、「-z separate-code」を付けたら解 決したという報告 ◼ https://github.com/uchan-nos/os-from-zero/issues/41#issuecomment-817331103 ⚫-z separate-codeとは ◼ https://man.archlinux.org/man/extra/lld/ld.lld.1.en#separate-loadable-segments ◼ PT_LOADセグメントの重なり(overlap)を制御するオプションの1つ ⚫MikanOSに手を加えず解決するならseparate-loadable-segments が正解か separate-loadable-segments いずれのセグメントも重ならないようにする separate-code 実行可能と不可能セグメントが互いに重ならないよう にする(同種のセグメント同士は重なる?) noseparate-code 重なりを許す 21

20.

パスとlnコマンド(2.8%) カテゴリ説明 ファイルパスやlnコマンドの挙動についての知識不足からくるIssue Issue実例 22

21.

/path/to/…は鬼門 EDK II のディレクトリに MikanOS ブートローダーのディレクトリをリンクします。 $ cd $HOME/edk2 $ ln -s /path/to/mikanos/MikanLoaderPkg ./ /path/to/mikanos は先ほど git clone でダウンロードした mikanos ディレクトリへの パスを指定します。 ⚫MikanOSの開発環境のセットアップ指示の一節 ⚫/path/to/mikanos をそのまま打ち込む人が続出 ⚫ln -sは、既存のリンクを上書きせずエラーになるので、rmせずに 再実行しても直らない ◼ 再実行時はln -sfが正解 23

22.

ブートローダーリビルド忘れ(2.8%) カテゴリ説明 ブートローダーのリビルドをしなかったことに起因するIssue Issue実例 24

23.

std::functionを使用すると停止する #57 ⚫質問者と私以外にも、1人の協力者を交えた議論が進行 ◼ 22通の返信が連なる(MikanOS的には)長大なIssueに成長 ◼ 質問者からビルド済みバイナリを含むリポジトリ一式をもらうなど、高度 なデバッグを展開 ⚫直接の原因:std::function型の変数が初期化されていなかった ⚫その原因:静的変数領域(.bss)を0クリアする改造を入れたブー トローダーをビルドしていなかった mikanos-build makeコマンド カーネル(kernel.elf) ビルドシステムが別 EDKⅡ buildコマンド ブートローダー(Loader.efi) 25

24.

Issueの時系列変化 カテゴリの時系列変化 50 45 40 35 件数 30 2022年4月 25 2021年6月 20 15 10 5 0 Issue番号 2021年3月 =出版日 誤植・表現修正提案 UEFIプログラミング Linuxコマンド操作 USBメモリのフォーマット 環境特有の問題 MikanOSのバグ パスとlnコマンド 写経ミス EDKII環境 lldバージョン10での挙動変更 質問者の勘違い コードや内容の疑問 ブートローダーリビルド忘れ mikanos-buildの特殊性 Ubuntuバージョン不整合 その他 2023年10月 29

25.

対策、反省 31

26.

これだけは知っておきたいLinuxコマンド ⚫本書でLinuxを初めて触る人向けのコマンド解説ドキュメント ◼ https://github.com/uchan-nos/os-from-zero/wiki/Basic-Linux-Commands ◼ 本書によく出てくるコマンドに限定 ⚫目次 ◼ lsコマンド ◼ pwdコマンド と cdコマンド ◼ lnコマンド ◼ rmコマンド ◼ 変数 ◼ echoコマンド ◼ mvコマンド ◼ 「.」と「..」 ◼ mvコマンドの最後の「/」 ◼ コマンドの成否 32

27.

GDB ⚫質問者の中にはGDBを使える人は少なそう ◼ 「GDB」でヒットするのは145件中3件 ◼ うち2件は同一質問者なので、ユーザー数は2 ⚫本書ではQEMUモニタの説明だけした ◼ GDBを説明するのは難しいかなと思ったので ⚫MikanOS開発に焦点を当てたGDB入門記事があると良いかも ⚫デバッグだけでなく、動きを追うのにも活躍するし! 33

28.

Macでやりたい人が多い ⚫本書の公式環境はUbuntuまたはWSL ⚫Macは未サポート ◼ 普段Mac使わない ◼ Macは開発に不向きだと思っている ⚫「mikanos mac」でGoogle検索すると 大量の記事がヒット ⚫Mac(Arm)では、x86-64向けOSの MikanOSをネイティブ開発はできない ⚫多くはDocker on Macでやってる 34

29.

コードに関する質問が少ない ⚫コードや内容の疑問はたった3.5% ⚫その他は誤植やビルドエラーなど ⚫当初は、コードの意図を聞くような質問がたくさん来るかなと 思っていた ⚫OS開発の難しさは、コード内容より開発環境にある、ということ かもしれない 35

30.

読者と筆者の成長に役立つ ⚫Issueでのやり取りを通じて成長していく ◼ 質問者:Linuxのターミナル操作 ◼ お互い:質問の仕方 例: https://github.com/uchan-nos/os-from-zero/issues/93 36

31.

Issueピックアップ 37

32.

英語での質問 ⚫please help me solve it #136 ◼ https://github.com/uchan-nos/os-from-zero/issues/136 ⚫質問内容は基本的なこと ◼ llvm-7が無い環境で開発環境をセットアップしようとして、エラー ⚫それが英文で来る不思議 ⚫本書は日本語と韓国語でしか出てないはず ◼ 中国語翻訳の話はどうなったんだろう… ⚫韓国の方が英語で質問したのだろうか? ⚫国際的に読まれる本書! 39

33.

余分なコードは読者に混乱をもたらす ⚫[質問]LocalAPICタイマについて #124 ◼ https://github.com/uchan-nos/os-from-zero/issues/124 ⚫9.4「重ね合わせ処理の時間計測」でLocal APICタイマを初期化す るコードで「32」をORしている理由は? ⚫lvt_timer = (0b001 << 16) | 32; //masked, one-shot ⚫割り込みを発生させて実験していたときの名残と思われる ⚫このような些細なコードでも読者は気になって眠れなくなってし まう 40

34.

LVT Timerレジスタ lvt_timer = (0b001 << 16) | 32; //masked, one-shot ⚫Timer Mode=0:ワンショット ⚫Mask=1:割り込み不許可 ⚫Vector=32:割り込みベクタ番号 が32 ◼ Mask=1のため割り込みは発生しない から、Vectorの設定値には意味がな い 図はIntel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3より引用 41

35.

発表まとめ ⚫ゼロからのOS自作入門サポートサイトに寄せられた質問を分析 ⚫カテゴリ分類 ⚫各カテゴリの例を紹介 ⚫対策としてLinuxコマンドのドキュメントを作成 ⚫反省点がいくつか ◼ GDBの解説があった方が良いかも ◼ Macを公式にサポートすると嬉しい人が多い? ◼ コードの内容以外に関する質問が多かった ⚫いくつかのIssueをピックアップして紹介 43