並列して処理をソフトウェアで処理を実施したい場合があります。

【問題点】
■その1
文字の受信待ちをしながら他の処理Aも実施したい場合を考えます。

処理Aを実施しつつ定期的にSSRレジスタのRDRFビットの状態をチェックするようなロジックをソフトで作れば実現可能です。
(定期的に状態をチェックするような処理をポーリングといいます。)

ただこの場合、ポーリングで状態をチェックする周期が長ければ長いほど文字の受信待ちの検出が遅くなってしまいます。しかし、CPUが一定時間に処理できる量は決まっているので、状態チェック処理にかければかけるほどその他の処理、ここでは処理Aの一定時間に処理できる量は増えます。

一方、状態をチェックする周期を短くすればするほど受信待ちの検出は早まります。しかし、先述したようにCPUが一定時間に処理できる量は決まっているので、状態チェック処理にかければかけるほど処理Aの一定時間に処理できる量が減ってしまいます。

一長一短で、もっと効率のよい方法があればというところです。


■その2
シリアルによる文字の送信処理をする場合を考えます。

送信処理が可能かの判断を実施する場合、SCIのSSRレジスタのTDREビットの状態をチェックするロジックをソフトで作ります。

まだ送信可能でない場合はポーリングをして送信可能であることを待ち合わせます。

この待ち合わせはソフトで実現するのでCPUの処理によって実現されるわけですが、この処理が非常に無駄な処理になります。

CPUの処理と比較してコントローラの処理が一定時間に処理できる量は少ない、つまりコントローラの動作は相対的に非常に遅いわけです。

この待ち合わせの間にも、別の処理ができる可能性があるわけで、ポーリングはCPU資源を無駄に浪費していると解釈できるわけです。


【対策】
そこで、ソフトでポーリングを実施して状態をチェックするとCPUの浪費に繋がるという課題を克服するための方法を割込みといいます。

それでは割込みとはなにか?
OSをブート・ローダから起動してみた。
問題ないようだ。

Hello Worldを出すだけのシンプルなものだが、これがOSのはじめの一歩かな。


$OS自作してみる。-os_first


これで次からOS作成することになる。



1thから6thまでのステップはOSには直接関係ないようだがとてもためになった。

ちなみにCPUの原理についてはOSを終了させてから実施してみようと思うので後回し。
OSのファイルは、ブート・ローダによって受信されRAMに展開されOSが起動できるようにされます。

ブート・ローダは割込みで最初に実行されるアドレスが決定されますが、OSはブート・ローダでソフトからアドレスを指定して実行されないといけません。

そのアドレスはどこにあるのか?
ELFヘッダの「Entry point address」で指定される必要があります。
この実行開始アドレスのことをスタート・アドレスやエントリ・ポイントと呼んでいます。

今度はそこに指定されるためには、何をどう記述すればよいのか?
リンカ・スクリプトに「ENTRY("_start")」と記述すればOKです。

_startとはstartup.sに記述したラベルのことです。

readelfで中を見るとこんなかんじで見事に指定されています。
--------------------
ELF Header:
Entry point address: 0xffc020

Symbol table '.symtab' contains 80 entries:
Num: Value Size Type Bind Vis Ndx Name
64: 00ffc020 0 NOTYPE GLOBAL DEFAULT 1 _start
--------------------

ブート・ローダの実行開始のアドレスはH8の仕様として割込みも鑑みて実施されていたものでした。
そのブート・ローダからのOS起動は、リンカ・スクリプトの記述で先頭の実行開始のアドレスを指定してやることで実現されます。