アットウィキロゴ

kozos

「12ステップで作る組み込みOS自作入門」という書籍の「7、8thステップ」が、今ひとつ腑に落ちないので、全体の流れをまとめてみる。


7thステップ 割り込み処理を実装する

  • 処理の流れ:vector.c→intr.S→interrupt.c→main.c

割り込み発生時(vector.c)

  • 割り込みベクタを見る(vector.c)
  • ベクタに記述された箇所(intr.S)をcallする。
  • ret

ベクタの飛び先(intr.S)

  • レジスタ退避
  • interrupt関数をcallする。
    • 1st param. : 割り込みの個別情報(割り込み元のベクタ依存で異なる)
    • 2nd param. : SP
  • レジスタ復旧
  • ret

interrupt関数(interrupt.c)

  • 1st param.の値に応じたハンドラを呼び出す
    • ハンドラ登録は、softvec_setintr関数で実施済み

ハンドラ登録例:intr関数(main.c)

  • 受信charを画面表示



8thステップ スレッドを実装する

  • 7thステップのハンドラ登録→ハンドラをcallする仕組みは存続

PHASE_1 初期スレッド生成とコマンド・スレッドの生成準備

start関数(startup.s)

  • main関数をcallする

main関数(main.c)

  • kz_start関数をcallする
    • start_threads関数を1st param.に設定
  • retしない(上記関数から戻らない)

kz_start関数(kozos.c)

  • setintr関数(割り込みハンドラ(syscall_intr, softerr_intr)登録)
  • thread_run関数をcallする(初期スレッド作成)(kozos.c)
  • dispatch関数をcallする(初期スレッド起動)(startup.s)→start_threads関数に移動
  • retしない(上記関数から戻らない)

setintr関数(kozos.c):割り込みハンドラ登録

  • softvec_setintr(kozos.c)
    • 割り込みベクタ設定:thread_intr関数(ハンドラ登録)
  • ハンドラ登録[handlers[]]

thread_run関数(kozos.c):スレッド生成

  • 新規TCBの確保
  • スタック領域の取得
  • プログラム・カウンタ
  • などなど

start_threads関数(main.c)

  • kz_run関数をcallする
    • test08_1_main関数のポインタを渡す
  • retしない(上記関数から戻らない)

PHASE_2 コマンド・スレッドの生成

kz_run関数(syscall.c)

  • 引数として渡されたパラメタを設定
  • kz_syscall関数をcallする
  • ret

kz_syscall関数(kozos.c)

  • asm [trapa #0](syscall割り込み)トラップ命令の実行
    • vector.c→intr.S→interrupt関数→thread_intr関数(setintr関数で登録済み)
疑問:
bootloadで実装 vector.c, intr.S これらの領域は、OSのFWを動作させる際も生きている。
osでも実装  interrupt関数(interrupt.c)以降
bootloadとosは、バイナリが異なる。interrupt関数のアドレスを同一にできるのはナゼ?
←自己解決:interrupt関数は、ROMで動作する。ハンドラは、bootloadのFWもRAM上に割り当てられているので、ハンドラの設定を含め正常に動作できる。この構成は、osの実行でも変わらない。

thread_intr関数(kozos.c)

  • intr_syscall関数
  • syscall_intr関数(handlers[])を実行する。
  • schedule()
  • dispatch(startup.s)→タスク切り替え
※キューに積んだ順で実行されるので、kz_startで開始したstartタスク終了後、dispatchにより、thread_initに切り替わる。
  • retしない

syscall_intr関数(kozos.c)

  • syscall_proc関数
  • ret

syscall_proc関数(kozos.c)

  • get_current関数(kozos.c):startタスクを抜く。
  • call_functions関数(kozos.c)
  • thread_run関数をcall
    • TCB内のsyscall情報の値を参照:KZ_SYSCALL_TYPE_RUN

thread_run関数(kozos.c):スレッド生成(≒キューへの登録)

  • TCBの取得
  • スタック領域の取得
  • プログラム・カウンタを設定
  • get_current関数で抜いたタスクをキューに再び積む(理解半ばのため更に勉強中)
  • test08_1_mainタスクをキューに積む

PHASE_3 コマンド・スレッドの実行

thread_init関数(kozos.c)

  • test08_1_main関数をcall(main.c)
  • thread_end関数をcall(kozos.c)
  • ret






-
最終更新:2012年11月10日 15:52