競プロ雑記帳

ゼロからのOS自作入門(MikanOS)のday03aでカーネルの読み込みがうまくいかない

下記の本を買ってからしばらく放置していたのですが、重い腰を上げてRustでやり始めました。
zero.osdev.jp

問題

day03a 初めてのカーネルを書いて実行し、qemuで見たところ明らかに違うアドレスがRIPに表示されていました。
一応RIP前後の命令を見ましたがhltは見当たりませんでした。

原因

同じような問題は結構起きているようで、サポートのレポジトリで何件が議論されていました。

github.com
github.com

上記に書いてある通り、リンカのバージョンが新しくなって仕様が変わったため、起こるバグのようです。

解決策

リンカの問題ということが分かったので、バージョンを下げるという手もありますが、リンカのオプションを追加するだけで治すことができます。

ld.lldのドキュメントを見ると、

Specify whether two adjacent PT_LOAD segments are allowed to overlap in pages. noseparate-code (default) allows overlap. separate-code allows overlap between two executable segments, or two non-executable segments. separate-loadable-segments disallows overlap.

ld(1) - OpenBSD manual pages

のように記述があります。
従って、リンカのオプションに -z separate-loadable-segments を追加することで治すことができます。

先ほど挙げたURLのIssueに書かれているように、day04d ローダを改良するを先に書くことでも治すことができます。