OS自作入門 -Advent11-

NO IMAGE

Step4 シリアル経由でファイルを転送する 前半

このstepではブートローダーというものを作成していくことになりそうだ。ブートローダーがなんであるのか。に関しては後述。

さて始めよう。

ブートローダー

実はこれまでのステップでやっていたことはブートローダーを作成するまでの前準備にすぎなかった。H8のROMに書き込みを行い実行していただけである。バイトコード(機械語コード)はテキスト領域にあり、CPUがROM上のバイトコードを読み込んで上から順に評価していただけである。OSができるよりも以前の専用機、パンチされたカードを使って上からプログラムを実行しているんじゃないかという感想。

ということでこれから作っていくOSも基本的な動作としてはROMから起動してROM上で動作することを起点とすることになる。ROM上へ保存されるので電源のON/OFFで消えることもなく(不揮発性)、電源ONと同時に起動されるようになるだろう。

ブートローダーの必要性について

これは全然知らなかった話。実はROMへの書き込み回数には上限があるらしい。ハードウェア的な話で書き込む度に何か劣化するのだろう。多分。H8だと100回前後らしい。OSを開発する上でtry errorを繰り返す度に書き込んでいたら100回なんて直ぐに超えてしまう。

ということで、ブートローダーというものを作成する。ブートローダーはOSの実行形式ファイルをシリアル経由でダウンロードし、それをRAM上に展開して起動するという役割を担うプログラムのことを指す。なので電源ON => ブートローダー起動 => OSダウンロード => OS起動という流れになる。この二段構えの構成をbootstrapと呼ぶらしい。

そういえばRaspberryPiで遊んでいる時もOSの書き込み対象はMicroSDであり、直接CPUとかに書き込むということはなかった。RaspberryPiのCPU側でMicroSDにあるファイルを展開するようになってるのだろうか。暇があればその辺りも読んでみたい。


シリアル経由でのファイル転送

bootstrapのために次の機能が必要になる。

  • シリアル経由でOSをダウンロードしRAM上へ保存
  • 実行形式ファイルをRAM上に展開
  • 展開されたOSを実行

ということで順にやっていこう。

シリアル経由でのファイル転送には、古くから使われているXMODEMというプロトコルを利用して行う。モデム時代にファイル転送にはよく使われていたらしい(懐かしい。FTPでもないとは。。。)

XMODEMのプロトコル仕様

簡単な解説が載っていたので抜粋しておく。

送信側
  1. 受信側からNAKを受けたら送信開始
  2. ブロックは固定長でデータ量が足りない場合はEOFで埋める
  3. 送信したらACKかNAKが返ってくるのをまつ。ACKなら続きのブロックを、NAKなら再送
  4. データの終端はEOTを送信し、ACKで終わり
  5. 中断時はCANを送信し、CANを受診したら中断
受信側
  1. 受診できるならNAK送信
  2. SOHを受けたら連続するブロックとして受信、成功したらACK、失敗したらNAK
  3. EOTを受けたらACKを返して終了
  4. 中断時はCANを送信し、CANを受けたら中断

ACK: ACKnowledge
NAK: Negative AcKnowledge

の略らしい。

XMODEMの実装

新しく以下のファイルを追加

  • xmodem.h, xmodem.c

以下のファイルを修正

  • main.c
  • ld.scr
  • serial.h, serial.c
  • lib.h, lib.c
  • Makefile

さて量が多いが頑張ろう。

xmodem.hだけを見ると

long xmodem_recv(char *buf);

これの追加しかないのでxmodemの受け手側だけ作れば良さそう。内部実装は3つに分かれていてxmodem_wait,xmodem_read_block,xmodem_recv。実装したものをGithub xmodemに置いておいたので参考に。

  • xmodem_wait
    待ち状態のための定期的なNAKの送信
  • xmodem_read_block
    固定長のブロックを読み込む処理
    チェックサムの処理とかもここでやってる
    チェックサムとは
    排他的論理和(XOR)で掛け合わせると一致している場合にゼロとなる値。
  • xmodem_recv
    ファイル受信の本体。
    waitしたり、read_blockしたり、CAN送信したり仕様に沿うように実装。

xmodemを使ってファイルのダウンロードができるようになった。
これを使ってファイル転送を行えるようにmainの方を書き換えていくのが次回かな。

今日はここまで。