LoginSignup
5
2

More than 5 years have passed since last update.

30日で作るosのソースコードと軽い解説~7日まで (1) Bootstrap

Last updated at Posted at 2018-05-30

5日までのまとめ

現在30日で作るosの本を読んでます。それで、今回は7日までで出来上がったソースコードを軽く説明して行きたいと思います。

正直、自分でも全部理解している自信がないので理解できる範囲で説明して行きたいと考えております。

qiitaの投稿も今回がはじめてなので、修正点やアドバイスなどありがたくお待ちしております

では、やっていきましょう!!!!

osの起動(記憶媒体からメモリにプログラムを書き込む処理)

まず、osをどのようにして、起動するかについて説明しています。
前提条件として、記憶媒体は、フロッピーディスクをこの本では扱っています。
また、アセンブラ?にはnasmと言うソフトを活用しています。

パソコンに、電源が入ってから何をするかを教える必要があります。
これを、Bootstrapといいます。
まず、はじめにパソコンに電源が入るとcpuはBIOS ROMのプログラムにアクセスします。そして、現在使用されているマザーボードにどのような周辺機器が接続されているか確認します。

BIOSのプログラムが最後行う処理は、現在ユーザが起動に使おうとしたディスクのはじめの512バイト(MBR領域とも言います)を読み込みます。
以下のプログラムはそのmbrで読み込まれるソースコードになっています。

boot.nas
CYLS    EQU     10              ; どこまで読み込むか

        ORG     0x7c00          ; このプログラムがどこに読み込まれるのか

entry:
        MOV     AX,0            ; レジスタ初期化
        MOV     SS,AX
        MOV     SP,0x7c00
        MOV     DS,AX

; ディスクを読む

        MOV     AX,0x0820
        MOV     ES,AX
        MOV     CH,0            ; シリンダ0
        MOV     DH,0            ; ヘッド0
        MOV     CL,2            ; セクタ2
readloop:
        MOV     SI,0            ; 失敗回数を数えるレジスタ
retry:
        MOV     AH,0x02         ; AH=0x02 : ディスク読み込み
        MOV     AL,1            ; 1セクタ
        MOV     BX,0
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ディスクBIOS呼び出し
        JNC     next            ; エラーがおきなければnextへ
        ADD     SI,1            ; SIに1を足す
        CMP     SI,5            ; SIと5を比較
        JAE     error           ; SI >= 5 だったらerrorへ
        MOV     AH,0x00
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ドライブのリセット
        JMP     retry
next:
        MOV     AX,ES           ; アドレスを0x200進める
        ADD     AX,0x0020
        MOV     ES,AX           ; ADD ES,0x020 という命令がないのでこうしている
        ADD     CL,1            ; CLに1を足す
        CMP     CL,18           ; CLと18を比較
        JBE     readloop        ; CL <= 18 だったらreadloopへ
        MOV     CL,1
        ADD     DH,1
        CMP     DH,2
        JB      readloop        ; DH < 2 だったらreadloopへ
        MOV     DH,0
        ADD     CH,1
        CMP     CH,CYLS
        JB      readloop        ; CH < CYLS だったらreadloopへ

; 読み終わったのでharibote.sysを実行だ!

        MOV     [0x0ff0],CH     ; IPLがどこまで読んだのかをメモ
        JMP     0xc200

error:
        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1            ; SIに1を足す
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e         ; 一文字表示ファンクション
        MOV     BX,15           ; カラーコード
        INT     0x10            ; ビデオBIOS呼び出し
        JMP     putloop
fin:
        HLT                     ; 何かあるまでCPUを停止させる
        JMP     fin             ; 無限ループ
msg:
        DB      0x0a, 0x0a      ; 改行を2つ
        DB      "load error"
        DB      0x0a            ; 改行
        DB      0

        RESB    0x7dfe-$        ; 0x7dfeまでを0x00で埋める命令

        DB      0x55, 0xaa

アセンブラ言語に慣れていない僕は軽く、吐き気がありますが笑
がんばって説明していきます。
ちなみに、なんですがこの本ではアセンブラ言語は大文字で書かれていましたが小文字でもいいそうです。

        ORG     0x7c00          
entry:
        MOV     AX,0            
        MOV     SS,AX
        MOV     SP,0x7c00
        MOV     DS,AX

はじめに、この部分なんですが
ORG 0x7c00
でこのプログラムはメモリ上の0x7c00番地からスタートするという意味があります。
なぜ、もっとはじめのほうの番地を使うことができないかといいます。これより前の番地ではすでにbiosが占領しているため私たちが使うことができないため0x7c00番地からはじまっています。
また、レジスタに変な値が入力されているといけないので初期化を行っています。

tuzuki:
        MOV     AX,0x0820
        MOV     ES,AX
        MOV     CH,0            ; シリンダ0
        MOV     DH,0            ; ヘッド0
        MOV     CL,2            ; セクタ2
readloop:
        MOV     SI,0            ; 失敗回数を数えるレジスタ
retry:
        MOV     AH,0x02         ; AH=0x02 : ディスク読み込み
        MOV     AL,1            ; 1セクタ
        MOV     BX,0
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ディスクBIOS呼び出し
        JNC     next            ; エラーがおきなければnextへ
        ADD     SI,1            ; SIに1を足す
        CMP     SI,5            ; SIと5を比較
        JAE     error           ; SI >= 5 だったらerrorへ
        MOV     AH,0x00
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ドライブのリセット
        JMP     retry

はじめに、esレジスタに番地を入力しているのは、そこに今度プログラムを書き込みますよーという意味です。ですので、今からフロッピーディスクからデータを読み込んでメモリに記述するのですが、そのメモリの始まりの番地を記述しています。
ここでは、フロッピーディスクから次のプログラムをよみこんでいます。
プロッピーディスクからメモリにプログラムを読み込むには、割り込みを使ってフロッピーディスクからプログラムを読み込む必要があります。
inc 13h

と記述することでcpu割り込みを行いフロッピディスクを読み込むのですが。
そのほかにも、フロッピーディスクのどこから読み込みのか?どれだけ読み込むのかをデータとして送らなければいけないのですがそのときにレジスタを使って情報を受け渡しています。
具体には、
alが何セクタ読み込むか
chは何番目のシリンダか
clは何番目のセクタから読み込むか
dhはheadの何番目か
dlはdriveの何番目か
そして、これらの情報をレジスタに渡したあとに、
int 0x13
と割り込みをかけてフロッピーディスクに情報を読み込みにいく。
また、以下ではフロッピーディスクにデータを読みこんでできなかった場合同じことを繰り返すプログラムが実装されています。

readloop:
        MOV     SI,0            ; 失敗回数を数えるレジスタ
retry:
        MOV     AH,0x02         ; AH=0x02 : ディスク読み込み
        MOV     AL,1            ; 1セクタ
        MOV     BX,0
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ディスクBIOS呼び出し
        JNC     next            ; エラーがおきなければnextへ
        ADD     SI,1            ; SIに1を足す
        CMP     SI,5            ; SIと5を比較
        JAE     error           ; SI >= 5 だったらerrorへ
        MOV     AH,0x00
        MOV     DL,0x00         ; Aドライブ
        INT     0x13            ; ドライブのリセット
        JMP     retry
next:
        MOV     AX,ES           ; アドレスを0x200進める
        ADD     AX,0x0020
        MOV     ES,AX           ; ADD ES,0x020 という命令がないのでこうしている
        ADD     CL,1            ; CLに1を足す
        CMP     CL,18           ; CLと18を比較
        JBE     readloop        ; CL <= 18 だったらreadloopへ
        MOV     CL,1
        ADD     DH,1
        CMP     DH,2
        JB      readloop        ; DH < 2 だったらreadloopへ
        MOV     DH,0
        ADD     CH,1
        CMP     CH,CYLS
        JB      readloop        ; CH < CYLS だったらreadloopへ

; 読み終わったのでharibote.sysを実行だ!

        MOV     [0x0ff0],CH     ; IPLがどこまで読んだのかをメモ
        JMP     0xc200

error:
        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1            ; SIに1を足す
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e         ; 一文字表示ファンクション
        MOV     BX,15           ; カラーコード
        INT     0x10            ; ビデオBIOS呼び出し
        JMP     putloop
fin:
        HLT                     ; 何かあるまでCPUを停止させる
        JMP     fin             ; 無限ループ
msg:
        DB      0x0a, 0x0a      ; 改行を2つ
        DB      "load error"
        DB      0x0a            ; 改行
        DB      0

        RESB    0x7dfe-$        ; 0x7dfeまでを0x00で埋める命令

        DB      0x55, 0xaa

そして、最後に

MOV [0x0ff0],CH
JMP 0xc200
0xc200にとびます。
これは、いろいろとコンパイルを行った結果
メイン処理の部分がそのアドレスの場所になったからそこにとんだと書いてありました。
詳しいことが、ちょっとわからなかったです。
まあ、今日はこの辺で。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2