💽

OSを1000行で書いてみた(をやってみる): 01

に公開

留学によってとれなかった授業であるOS(Operating System)の講義の内容の埋め合わせをしたいと思っています.
 ネット上にあるいくつかの大学の講義資料と共に、少し前に話題になった"OSを1000行で作る" に手を出してみます.よかったら一緒に読んでつくってみませんか.
第一回は05. "Hello World!を表示する" まで行きます.
WSL2インストールしてUbuntu上で動かしてます.
個人的に情報付け足しておきたい部分を書いています.

https://operating-system-in-1000-lines.vercel.app/ja/

01 開発環境.

とりあえずなんだこれ?となると思いますが,まずはインストールを済ませてしまいましょう.OpenSBIとQEMUについての説明は後ほど.

02 RISK-Vについて.

オープンソースライセンスの命令セットアーキテクチャ.日本でもやったし、イタリアでもこれで勉強した.私はちゃんと自分で実装したことないので実装してみたい.
一応説明しておくと、RISK-Vはただの言語(ex. add x1, x2, x3)
私たちが作るのはOSであって、RISC-Vで実装されたCPU上でOS(たとえば xv6-riscv や Linux-riscvなど)が動いてその上でemacsなどのアプリケーションが走る、その根幹部分である.
CSR: Control and Status Register

03 03 OSの全体像.

本プロジェクトを通してシンプルなOSを作成できる.(いくつかの内容は欠けているが重要な部分は満たしている)

04 ブート処理

RISK-Vの3つのモード

まずはRISK-Vのモードについて説明.

モード 概要
M-mode 最も特権が高い.ファーム/ハードウェア制御
S-mode カーネルが動作するモード
U-mode アプリケーションが動作するモード

この3つのモードのうち,Mモードで実行されるファームウェアである.つまり,SBIとは一番偉い管理者権限を持ってるソフト.
OpenSBI: Supervisor Binary Interfaceのオープンソースの実装.
OS(S-Mode:カーネルが動作する)とSEE(M-Mode:最も権限が強い)のインターフェースの役割を果たす部分である.

QEMU:(generic and open source)machine emulator/virtualizer


リンカスクリプト(拡張子.ld): プログラムの各データ領域をメモリ上にどう配置するかを指定する.OSや組込みシステムでのメモリの正確な制御のために必要.

ここから少し初見だと難しくなると思うので、注意深く.
リンカスクリプトは、メモリ(演算命令を持ってきて実行するところ)の領域を規定します.

↓以下のサイトが分かりやすかったのでお借りしました.
https://www.momoyama-usagi.com/entry/info-calc-sys13

Cの授業とか計算機構成の演習とか,コンピュータアーキテクチャなどの授業でさらっと勉強した記憶.これらの領域を規定していきます.

kernel.ld
ENTRY(boot)

SECTIONS {
    . = 0x80200000;

    .text :{
        KEEP(*(.text.boot));
        *(.text .text.*);
    }

    .rodata : ALIGN(4) {
        *(.rodata .rodata.*);
    }

    .data : ALIGN(4) {
        *(.data .data.*);
    }

    .bss : ALIGN(4) {
        __bss = .;
        *(.bss .bss.* .sbss .sbss.*);
        __bss_end = .;
    }

    . = ALIGN(4);
    . += 128 * 1024; /* 128KB */
    __stack_top = .;
}

ここでは,
.text : コード領域
.rodata: 定数データ領域.読み取り専用.(初期値あり)
.data: 読み書き可能データ領域.(ヒープ、スタックのことと解釈)
.bss: 読み書き可能データ領域.(初期値なし)
という風に宣言しています.
これにプラスアルファでいくつか設定すると…

x0/zero  00000000 x1/ra    8000a084 x2/sp    80032f30 x3/gp    00000000
 x4/tp    80033000 x5/t0    00000001 x6/t1    00000000 x7/t2    00000000
 x8/s0    80032f50 x9/s1    00000001 x10/a0   00000000 x11/a1   87000000
 x12/a2   00000007 x13/a3   00000019 x14/a4   4014112d x15/a5   00000001
 x16/a6   00000008 x17/a7   00000002 x18/s2   00000000 x19/s3   00000000
 x20/s4   87000000 x21/s5   00000000 x22/s6   80006800 x23/s7   8001c020
 x24/s8   00002000 x25/s9   8002b4e4 x26/s10  00000000 x27/s11  00000000
 x28/t3   616d6569 x29/t4   8001a5a1 x30/t5   000000fc x31/t6   00000000
 f0/ft0   ffffffff00000000 f1/ft1   ffffffff00000000 f2/ft2   ffffffff00000000 f3/ft3   ffffffff00000000
 f4/ft4   ffffffff00000000 f5/ft5   ffffffff00000000 f6/ft6   ffffffff00000000 f7/ft7   ffffffff00000000
 f8/fs0   ffffffff00000000 f9/fs1   ffffffff00000000 f10/fa0  ffffffff00000000 f11/fa1  ffffffff00000000
 f12/fa2  ffffffff00000000 f13/fa3  ffffffff00000000 f14/fa4  ffffffff00000000 f15/fa5  ffffffff00000000
 f16/fa6  ffffffff00000000 f17/fa7  ffffffff00000000 f18/fs2  ffffffff00000000 f19/fs3  ffffffff00000000
 f20/fs4  ffffffff00000000 f21/fs5  ffffffff00000000 f22/fs6  ffffffff00000000 f23/fs7  ffffffff00000000
 f24/fs8  ffffffff00000000 f25/fs9  ffffffff00000000 f26/fs10 ffffffff00000000 f27/fs11 ffffffff00000000
 f28/ft8  ffffffff00000000 f29/ft9  ffffffff00000000 f30/ft10 ffffffff00000000 f31/ft11 ffffffff00000000

ただしくレジスタなどが設定されました(詳しくは元サイトをご覧ください.)見覚えのあるx0-x31/f0-f31のレジスタがでてきたので満足です.

05 hello world!

kernel.h上でOpenSBIを呼び出すことで実現していると理解しました.Console Putcharを用いて,一文字ずつ画面に出力していく.

OpenSBI v1.2
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|
--中略--
Hello World!

なんだかんだあってなんとかHello Worldできました.やり方は参考リンク先に書いてある通りです.よくあることだけど、なぜか動かなくて色々試したらいつの間にか動いた.結局なぜうまくいったのか理由が分からず悔しい.これを一から書いた人は本当にすごいと思います.
次はprintf 関数を実装します.
間違っている内容あったら教えてほしいです.使用させていただいた資料,技術等に感謝申し上げます.

Discussion