SlideShare uma empresa Scribd logo
1 de 25
Baixar para ler offline
12ステップで作る組込みOS自作入門
      12thステップ




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

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

【税込価格】
4,410円

【サポートページ】
http://kozos.jp/books/makeos/
もくじ
1.割込みとスレッド
2.コマンド処理の実装
3.プログラムの実行
1.割込みとスレッド
割込みの延長で動作
●   7thのようなサンプル・プログラムは、シリア
    ル受信割込みのハンドラ内部でコマンド応答処
    理を行なっている
    –   こういった実装を「割込みの内部で処理している」
        「割込みの延長で動作する」などと呼ぶ
●   割込みの内部で処理すると、重たい処理であれ
    ば割込みの遅延が発生するので良くない
●   割込みハンドラで必要な処理を行うのではな
    く、処理用のスレッドで行う形が良い
    –   シリアル通信を例に行なってみる
シリアル送受信の場合
●   シリアル・コントローラは送信と受信の割込み
    ベクタが同じなので、一つの割込みハンドラで
    送信と受信の処理を行う
●   シリアル受信割込みはデータを受信することで
    割込みが発生する
●   シリアル送信割込みは1文字送信を行ったと
    き、その送信処理が完了して次の文字の送信が
    可能になったときに発生する
シリアル受信割込み
●   シリアル受信処理の実装
    –   ①割込みハンドラで受信文字を取り出してメッセー
        ジによりコマンド応答スレッドに送信
    –   ②コマンド応答スレッドは、メッセージを受信した
        ら文字を組み立ててコマンドとして解釈し、該当の
        処理を行う
●   こうすればシリアル受信の割込みはコマンド応
    答スレッドに受信文字を送信するだけで済む
シリアル送信割込み
●   これまでの方法だとビジーループにより送信可
    能になるまで待ち合わせる形だった
●   ビジーループ中は他の処理が行えず、CPUが空
    回りしている状態でCPU時間が無駄
●   この問題を回避する方法として、シリアル送信
    割込みを利用する
シリアル送信割込みの実装例
●   実装例
    –   シリアル送信の割込みハンドラとシリアル送信ス
        レッド作成
    –   シリアル送信スレッドは送信要求を受けたら、送信
        バッファに送信する文字列を書き込み、先頭の1文
        字を送信。送信後に割込み待ち状態に
    –   1文字の送信が完了するとシリアル送信割込みが発
        生。割込みハンドラでは送信バッファを参照し、未
        送信の文字列が残っているならば次の1文字を送信
    –   1文字の送信が完了すると再度送信割込みが入る
●   この部分は今回のプログラムでいうところの
    consdrv.cにあたる
非タスク・コンテキスト
●   シリアル受信割込みが発生したとき、スレッド
    に受信データを渡し、コマンド・スレッドでコ
    マンド応答処理を行う
●   要は受信データは行単位でメモリに格納して
    メッセージ通信により渡す流れとなる
    –   つまり、シリアル受信割込み発生中にメッセージ通
        信とメモリ獲得の割込みが必要となり、割込み中に
        割込みが発生するという結果になる。これではコン
        テキスト情報が破壊されてしまい正常に動作しない
●   割込み処理中は中断も再開もできないわけで、
    スレッドのようにスリープさせられない
●   こういう状態を非タスク・コンテキストと呼ぶ
タスク・コンテキスト
●   割込みが非タスク・コンテキストで動作するな
    ら、スレッドの状態はタスク・コンテキストと
    呼ぶ
●   割込み中の割込みではコンテキスト情報の保存
    先が無いため、システム・コールは呼べない
●   よって、スレッドへのデータの受け渡しのため
    に、割込みではないけれど同じ処理ができる
    サービスをOSに実装する必要がある
サービス・コール
●   そこで、システム・コールと同じ処理を割込み
    でなく関数として呼び出せるサービス・コール
    という機能を実装する
    –   実体はシステム・コールと全く同じ。KOZOSでは呼
        び名を変えているだけ
●   サービス・コールは割込みハンドラでの処理中
    に、システム・コールと同じようなことができ
    るための関数ってわけ
●   よって、サービス・コールは割込みハンドラで
    のみ利用可能でスレッドからの利用は一切禁止
    –   スレッドの実行中に割込みが入り他スレッドに処理
        が切り替わったりそのスレッドがシステム・コール
        を発行すると、関数が再入される可能性もあるため
追加するサービス・コール
●   追加するサービス・コールは以下の4つ
    –   kx_wakeup()
    –   kx_send()
    –   kx_kmalloc(),kx_kmfree()
●   実際はシステム・コールのkz_xxxと同じで、割
    込みハンドラ内でのみ利用可能
    –   処理内容はkz_wakeup()をコピペして、kx_wakeup()
        にしただけのやつ
排他
●   シリアル送信割込みでは送信バッファの扱いに
    注意する必要がある
●   送信バッファをスレッドと割込みという異なる
    コンテキストから操作しており、再入が行われ
    る可能性がある
●   そこで今回は割込み禁止にして送信を行う関数
    を再入させないようにする
割込みの管理
●   今まで割込みハンドラの登録は内部のサービス
    関数によって行なっていたけれど、ここでシス
    テム・コールとして利用できるようにしている
●   これでOSのユーザが割込みハンドラを自由に登
    録できるようにはなった
UMLのコマンド処理図




448頁 図12.1 シーケンス図 より
2.コマンド処理の実装
プログラムの修正と追加
●   追加ファイル
    –   consdrv.h,consdrv.c...コンソール・ドライバ・ス
        レッド
    –   command.c...コマンド・スレッド
●   修正ファイル
    –   defines.h...メッセージIDの定義
    –   syscall.h,syscall.c...システム・コール、サービ
        ス・コールの追加
    –   kozos.h,kozos.c...システム・コール、サービス・
        コールの追加
    –   main.c...起動するスレッドの修正
    –   Makefile
修正と追加内容
●   サービス・コール追加
    –   追加した関数についてはスライドの12p参照
    –   サービス・コールの追加に伴い、ごちゃごちゃと細
        かい部分修正
●   コンソール・ドライバ・スレッド追加
    –   コンソールを利用するためのデバイス・スレッド
    –   基本的には他スレッドからのコマンド
        (CONSDRV_CMD_USEやCONSDRV_SMD_WRITE)受け付け
        と、シリアル送受信の処理が行われる(割込みハン
        ドラもここで登録)
●   コマンド・スレッド追加
    –   コンソールからのコマンド処理を行う
●   あとはまあいろいろだ
構造体のパディング
●   一般的なCPUでは整数値などのデータはそのサ
    イズにアライメントされている必要がある
    –   2バイトのデータは2の倍数のアドレス、4バイトの
        データは4の倍数のアドレスに配置されている必要
        があるわけ
●   アドレスをなんらかの値の倍数に合わせること
    をアライメントと呼び、その倍数を境界やバウ
    ンダリと言う
●   今回はconsregという構造体でアライメントが
    為されており、アライメント調節用の付加領域
    のことを一般にパディングと呼ぶ。パディング
    はコンパイラによって自動的に付加される
シリアル送受信の処理
●   consdrv.cにあるconsdrv_intrproc()が割込み
    の実質的な処理にあたる
●   コンソールに文字が入力されたとき(シリアル
    受信割込み)と、コンソールに1文字送信して送
    信処理が完了し、次の文字が送れるようになっ
    たとき(シリアル送信割込み)の処理を行う
●   1つの関数で2つ役割があるので注意すること
●   この割込みハンドラではsend_char()を利用し
    ているが、スレッド側からもこの関数を利用し
    ている(スレッド側は実際はsend_string())
●   再入の不具合がおこるのでスレッド側から呼び
    出すときは割込み禁止にして呼び出されている
3.プログラムの実行
a
/Users/sandai/12step/src/12/os% sudo cu -l /dev/tty.usbserial-
FTG6PQ4H
.
.
.
kzload> run
starting from entry point: ffc020
kozos boot succeed!
command> echo aaa
  aaa
command>
4.まとめ
まとめ
●   今回のポイントはシリアル送受信の割込み部分
    と、それを可能にしているタスク間通信。ス
    レッドはいわずもがな
●   最終的にはCPUとメモリとI/Oをユーザから操作
    できるようなシステムコールが実装されたこと
    になる
●   あとはタイマとかLANのドライバとか書いたり
    するのが発展系なんだろう
●   おつかれーつかれたー

Mais conteúdo relacionado

Destaque

組込みにおけるHTML5
組込みにおけるHTML5組込みにおけるHTML5
組込みにおけるHTML5
Tomo Watanabe
 
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
Hirotaka Kawata
 

Destaque (17)

C++でできる!OS自作入門
C++でできる!OS自作入門C++でできる!OS自作入門
C++でできる!OS自作入門
 
ハッキング実演
ハッキング実演ハッキング実演
ハッキング実演
 
ゲーム組み込み用スクリプト言語を作ってみた
ゲーム組み込み用スクリプト言語を作ってみたゲーム組み込み用スクリプト言語を作ってみた
ゲーム組み込み用スクリプト言語を作ってみた
 
バイナリで遊ぼう(オープンソースカンファレンス2014 Tokyo/Fall ライトニングトーク)
バイナリで遊ぼう(オープンソースカンファレンス2014 Tokyo/Fall ライトニングトーク)バイナリで遊ぼう(オープンソースカンファレンス2014 Tokyo/Fall ライトニングトーク)
バイナリで遊ぼう(オープンソースカンファレンス2014 Tokyo/Fall ライトニングトーク)
 
コンピュータビジョン 1章
コンピュータビジョン 1章コンピュータビジョン 1章
コンピュータビジョン 1章
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】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自作入門
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門
 
【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門【学習メモ#4th】12ステップで作る組込みOS自作入門
【学習メモ#4th】12ステップで作る組込みOS自作入門
 
組込みにおけるHTML5
組込みにおけるHTML5組込みにおけるHTML5
組込みにおけるHTML5
 
【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門 【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門
 
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
 
QEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングQEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミング
 
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
バイナリより低レイヤな話 (プロセッサの心を読み解く) - カーネル/VM探検隊@北陸1
 
アセンブラ漢文
アセンブラ漢文アセンブラ漢文
アセンブラ漢文
 

Último

Último (11)

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 

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

  • 5. 割込みの延長で動作 ● 7thのようなサンプル・プログラムは、シリア ル受信割込みのハンドラ内部でコマンド応答処 理を行なっている – こういった実装を「割込みの内部で処理している」 「割込みの延長で動作する」などと呼ぶ ● 割込みの内部で処理すると、重たい処理であれ ば割込みの遅延が発生するので良くない ● 割込みハンドラで必要な処理を行うのではな く、処理用のスレッドで行う形が良い – シリアル通信を例に行なってみる
  • 6. シリアル送受信の場合 ● シリアル・コントローラは送信と受信の割込み ベクタが同じなので、一つの割込みハンドラで 送信と受信の処理を行う ● シリアル受信割込みはデータを受信することで 割込みが発生する ● シリアル送信割込みは1文字送信を行ったと き、その送信処理が完了して次の文字の送信が 可能になったときに発生する
  • 7. シリアル受信割込み ● シリアル受信処理の実装 – ①割込みハンドラで受信文字を取り出してメッセー ジによりコマンド応答スレッドに送信 – ②コマンド応答スレッドは、メッセージを受信した ら文字を組み立ててコマンドとして解釈し、該当の 処理を行う ● こうすればシリアル受信の割込みはコマンド応 答スレッドに受信文字を送信するだけで済む
  • 8. シリアル送信割込み ● これまでの方法だとビジーループにより送信可 能になるまで待ち合わせる形だった ● ビジーループ中は他の処理が行えず、CPUが空 回りしている状態でCPU時間が無駄 ● この問題を回避する方法として、シリアル送信 割込みを利用する
  • 9. シリアル送信割込みの実装例 ● 実装例 – シリアル送信の割込みハンドラとシリアル送信ス レッド作成 – シリアル送信スレッドは送信要求を受けたら、送信 バッファに送信する文字列を書き込み、先頭の1文 字を送信。送信後に割込み待ち状態に – 1文字の送信が完了するとシリアル送信割込みが発 生。割込みハンドラでは送信バッファを参照し、未 送信の文字列が残っているならば次の1文字を送信 – 1文字の送信が完了すると再度送信割込みが入る ● この部分は今回のプログラムでいうところの consdrv.cにあたる
  • 10. 非タスク・コンテキスト ● シリアル受信割込みが発生したとき、スレッド に受信データを渡し、コマンド・スレッドでコ マンド応答処理を行う ● 要は受信データは行単位でメモリに格納して メッセージ通信により渡す流れとなる – つまり、シリアル受信割込み発生中にメッセージ通 信とメモリ獲得の割込みが必要となり、割込み中に 割込みが発生するという結果になる。これではコン テキスト情報が破壊されてしまい正常に動作しない ● 割込み処理中は中断も再開もできないわけで、 スレッドのようにスリープさせられない ● こういう状態を非タスク・コンテキストと呼ぶ
  • 11. タスク・コンテキスト ● 割込みが非タスク・コンテキストで動作するな ら、スレッドの状態はタスク・コンテキストと 呼ぶ ● 割込み中の割込みではコンテキスト情報の保存 先が無いため、システム・コールは呼べない ● よって、スレッドへのデータの受け渡しのため に、割込みではないけれど同じ処理ができる サービスをOSに実装する必要がある
  • 12. サービス・コール ● そこで、システム・コールと同じ処理を割込み でなく関数として呼び出せるサービス・コール という機能を実装する – 実体はシステム・コールと全く同じ。KOZOSでは呼 び名を変えているだけ ● サービス・コールは割込みハンドラでの処理中 に、システム・コールと同じようなことができ るための関数ってわけ ● よって、サービス・コールは割込みハンドラで のみ利用可能でスレッドからの利用は一切禁止 – スレッドの実行中に割込みが入り他スレッドに処理 が切り替わったりそのスレッドがシステム・コール を発行すると、関数が再入される可能性もあるため
  • 13. 追加するサービス・コール ● 追加するサービス・コールは以下の4つ – kx_wakeup() – kx_send() – kx_kmalloc(),kx_kmfree() ● 実際はシステム・コールのkz_xxxと同じで、割 込みハンドラ内でのみ利用可能 – 処理内容はkz_wakeup()をコピペして、kx_wakeup() にしただけのやつ
  • 14. 排他 ● シリアル送信割込みでは送信バッファの扱いに 注意する必要がある ● 送信バッファをスレッドと割込みという異なる コンテキストから操作しており、再入が行われ る可能性がある ● そこで今回は割込み禁止にして送信を行う関数 を再入させないようにする
  • 15. 割込みの管理 ● 今まで割込みハンドラの登録は内部のサービス 関数によって行なっていたけれど、ここでシス テム・コールとして利用できるようにしている ● これでOSのユーザが割込みハンドラを自由に登 録できるようにはなった
  • 18. プログラムの修正と追加 ● 追加ファイル – consdrv.h,consdrv.c...コンソール・ドライバ・ス レッド – command.c...コマンド・スレッド ● 修正ファイル – defines.h...メッセージIDの定義 – syscall.h,syscall.c...システム・コール、サービ ス・コールの追加 – kozos.h,kozos.c...システム・コール、サービス・ コールの追加 – main.c...起動するスレッドの修正 – Makefile
  • 19. 修正と追加内容 ● サービス・コール追加 – 追加した関数についてはスライドの12p参照 – サービス・コールの追加に伴い、ごちゃごちゃと細 かい部分修正 ● コンソール・ドライバ・スレッド追加 – コンソールを利用するためのデバイス・スレッド – 基本的には他スレッドからのコマンド (CONSDRV_CMD_USEやCONSDRV_SMD_WRITE)受け付け と、シリアル送受信の処理が行われる(割込みハン ドラもここで登録) ● コマンド・スレッド追加 – コンソールからのコマンド処理を行う ● あとはまあいろいろだ
  • 20. 構造体のパディング ● 一般的なCPUでは整数値などのデータはそのサ イズにアライメントされている必要がある – 2バイトのデータは2の倍数のアドレス、4バイトの データは4の倍数のアドレスに配置されている必要 があるわけ ● アドレスをなんらかの値の倍数に合わせること をアライメントと呼び、その倍数を境界やバウ ンダリと言う ● 今回はconsregという構造体でアライメントが 為されており、アライメント調節用の付加領域 のことを一般にパディングと呼ぶ。パディング はコンパイラによって自動的に付加される
  • 21. シリアル送受信の処理 ● consdrv.cにあるconsdrv_intrproc()が割込み の実質的な処理にあたる ● コンソールに文字が入力されたとき(シリアル 受信割込み)と、コンソールに1文字送信して送 信処理が完了し、次の文字が送れるようになっ たとき(シリアル送信割込み)の処理を行う ● 1つの関数で2つ役割があるので注意すること ● この割込みハンドラではsend_char()を利用し ているが、スレッド側からもこの関数を利用し ている(スレッド側は実際はsend_string()) ● 再入の不具合がおこるのでスレッド側から呼び 出すときは割込み禁止にして呼び出されている
  • 23. a /Users/sandai/12step/src/12/os% sudo cu -l /dev/tty.usbserial- FTG6PQ4H . . . kzload> run starting from entry point: ffc020 kozos boot succeed! command> echo aaa aaa command>
  • 25. まとめ ● 今回のポイントはシリアル送受信の割込み部分 と、それを可能にしているタスク間通信。ス レッドはいわずもがな ● 最終的にはCPUとメモリとI/Oをユーザから操作 できるようなシステムコールが実装されたこと になる ● あとはタイマとかLANのドライバとか書いたり するのが発展系なんだろう ● おつかれーつかれたー