この記事は自作OS Advent Calendar 2020の9日目の記事です。
最近は大学の課題や様々な用事、精神的事情が重なってなかなかプログラムがかけてませんがアドベントカレンダーの枠が空いていたので短いですが急遽この記事を書いてみました。
最近、私の自作OS – Methylenixでマルチコア(SMP)対応を行いました。
https://github.com/PG-MANA/Methylenix
自作OSのMethylenixでSMP対応に成功して一応、簡単なタスク管理はできるようになった。
— PG_MANA (@PG_MANA_) November 23, 2020
ここからは本格的にタスク管理機構の設計をする
動画は一秒ごとに各CPUが画面に文字を表示するようにした場面 pic.twitter.com/oww6JXZfCR
このOSはx86_64用に開発されているわけですが、x86_64では通常起動直後はBSP(BootStrap Processor)のみが動作しておりそれ以外のコアは停止しています。そのためにBSPがAP(Application Processor)を適切に初期化してあげる必要があり、これにはUEFIのMpServiceというものを使用するか(よく知らないので詳細はここでは説明できない)、LocalAPICのプロセッサ間通信を利用します。
Methylenixでは後者を選択しており、
https://github.com/PG-MANA/Methylenix/blob/11239235352ac46a051999edd47ae0590ba5f6c7/src/arch/x86_64/init.rs#L269で実装されています。
この方式ではAPが16bitリアルモードで立ち上がってきてしまうので、メモリアドレスが1MB以下の場所のメモリの確保やブートコードの転送などいろいろなことをしています…(ここらへんの設計が地味に辛かった…)
一方RISC-VなどのRISC系のCPUは起動と同時に全てのコアが一斉にエントリポイントを実行することが多く、この場合はコアIDを見ながらセマフォなどの排他処理を最初から行わないとスタックの競合やUARTの出力がダブるなど(HeHello,o, wwoorrldld!!となるなど)するので注意が必要です。RISC-VボードのSDKなどでif(core_id == 0){…}などあるのはこのためです。
x86_64でのマルチコア対応などをまとめてしっかりとした文章にしたいな…