SlideShare a Scribd company logo
1 of 42
Download to read offline
12ステップで作る組込みOS自作入門
      8thステップ




                @sandai
【参考書籍】
12ステップで作る組込みOS自作入門
【内容】
1ステップずつ、実際に動かしながらプログラムを発展さ
せていく方式で無理なく学べる。OSやハードウェアに詳
しくない方にも理解できるよう
に十分な説明を提供

坂井 弘亮(著)
カットシステム(2010/5)

【税込価格】
4,410円

【サポートページ】
http://kozos.jp/books/makeos/
もくじ
1.タスクとスレッド
2.スレッドの実装
3.プログラムの実行
4.まとめ
1.タスクとスレッド
ポーリングによるサービスの実行
●   割込みを利用せず一定時間ごとにサービスを実
    行する場合、ビジーループで行う方法がある
int main()
{
    .
    .
    while(1) {
        if(0.1秒が経過したか) {
            led_main();
        }
    }
    .
    .
}

int led_main()
{
    (LEDを点滅させる処理)
}
複数のサービスを切り替えて実行
●   今度は一定時間ごとに複数のサービスを切り替
    えて実行するケース
int main()
{
    .
    .
    while(1) {
        if(0.1秒が経過したか) {
            led_main();
        }
        if (1秒が経過したか?) {
            write_time();
        }
        if (シリアル受信したか?) {
            command_exec();
        }
    }
    .
    .
}
メイン・ループ
●   前のページのように、while(1)のような処理の
    中心となるループをメイン・ループと呼ぶ
●   それぞれ一定時間ごとにチェックしながらサー
    ビスを実行する場合、このビジー・ループの方
    法だと重い処理を行うときに時間がずれる
●   そういった重い処理をビジー・ループで正常に
    回したいなら、一定のタイミングごとにメイ
    ン・ループに戻るという方法が考えられる
    –   処理状態を保存して(サンプルの場合はstaticの変
        数に格納している)戻る感じだね
●   とはいえ、サービスの増加や処理が複雑になっ
    ていけば、このような方法ではもたない
処理の共通化
●   サービスに対する処理を共通化する
    –   定期的な処理の切り替え
    –   処理状態の中断、保存、再開
●   処理状態の保存ならstaticの変数に退避させず
    にスタックとレジスタの状態を保存すればいい
    –   各々の関数で行う必要はない
●   このためには、実行する処理をサービスの単位
    で区切る必要がある
●   このサービスの単位をタスクと呼ぶ
タスクをスレッドとして実装
●   スレッドとして実装することでプログラムをタ
    スクごとに独立して動作できる
    –   下記のようなイメージで書ける
int main()
{
    kz_start(start_threads, …);
    return 0;
}

ini start_threads(int argc, char *argv[])
{
    kz_run(led_main, “led”, 1, ...);
    kz_run(timer_main, “timer”, 1, ...);
    kz_run(command_main, “command”, 1, ...);

    while(1) {
        asm volatile(“sleep”);
    }
}
.
.
スレッドの起動とシステム・コール
●   kz_run()にタスクにあたる関数を渡すことで、
    それをOSがメイン関数としてスレッドを起動す
    る
    –   こうすることで各タスクはスレッドとしてひとつの
        処理単位で動作する
●   kz_run()のようにOSに対するサービス要求をす
    る関数をシステム・コールと呼ぶ
●   タスクの切り替えは割込みが発生したときかシ
    ステム・コールが呼ばれたときに行われる
スケジューリングとディスパッチ
●   割込みかシステム・コールが呼ばれたとき、次
    に動作すべきスレッドの選択とその処理再開が
    行われる
    –   前者をスケジューリングと呼び、後者をディスパッ
        チと呼ぶ
●   動作を中断したスレッドをディスパッチによっ
    て再開するには、中断時の処理状態を保存して
    おく必要がある
    –   その情報をコンテキスト情報、あるいは単にコンテ
        キストと呼ぶ
コンテキスト情報
●   一般的にはSPやPCも含む各種レジスタ値がス
    レッドのコンテキストにあたる
●   スレッドのディスパッチにはそのスレッドのコ
    ンテキストを新たに読み込む必要がある
    –   この動作をコンテキスト切り替え、コンテキスト・
        チェンジと呼ぶ
●   スレッドはタスクがそれぞれ独立して実行して
    いるようにみせかけているだけで、実際は細か
    くタスクを切り替えながら並列に動作させてい
    るに過ぎない
アプリケーション・プログラム
●   スレッドを実装することで各種サービスをタス
    クに分割してスレッド化し、別々のプログラム
    のように動作させることができる
●   OS上でタスクとして動作するプログラムを一般
    にアプリケーション・プログラムと呼ぶ
    –   日本語では応用プログラムと言う
    –   スレッドとして動作するならそのスレッドはユー
        ザ・スレッドと呼ぶことができる
カーネル
●   OSの中核のことをカーネル、またはコアと呼ぶ
●   もともと備わっているアプリケーション・プロ
    グラムも含めた全体をOSと呼ぶ場合と、カーネ
    ル部分のみをOSと呼ぶ場合がある
●   たとえばWindowsでいうところのエクスプロー
    ラはアプリケーション・プログラムだし、Mac
    でいえばFinderがそれにあたる
割込みでスレッドの切り替え
●   スレッドの切り替えはOSが適当なタイミングで
    行う。具体的には割込み処理で行う
●   割込み処理を応用すればレジスタ値の保存と復
    旧の処理をスムーズに行える
    –   たとえば、割込み復帰命令を応用すればディスパッ
        チすることができるなど
●   スレッドの切り替えは割込み処理でなくてもで
    きるけど、割込みの「処理を強制的に中断す
    る」性質を利用した方が正確な動作が期待でき
    る
システム・コール
●   OSは割込み処理の延長として動作する
    –   このためスレッドからOSの機能を利用するには、ス
        レッド側から明示的に割込みを発生させるのが適切
●   このために多くのCPUはソフトウェア的に割込
    みを発生させることができるシステム・コール
    命令を持っている
    –   命令を実行するとシステム・コール割込みという内
        部割り込みが発生
    –   あとは外部割り込みの要領で割込みハンドラを用意
        してそれを実行させる流れ
●   こういう手順で実装されるOSのサービスを一般
    的にシステム・コールと呼ぶ
2.スレッドの実装
プログラムの追加
●   ブートローダ
    –    無し
●   OS
    –    kozos.h,kozos.c...スレッドの実装
    –    syscall.h,syscall.c...システムコール利用のため
         の関数
    –    test08_1.c...テスト・プログラム
プログラムの修正
●   ブートローダ
    –    ld.scr...割込みとブートのスタックを明確化
    –    intr.S...割込みスタックへの切り替えを追加
    –    startup.s...ブートスタックを利用するように変更
●   OS
    –    ld.scr...スタックを分離、明確化
    –    startup.s...スレッドのディスパッチを追加
    –    defines.h...型の定義を追加
    –    main.c...OSを利用するように変更
    –    Makefile
ブートローダの修正
●   スタックをスレッドごとに確保するように変え
    る
●   スタックを3種類に分ける
    –   起動処理で利用(ブートスタック)
    –   割込み処理で利用(割込みスタック)
    –   スレッドごとに確保(ユーザ・スタック)
●   ブートローダにユーザ・スタックは必要ないの
    で上2つだけ
割込みスタック
●   割込み処理のタイミングでスタックを切り替え
●   ld.scrでスタックのアドレスを取得し、intr.S
    とstartup.sにてそれぞれ切り替えている
    –   ここではintr.Sのsyscallだけだけ表示
_intr_syscall:
        .
        .
        .
        mov.l    er0, @-er7
        mov.l    er7, er1
        mov.l    #_intrstack, sp ←割込みスタックを利用
        mov.l    er1, @-er7
        mov.w    #SOFTVEC_TYPE_SYSCALL, r0
        jsr      @_interrupt
        mov.l    @er7+, er1
        mov.l    er1, er7a
OSの修正と追加
●   修正と追加内容
    –   スタックの分離
    –   ディスパッチの実装
    –   スレッドの実装
    –   システムコールの実装
    –   アプリケーションの実装
●   スタックについてはブートローダと同じ
ディスパッチ(startup.s)
●   @er0, er7でスタックポインタをユーザ・ス
    タックの位置に切り替えていると思われる
    –   以降はthread_run()で用意したユーザ・スタックを
        使っていく
    –   あとは書籍の説明にある通り
_dispatch:
        mov.l   @er0, er7
        mov.l   @er7+, er0
        mov.l   @er7+, er1
        mov.l   @er7+, er2
        mov.l   @er7+, er3
        mov.l   @er7+, er4
        mov.l   @er7+, er5
        mov.l   @er7+, er6
        rte
スレッド(kozos.c)
●   大まかな流れとしては、kz_start()で初期ス
    レッドを生成し、それからkz_run()でcommand
    スレッドを生成しているという流れ
●   この際に実装したシステム・コールを利用して
    いる
●   処理があっちこっち飛んでいるうえに構造体が
    あるので理解しにくい部分だと思う
●   コードの量が多いので、最後のまとめで細かい
    部分を記述する
システムコール(syscall.c)
●   kozos.cで定義しているシステム・コールを呼
    び出すためのサービス関数(API)
●   アプリ側からOSの機能を利用するときに使うイ
    ンタフェース
●   今はkz_run()とkz_exit()を持ってい
    て、kozos.cのsyscall()を呼び出す機能を持っ
    ている
●   その先にsyscall()からthread_intr()に渡すた
    めのパラメータを構造体に設定して持っている
アプリケーション
        (test08_1_main.c)
●   コンソールからの文字を入力された通りに返す
    アプリ
●   ここは特に難しくないので特に触れない
3.プログラムの実行
ビルドの失敗(kozos.c)
●   ビルドに失敗した
●   どうもプロトタイプ宣言は関数の外にする必要
    があるらしい。(gcc4.7.1ではこうしなければ
    ならない)
static void thread_intr(softvec_type_t type, unsigned long sp);

static int setintr(softvec_type_t type, kz_handler_t handler)
{
    softvec_setintr(type, thread_intr);

    handlers[type] = handler;

    return 0;
}
もういっこビルドの失敗(kozos.c)
●   どうも構造体の大きさに問題があるらしい。そ
    こで64bitの構造体へと大きさを調節
●   アライメントだったけなこれ
typedef struct _kz_thread {
    .
    .
    } syscall;

    kz_context context;
    char dummy[16]; ←ここを追加
} kz_thread;
プログラムの実行
/Users/sandai/12step/src/08/os% sudo cu -l /dev/tty.usbserial-FTG6PQ4H
Connected.
kzload (kozos boot loader) started.
kzload> load
~+lsx kozos
Sending kozos, 27 blocks: Give your local XMODEM receive command now.
Bytes Sent:   3584   BPS:282

Transfer complete

XMODEM receive succeeded!
kzload> run
starting from entry point: ffc020
kozos boot succeed!
start EXIT.
test08_1 started.
> echo eeee
 eeee
> exit
test8_1 exit.
command EXIT.
system error.
4.まとめ
まとめ1
●   8ステップが今までで一番難しい気がする
●   いくつかメモを取りながら構造体のパラメータ
    を把握して、流れを読み取る必要があるだろう
●   細かい説明は書籍にあるのでいいとして、ここ
    では全体的な流れを細かく記述しておく
まとめ2
●   main関数からkz_start()呼び出し
●   kz_start()
    –   データの初期化
    –   setintrによる割込みハンドラの設定
    –   thread_run()の直接呼び出しによる初期スレッドの
        生成
    –   作成したスレッドをdispatch()により起動
●   thread_init()が呼び出される
     – thp->init.func()によりstart_threads()を
       呼び出し
まとめ3
●   start_threads()でkz_run()が呼び出される
●   kz_run()
    –   受け取ったパラメータを構造体に設定
    –   それからkz_syscallでシステム・コール発行
●   kz_syscall()
    –   受け取ったシステムコールの種類(type)と、設定し
        た構造体をcurrent->syscall.xxxに退避
    –   その後asm volatile(“trapa #0”)でトラッ
        プ命令の割込みを自発的に発生させる
まとめ3
●   トラップ命令が発生するとsetintr()で設定し
    たthread_intr()が呼び出される
●   thread_intr()
    –   spのコンテキストをcurrent->contextに保存
    –   handlers[type]()でsetintr()のときに登録したハ
        ンドラのうち、syscall_intr()を呼び出す
●   syscall_intr()からsyscall_proc()を呼び出す
まとめ4
●   syscall_proc()
    –   getcurrent()により、カレント・スレッドをキュー
        から外す。この段階ではキューには何も入っていな
        い状態になる
    –   call_functions()を呼び出す
●   call_functions()
    –   KZ_SYSCALL_TYPE_RUNが今回のシステムコールの種
        類なので、thread_run()が実行される
    –   パラメータはkz_syscall()のときに退避させておい
        たcurrent->syscall_param
まとめ5
●   thread_run()が実行されたら、処理がさっきの
    thread_intr()まで戻る
    –   handler[type]()ってやってたところね
    –   たぶんここの流れがわかりにくいが、割込み処理が
        終了したのだから戻るのは当たり前
●   thread_intr()に戻ると、schedule()が実行さ
    れ、キューの先頭がカレントスレッドになる
    –   カレントスレッドは最初に起動したstartスレッ
        ド。このスレッドの流れもつかみにくい部分だけ
        ど、きっちり処理を追えば分かるはず
●   そしてdispatch()で割込みで中断していた
    startスレッドが再開される
まとめ6
●   startスレッドの再開は、thp->init.func()が
    丁度終えたところから
    –   thread_end()の呼び出し。実体はkz_exit()
●   kz_exit()
    –   kz_syscall()でシステムコールが発行される
    –   種類はKZ_SYSCALL_TYPE_EXIT
●   kz_syscall()
    –   パラメータはNULLなので何もなし
    –   asm volatile(“torapa #0”)のトラップ命令で割
        込みが発生し、thread_intr()が呼び出される
まとめ7
●   thread_intr()
    –   handlers[type]()が呼び出される。これは
        syscall_intr()にあたる
●   syscall_intr()
    –   ここでsyscall_proc()が呼び出される
●   syscall_proc()
    –   getcurrent()により、カレントスレッドである
        startスレッドがキューから外れる
    –   call_functions()の呼び出し
まとめ8
●   call_functions()
    –   typeはKZ_SYSCALL_TYPE_EXITなの
        で、thread_exit()が呼び出される
    –   thread_exit()が呼び出され、start EXITの文字が
        出力され、memset()でスレッドがクリアされ消滅
●   処理はthread_intr()に戻り、schedule()の呼
    び出しによって、commandスレッドがキューの
    先頭に来る
●   それからdispatch()によりcommandスレッドが
    起動
まとめ9
●   dispatch()によりthread_init()が呼び出さ
    れ、thp->init.func()によりtest08_1_mainが
    呼び出されるという流れ
●   ながいーおわりー
まとめまとめまとめー
●   kz_start()の存在があるからちょっとわかりに
    くいけれど、これは結局は、スレッドを起動す
    るための「スレッド」を作ってる
●   でまあスレッドを作ったらkz_exit()でシステ
    ムコールを発行して、次のスレッドを起動させ
    ているってわけね
●   thread_run()をシステムコールから発行してい
    ないので、ちょっと違和感がある

More Related Content

What's hot

AtCoder Regular Contest 002
AtCoder Regular Contest 002AtCoder Regular Contest 002
AtCoder Regular Contest 002AtCoder Inc.
 
AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説AtCoder Inc.
 
AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説AtCoder Inc.
 
AtCoder Beginner Contest 006 解説
AtCoder Beginner Contest 006 解説AtCoder Beginner Contest 006 解説
AtCoder Beginner Contest 006 解説AtCoder Inc.
 
AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説AtCoder Inc.
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.kiki utagawa
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Inc.
 
AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説AtCoder Inc.
 
AtCoder Beginner Contest 020 解説
AtCoder Beginner Contest 020 解説AtCoder Beginner Contest 020 解説
AtCoder Beginner Contest 020 解説AtCoder Inc.
 
AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説AtCoder Inc.
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Inc.
 
AtCoder Regular Contest 020 解説
AtCoder Regular Contest 020 解説AtCoder Regular Contest 020 解説
AtCoder Regular Contest 020 解説AtCoder Inc.
 
AtCoder Beginner Contest 019 解説
AtCoder Beginner Contest 019 解説AtCoder Beginner Contest 019 解説
AtCoder Beginner Contest 019 解説AtCoder Inc.
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説AtCoder Inc.
 
Indeedなう B日程 解説
Indeedなう B日程 解説Indeedなう B日程 解説
Indeedなう B日程 解説AtCoder Inc.
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説AtCoder Inc.
 

What's hot (20)

AtCoder Regular Contest 002
AtCoder Regular Contest 002AtCoder Regular Contest 002
AtCoder Regular Contest 002
 
AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説AtCoder Beginner Contest 018 解説
AtCoder Beginner Contest 018 解説
 
AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説AtCoder Beginner Contest 033 解説
AtCoder Beginner Contest 033 解説
 
AtCoder Beginner Contest 006 解説
AtCoder Beginner Contest 006 解説AtCoder Beginner Contest 006 解説
AtCoder Beginner Contest 006 解説
 
AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説AtCoder Beginner Contest 008 解説
AtCoder Beginner Contest 008 解説
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説AtCoder Beginner Contest 023 解説
AtCoder Beginner Contest 023 解説
 
AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説AtCoder Beginner Contest 011 解説
AtCoder Beginner Contest 011 解説
 
AtCoder Beginner Contest 020 解説
AtCoder Beginner Contest 020 解説AtCoder Beginner Contest 020 解説
AtCoder Beginner Contest 020 解説
 
AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説AtCoder Beginner Contest 030 解説
AtCoder Beginner Contest 030 解説
 
Abc009
Abc009Abc009
Abc009
 
AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説AtCoder Beginner Contest 035 解説
AtCoder Beginner Contest 035 解説
 
AtCoder Regular Contest 020 解説
AtCoder Regular Contest 020 解説AtCoder Regular Contest 020 解説
AtCoder Regular Contest 020 解説
 
AtCoder Beginner Contest 019 解説
AtCoder Beginner Contest 019 解説AtCoder Beginner Contest 019 解説
AtCoder Beginner Contest 019 解説
 
CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説CODE FESTIVAL 2014 本選 解説
CODE FESTIVAL 2014 本選 解説
 
双対性
双対性双対性
双対性
 
Indeedなう B日程 解説
Indeedなう B日程 解説Indeedなう B日程 解説
Indeedなう B日程 解説
 
CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説CODE FESTIVAL 2015 予選A 解説
CODE FESTIVAL 2015 予選A 解説
 
Execution
ExecutionExecution
Execution
 

Viewers also liked

【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 sandai
 
【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 sandai
 
【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 sandai
 
C++でできる!OS自作入門
C++でできる!OS自作入門C++でできる!OS自作入門
C++でできる!OS自作入門uchan_nos
 
【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門sandai
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門sandai
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門sandai
 
QEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングQEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングYuma Ohgami
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくばHirotaka Kawata
 
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -Kishi Shundo
 
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)kozossakai
 
やってよかったOS作り
やってよかったOS作りやってよかったOS作り
やってよかったOS作りHidemi Kawai
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門demuyan
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門Hirotaka Kawata
 
【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介Yuma Ohgami
 
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめWeb系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめNisei Kimura
 
Ctfのためのpython入門
Ctfのためのpython入門Ctfのためのpython入門
Ctfのためのpython入門shiracamus
 
ハッキング実演
ハッキング実演ハッキング実演
ハッキング実演Ken Ogura
 

Viewers also liked (20)

【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門 【学習メモ#9th】12ステップで作る組込みOS自作入門
【学習メモ#9th】12ステップで作る組込みOS自作入門
 
【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門 【学習メモ#11th】12ステップで作る組込みOS自作入門
【学習メモ#11th】12ステップで作る組込みOS自作入門
 
【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門 【学習メモ#6th】12ステップで作る組込みOS自作入門
【学習メモ#6th】12ステップで作る組込みOS自作入門
 
C++でできる!OS自作入門
C++でできる!OS自作入門C++でできる!OS自作入門
C++でできる!OS自作入門
 
【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門
 
QEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングQEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミング
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
 
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
 
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
 
やってよかったOS作り
やってよかったOS作りやってよかったOS作り
やってよかったOS作り
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門
 
人工知能概論 1
人工知能概論 1人工知能概論 1
人工知能概論 1
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
 
【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介
 
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめWeb系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
 
Ctfのためのpython入門
Ctfのためのpython入門Ctfのためのpython入門
Ctfのためのpython入門
 
ハッキング実演
ハッキング実演ハッキング実演
ハッキング実演
 

Similar to 【学習メモ#8th】12ステップで作る組込みOS自作入門

HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLakirahiguchi
 
リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズKazuhiro Takahashi
 
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Hiraku Toyooka
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)Kazuhiro Yoshikawa
 
Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Yoshinori Matsunobu
 
Q4 Mでメッセージキュー
Q4 MでメッセージキューQ4 Mでメッセージキュー
Q4 Mでメッセージキューngi group.
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチKazuki Onishi
 
NGS解析を始めた時にぶつかりがちな小さい壁あれこれ
NGS解析を始めた時にぶつかりがちな小さい壁あれこれNGS解析を始めた時にぶつかりがちな小さい壁あれこれ
NGS解析を始めた時にぶつかりがちな小さい壁あれこれDNA Data Bank of Japan center
 
Read daemon on 20121110 by shinaisan
Read daemon on 20121110 by shinaisanRead daemon on 20121110 by shinaisan
Read daemon on 20121110 by shinaisanshinaisan
 
システムパフォーマンス勉強会#5
システムパフォーマンス勉強会#5システムパフォーマンス勉強会#5
システムパフォーマンス勉強会#5shingo suzuki
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめMikiya Okuno
 
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010Tsukasa Oi
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishYohei Azekatsu
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPNSaitoNmiri
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Java concurrency in_practice_chap06
Java concurrency in_practice_chap06Java concurrency in_practice_chap06
Java concurrency in_practice_chap06ohtsuchi
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動Takashi Takizawa
 
MINCS – containers in the shell script
MINCS – containers in the shell scriptMINCS – containers in the shell script
MINCS – containers in the shell scriptMasami Hiramatsu
 

Similar to 【学習メモ#8th】12ステップで作る組込みOS自作入門 (20)

HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
リアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズリアルタイムOsのカスタマイズ
リアルタイムOsのカスタマイズ
 
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)Linuxのプロセススケジューラ(Reading the Linux process scheduler)
Linuxのプロセススケジューラ(Reading the Linux process scheduler)
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)
 
Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)Linux/DB Tuning (DevSumi2010, Japanese)
Linux/DB Tuning (DevSumi2010, Japanese)
 
Q4 Mでメッセージキュー
Q4 MでメッセージキューQ4 Mでメッセージキュー
Q4 Mでメッセージキュー
 
プロセスとコンテキストスイッチ
プロセスとコンテキストスイッチプロセスとコンテキストスイッチ
プロセスとコンテキストスイッチ
 
Gingerbread
GingerbreadGingerbread
Gingerbread
 
NGS解析を始めた時にぶつかりがちな小さい壁あれこれ
NGS解析を始めた時にぶつかりがちな小さい壁あれこれNGS解析を始めた時にぶつかりがちな小さい壁あれこれ
NGS解析を始めた時にぶつかりがちな小さい壁あれこれ
 
Read daemon on 20121110 by shinaisan
Read daemon on 20121110 by shinaisanRead daemon on 20121110 by shinaisan
Read daemon on 20121110 by shinaisan
 
システムパフォーマンス勉強会#5
システムパフォーマンス勉強会#5システムパフォーマンス勉強会#5
システムパフォーマンス勉強会#5
 
DTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめDTraceによるMySQL解析ことはじめ
DTraceによるMySQL解析ことはじめ
 
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
 
Dbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publishDbts2012 unconference wttrw_yazekatsu_publish
Dbts2012 unconference wttrw_yazekatsu_publish
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSP
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Java concurrency in_practice_chap06
Java concurrency in_practice_chap06Java concurrency in_practice_chap06
Java concurrency in_practice_chap06
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
 
MINCS – containers in the shell script
MINCS – containers in the shell scriptMINCS – containers in the shell script
MINCS – containers in the shell script
 

Recently uploaded

Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 

Recently uploaded (9)

Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 

【学習メモ#8th】12ステップで作る組込みOS自作入門

  • 5. ポーリングによるサービスの実行 ● 割込みを利用せず一定時間ごとにサービスを実 行する場合、ビジーループで行う方法がある int main() { . . while(1) { if(0.1秒が経過したか) { led_main(); } } . . } int led_main() { (LEDを点滅させる処理) }
  • 6. 複数のサービスを切り替えて実行 ● 今度は一定時間ごとに複数のサービスを切り替 えて実行するケース int main() { . . while(1) { if(0.1秒が経過したか) { led_main(); } if (1秒が経過したか?) { write_time(); } if (シリアル受信したか?) { command_exec(); } } . . }
  • 7. メイン・ループ ● 前のページのように、while(1)のような処理の 中心となるループをメイン・ループと呼ぶ ● それぞれ一定時間ごとにチェックしながらサー ビスを実行する場合、このビジー・ループの方 法だと重い処理を行うときに時間がずれる ● そういった重い処理をビジー・ループで正常に 回したいなら、一定のタイミングごとにメイ ン・ループに戻るという方法が考えられる – 処理状態を保存して(サンプルの場合はstaticの変 数に格納している)戻る感じだね ● とはいえ、サービスの増加や処理が複雑になっ ていけば、このような方法ではもたない
  • 8. 処理の共通化 ● サービスに対する処理を共通化する – 定期的な処理の切り替え – 処理状態の中断、保存、再開 ● 処理状態の保存ならstaticの変数に退避させず にスタックとレジスタの状態を保存すればいい – 各々の関数で行う必要はない ● このためには、実行する処理をサービスの単位 で区切る必要がある ● このサービスの単位をタスクと呼ぶ
  • 9. タスクをスレッドとして実装 ● スレッドとして実装することでプログラムをタ スクごとに独立して動作できる – 下記のようなイメージで書ける int main() { kz_start(start_threads, …); return 0; } ini start_threads(int argc, char *argv[]) { kz_run(led_main, “led”, 1, ...); kz_run(timer_main, “timer”, 1, ...); kz_run(command_main, “command”, 1, ...); while(1) { asm volatile(“sleep”); } } . .
  • 10. スレッドの起動とシステム・コール ● kz_run()にタスクにあたる関数を渡すことで、 それをOSがメイン関数としてスレッドを起動す る – こうすることで各タスクはスレッドとしてひとつの 処理単位で動作する ● kz_run()のようにOSに対するサービス要求をす る関数をシステム・コールと呼ぶ ● タスクの切り替えは割込みが発生したときかシ ステム・コールが呼ばれたときに行われる
  • 11. スケジューリングとディスパッチ ● 割込みかシステム・コールが呼ばれたとき、次 に動作すべきスレッドの選択とその処理再開が 行われる – 前者をスケジューリングと呼び、後者をディスパッ チと呼ぶ ● 動作を中断したスレッドをディスパッチによっ て再開するには、中断時の処理状態を保存して おく必要がある – その情報をコンテキスト情報、あるいは単にコンテ キストと呼ぶ
  • 12. コンテキスト情報 ● 一般的にはSPやPCも含む各種レジスタ値がス レッドのコンテキストにあたる ● スレッドのディスパッチにはそのスレッドのコ ンテキストを新たに読み込む必要がある – この動作をコンテキスト切り替え、コンテキスト・ チェンジと呼ぶ ● スレッドはタスクがそれぞれ独立して実行して いるようにみせかけているだけで、実際は細か くタスクを切り替えながら並列に動作させてい るに過ぎない
  • 13. アプリケーション・プログラム ● スレッドを実装することで各種サービスをタス クに分割してスレッド化し、別々のプログラム のように動作させることができる ● OS上でタスクとして動作するプログラムを一般 にアプリケーション・プログラムと呼ぶ – 日本語では応用プログラムと言う – スレッドとして動作するならそのスレッドはユー ザ・スレッドと呼ぶことができる
  • 14. カーネル ● OSの中核のことをカーネル、またはコアと呼ぶ ● もともと備わっているアプリケーション・プロ グラムも含めた全体をOSと呼ぶ場合と、カーネ ル部分のみをOSと呼ぶ場合がある ● たとえばWindowsでいうところのエクスプロー ラはアプリケーション・プログラムだし、Mac でいえばFinderがそれにあたる
  • 15. 割込みでスレッドの切り替え ● スレッドの切り替えはOSが適当なタイミングで 行う。具体的には割込み処理で行う ● 割込み処理を応用すればレジスタ値の保存と復 旧の処理をスムーズに行える – たとえば、割込み復帰命令を応用すればディスパッ チすることができるなど ● スレッドの切り替えは割込み処理でなくてもで きるけど、割込みの「処理を強制的に中断す る」性質を利用した方が正確な動作が期待でき る
  • 16. システム・コール ● OSは割込み処理の延長として動作する – このためスレッドからOSの機能を利用するには、ス レッド側から明示的に割込みを発生させるのが適切 ● このために多くのCPUはソフトウェア的に割込 みを発生させることができるシステム・コール 命令を持っている – 命令を実行するとシステム・コール割込みという内 部割り込みが発生 – あとは外部割り込みの要領で割込みハンドラを用意 してそれを実行させる流れ ● こういう手順で実装されるOSのサービスを一般 的にシステム・コールと呼ぶ
  • 18. プログラムの追加 ● ブートローダ – 無し ● OS – kozos.h,kozos.c...スレッドの実装 – syscall.h,syscall.c...システムコール利用のため の関数 – test08_1.c...テスト・プログラム
  • 19. プログラムの修正 ● ブートローダ – ld.scr...割込みとブートのスタックを明確化 – intr.S...割込みスタックへの切り替えを追加 – startup.s...ブートスタックを利用するように変更 ● OS – ld.scr...スタックを分離、明確化 – startup.s...スレッドのディスパッチを追加 – defines.h...型の定義を追加 – main.c...OSを利用するように変更 – Makefile
  • 20. ブートローダの修正 ● スタックをスレッドごとに確保するように変え る ● スタックを3種類に分ける – 起動処理で利用(ブートスタック) – 割込み処理で利用(割込みスタック) – スレッドごとに確保(ユーザ・スタック) ● ブートローダにユーザ・スタックは必要ないの で上2つだけ
  • 21. 割込みスタック ● 割込み処理のタイミングでスタックを切り替え ● ld.scrでスタックのアドレスを取得し、intr.S とstartup.sにてそれぞれ切り替えている – ここではintr.Sのsyscallだけだけ表示 _intr_syscall: . . . mov.l er0, @-er7 mov.l er7, er1 mov.l #_intrstack, sp ←割込みスタックを利用 mov.l er1, @-er7 mov.w #SOFTVEC_TYPE_SYSCALL, r0 jsr @_interrupt mov.l @er7+, er1 mov.l er1, er7a
  • 22. OSの修正と追加 ● 修正と追加内容 – スタックの分離 – ディスパッチの実装 – スレッドの実装 – システムコールの実装 – アプリケーションの実装 ● スタックについてはブートローダと同じ
  • 23. ディスパッチ(startup.s) ● @er0, er7でスタックポインタをユーザ・ス タックの位置に切り替えていると思われる – 以降はthread_run()で用意したユーザ・スタックを 使っていく – あとは書籍の説明にある通り _dispatch: mov.l @er0, er7 mov.l @er7+, er0 mov.l @er7+, er1 mov.l @er7+, er2 mov.l @er7+, er3 mov.l @er7+, er4 mov.l @er7+, er5 mov.l @er7+, er6 rte
  • 24. スレッド(kozos.c) ● 大まかな流れとしては、kz_start()で初期ス レッドを生成し、それからkz_run()でcommand スレッドを生成しているという流れ ● この際に実装したシステム・コールを利用して いる ● 処理があっちこっち飛んでいるうえに構造体が あるので理解しにくい部分だと思う ● コードの量が多いので、最後のまとめで細かい 部分を記述する
  • 25. システムコール(syscall.c) ● kozos.cで定義しているシステム・コールを呼 び出すためのサービス関数(API) ● アプリ側からOSの機能を利用するときに使うイ ンタフェース ● 今はkz_run()とkz_exit()を持ってい て、kozos.cのsyscall()を呼び出す機能を持っ ている ● その先にsyscall()からthread_intr()に渡すた めのパラメータを構造体に設定して持っている
  • 26. アプリケーション (test08_1_main.c) ● コンソールからの文字を入力された通りに返す アプリ ● ここは特に難しくないので特に触れない
  • 28. ビルドの失敗(kozos.c) ● ビルドに失敗した ● どうもプロトタイプ宣言は関数の外にする必要 があるらしい。(gcc4.7.1ではこうしなければ ならない) static void thread_intr(softvec_type_t type, unsigned long sp); static int setintr(softvec_type_t type, kz_handler_t handler) { softvec_setintr(type, thread_intr); handlers[type] = handler; return 0; }
  • 29. もういっこビルドの失敗(kozos.c) ● どうも構造体の大きさに問題があるらしい。そ こで64bitの構造体へと大きさを調節 ● アライメントだったけなこれ typedef struct _kz_thread { . . } syscall; kz_context context; char dummy[16]; ←ここを追加 } kz_thread;
  • 30. プログラムの実行 /Users/sandai/12step/src/08/os% sudo cu -l /dev/tty.usbserial-FTG6PQ4H Connected. kzload (kozos boot loader) started. kzload> load ~+lsx kozos Sending kozos, 27 blocks: Give your local XMODEM receive command now. Bytes Sent: 3584 BPS:282 Transfer complete XMODEM receive succeeded! kzload> run starting from entry point: ffc020 kozos boot succeed! start EXIT. test08_1 started. > echo eeee eeee > exit test8_1 exit. command EXIT. system error.
  • 32. まとめ1 ● 8ステップが今までで一番難しい気がする ● いくつかメモを取りながら構造体のパラメータ を把握して、流れを読み取る必要があるだろう ● 細かい説明は書籍にあるのでいいとして、ここ では全体的な流れを細かく記述しておく
  • 33. まとめ2 ● main関数からkz_start()呼び出し ● kz_start() – データの初期化 – setintrによる割込みハンドラの設定 – thread_run()の直接呼び出しによる初期スレッドの 生成 – 作成したスレッドをdispatch()により起動 ● thread_init()が呼び出される – thp->init.func()によりstart_threads()を 呼び出し
  • 34. まとめ3 ● start_threads()でkz_run()が呼び出される ● kz_run() – 受け取ったパラメータを構造体に設定 – それからkz_syscallでシステム・コール発行 ● kz_syscall() – 受け取ったシステムコールの種類(type)と、設定し た構造体をcurrent->syscall.xxxに退避 – その後asm volatile(“trapa #0”)でトラッ プ命令の割込みを自発的に発生させる
  • 35. まとめ3 ● トラップ命令が発生するとsetintr()で設定し たthread_intr()が呼び出される ● thread_intr() – spのコンテキストをcurrent->contextに保存 – handlers[type]()でsetintr()のときに登録したハ ンドラのうち、syscall_intr()を呼び出す ● syscall_intr()からsyscall_proc()を呼び出す
  • 36. まとめ4 ● syscall_proc() – getcurrent()により、カレント・スレッドをキュー から外す。この段階ではキューには何も入っていな い状態になる – call_functions()を呼び出す ● call_functions() – KZ_SYSCALL_TYPE_RUNが今回のシステムコールの種 類なので、thread_run()が実行される – パラメータはkz_syscall()のときに退避させておい たcurrent->syscall_param
  • 37. まとめ5 ● thread_run()が実行されたら、処理がさっきの thread_intr()まで戻る – handler[type]()ってやってたところね – たぶんここの流れがわかりにくいが、割込み処理が 終了したのだから戻るのは当たり前 ● thread_intr()に戻ると、schedule()が実行さ れ、キューの先頭がカレントスレッドになる – カレントスレッドは最初に起動したstartスレッ ド。このスレッドの流れもつかみにくい部分だけ ど、きっちり処理を追えば分かるはず ● そしてdispatch()で割込みで中断していた startスレッドが再開される
  • 38. まとめ6 ● startスレッドの再開は、thp->init.func()が 丁度終えたところから – thread_end()の呼び出し。実体はkz_exit() ● kz_exit() – kz_syscall()でシステムコールが発行される – 種類はKZ_SYSCALL_TYPE_EXIT ● kz_syscall() – パラメータはNULLなので何もなし – asm volatile(“torapa #0”)のトラップ命令で割 込みが発生し、thread_intr()が呼び出される
  • 39. まとめ7 ● thread_intr() – handlers[type]()が呼び出される。これは syscall_intr()にあたる ● syscall_intr() – ここでsyscall_proc()が呼び出される ● syscall_proc() – getcurrent()により、カレントスレッドである startスレッドがキューから外れる – call_functions()の呼び出し
  • 40. まとめ8 ● call_functions() – typeはKZ_SYSCALL_TYPE_EXITなの で、thread_exit()が呼び出される – thread_exit()が呼び出され、start EXITの文字が 出力され、memset()でスレッドがクリアされ消滅 ● 処理はthread_intr()に戻り、schedule()の呼 び出しによって、commandスレッドがキューの 先頭に来る ● それからdispatch()によりcommandスレッドが 起動
  • 41. まとめ9 ● dispatch()によりthread_init()が呼び出さ れ、thp->init.func()によりtest08_1_mainが 呼び出されるという流れ ● ながいーおわりー
  • 42. まとめまとめまとめー ● kz_start()の存在があるからちょっとわかりに くいけれど、これは結局は、スレッドを起動す るための「スレッド」を作ってる ● でまあスレッドを作ったらkz_exit()でシステ ムコールを発行して、次のスレッドを起動させ ているってわけね ● thread_run()をシステムコールから発行してい ないので、ちょっと違和感がある