Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Interrupts on xv6

Takuya ASADA
September 02, 2012

Interrupts on xv6

Takuya ASADA

September 02, 2012
Tweet

More Decks by Takuya ASADA

Other Decks in Technology

Transcript

  1. 割り込みとは ž  現在CPU上で実行しているプログラムを停止 して別の処理を実行する為にCPUが持つ機能 —  UNIX上のアプリケーションにおける「シグナル」に 近い概念 ž  二種類ある — 

    ハードウェア割り込み ◦  ハードウェアからCPUへ「キーボード押されたよ」な どのメッセージを通知するのに使う ◦  単に「割り込み」と呼ばれる事もある —  ソフトウェア割り込み ◦  ソフトウェアから割り込みを起こせる ◦  モード切替に利用される→システムコールに使う
  2. 書き込みが終了したら? 割り込みを使う場合 ž  送信完了時の処理は、割り込み着信時に実行すれ ばいい 書き込み処理: send_write_request(buffer); sleep(buffer); 割り込みハンドラ: buffer

    = find_buffer(ata_reg); buffer.is_dirty = 0; wakeup(buffer); ž  busy waitしていない分のCPU時間を別の処 理(別のプロセスを実行など)にまわせる ž  sleep()/wakeup()で待ち合わせ
  3. 割り込みハンドラ ž  割り込みを受けた時にCPUが実行するプロ グラム(関数呼び出しを伴わない関数のよ うなもの) ž  割り込みハンドラ実行時にCPUがレジスタ の状態をスタックへ退避 ž  ハードウェア割り込みの場合は、デバイス

    のレジスタを読んで割り込みの処理に応じ た最小限の処理を実行 ž  割り込みハンドラから終了用の命令を実行 して、スタックから割り込み前の状態へ復 帰
  4. IDT(Interrupt Descriptor Table)と IDTR ž  各ベクタの割り込みハンドラの情報を持 つGate Descriptorが並んでいるメモリ上 のテーブル ž 

    テーブルの先頭アドレスとLimit値 (テーブルのサイズ、255未満のGate数 に対応)をCPUのIDTRに書き込む事に より設定(IDTRを設定しない限り、 CPUは割り込み時に何をしたらいいか 分からない)
  5. Gate Descriptor ž  前述の「割込みハンドラ」のアドレスを持つ 構造体 ž  単なる関数へのポインタではなくて、セグメ ントの設定とか権限(Ring)とか16 bit/32 bit

    のモード選択とか、幾つかのパラメータを含 む ž  Task gate, Interrupt gate, Trap gateの三種類あ る —  Task gateはHWのマルチタスク機能でハンドリング する方法で今は使われていない —  Interrupt gateとTrap gateは普通に割り込みハンドラ へジャンプする方法 EFLAGS.IFフラグをクリアするか否かが違い
  6. IDT,IDTR,Gate descriptorの関係 Base address Limit 0 15 16 47 IDTR

    register IDT Gate for interrupt 0 Gate for interrupt 1 Gate for interrupt 2 Gate for interrupt 3 … Gate for interrupt 255 offset 15..0 segment selector rese rved DPL /P offset 31..16 Interrupt Gate
  7. xv6のIDT周りを見てみる ž  main.c:main() —  tvinit(); 割り込みベクタの設定 —  mpmain(); ◦  idtinit();

    IDTRの設定 ž  trap.c:tvinit() —  for(0..255) SETGATE(idt[i] … vectors[i] …) idt[i]にvectors[i]を割り込みハンドラとしたgate descriptorを設定 —  システムコールだけDPL_USERに ž  trap.c:idtinit() —  x86.h:lidt() ◦  asm volatile(“lidt (%0)” :: “r” (pd)); LIDT命令でidtのアド レスを設定
  8. xv6の割り込み・例外ハンドラ ž  vectors.pl→vectors.S —  vectorsはvector0..vector255を指すポインタが入っている テーブルで、vectorNはalltrapsを呼んでいる ž  trapasm.S —  全レジスタpush

    —  pushl %esp —  call trap —  全レジスタpop —  iret (割り込みからの復帰) ž  trap.c:trap() —  trapasm.Sから引数として渡されたスタックポインタを構 造体として参照 —  trapnoがシステムコールの場合・タイマ/IDE/キーボー ド/シリアル割り込みの場合についてそれぞれのハンド ル関数をコールしている
  9. Advanced Programmable Interrupt Controller (APIC) ž  オリジナルのx86アーキテクチャでは割 り込みコントローラとしてPIC(8259)を 使っていたが、P6以降のx86アーキテク チャではAPICへ移行(PICも未だ存在し

    ていて使える) ž  CPU毎に存在しCPUに内蔵されている Local APICと、ICH(Southbridge)に 内蔵されているI/O APICから構成されて いる
  10. Local APICとI/O APIC CPU Local APIC CPU Local APIC CPU

    Local APIC ICH(South bridge) IOAPIC External Interrupts 8259A PIC LINT0 LINT1 NMI IPI Timer
  11. Local Vector Table ž  ローカル割り込みのベクタ番号を設定 —  CMCI(Corrected Machine Check Interrupt)

    —  Timer —  Thermal Monitor —  Performance Counter —  LINT0/1 レガシーデバイスとか —  Error ž  外部割り込みはここで設定しない
  12. 割り込みの受信 ž  IRR: Interrupt Request Register CPUが未処理の割り込みベクタ番号にビッ トが立っている ž  ISR:

    In Service Register 次に割り込む候補 EOIへ書き込まれた時にIRR→ISRへビット が更新される ž  EOI: End Of Interrupt Register 割り込みハンドラ終了通知として0を書き 込む(例外有り)
  13. Redirection Table ž  各IRQの宛先APIC ID, Vectorなどを設定 —  Destination 宛先APIC ID

    —  Mask 割り込みマスク —  Trigger Mode Edge/Level —  Remote IRR —  Interrupt Input Pin Polarity —  Delivery Status Idle/Pending —  Destination Mode Physical/Logical —  Delivery Mode Fixed/Lowest… —  Vector Vector no of interrupt
  14. Destination Mode ž  Physical Destination Mode —  LAPIC上のLocal APIC ID

    Registerの値を指 定する事によりCPUを一意に特定 ž  Logical Destination Mode —  LAPIC上のLogical Destination Registerと Destination Format Registerの値とAddress されたIDがマッチするかどうかで判別
  15. Logical Destination Mode ž  Destination Format Registerでモード選択 ž  flat model

    —  各LAPIC毎にLDRへ異なるbitを立て、宛先アド レスには複数のbitを立てる事で複数のCPUのを 選択可能 —  アドレスが8bitしか無いので対応CPU数は8まで ž  cluster model —  LDRと宛先アドレスを4bitで分割、双方cluster IDとlogical IDを持つ —  使い方がよくわからない…8より多いCPUをサ ポートする為の階層化?
  16. Delivery Mode ž  Fixed Destinationに指定された全てのCPUへ 割り込み ž  Lowest priority DestinationのうちLAPICのTask

    Priority Registerの値が最も小さいCPUへ割り込 み →TPRを制御する事で動的に割り込み先 を変更可能
  17. xv6のLAPIC周りを見てみる ž  main.c:main() —  lapicinit(); LAPICを初期化 ž  lapic.c:lapicinit() —  LAPIC有効化

    —  タイマー初期化 —  LINT0/LINT1、パフォーマンスカウンタ割り 込み無効化 —  エラー割り込みのベクタ番号設定 —  エラーステータスレジスタクリア —  割り込みクリア
  18. xv6のI/O APIC周り ž  main.c:main() —  ioapicinit(); —  ideinit(); ž  ioapic.c:ioapicinit()

    —  全ての割り込みを無効に ž  ide.c:ideinit() —  ioapicenable(IRQ_IDE, ncpu – 1); IRQ_IDEをAPIC ID=ncpu -1へ送るよう設定 —  質問:Delivery ModeとDestination Modeは 何?
  19. PIC(8259) ž  IOAPICと同様ICHに存在 IOAPIC(又はcpu0のLocal APIC)へ接続 されている ž  「古い割り込みコントローラ」のように紹 介したが、レガシデバイスが接続されてい るのでそのようなデバイスを使う場合は

    PICを使う必要がある ž  xv6ではレガシデバイスを使う為、 PIC→IOAPICの順で割り込みの設定を行 なっている —  ideinit(),consoleinit(),uartinit()で呼んでいる ioapicenable()の手前にあるpicenable()
  20. MSI: Message Signal Interrupt MSI-X: MSI Extended Interrupt ž  物理的な割り込み線を用いず、(多分、

    PCIの?)メッセージング機構により割 り込みを通知する仕組み ž  PCI Expressからサポート必須 ž  IO APICを経由しない(!) ž  →割り込み先どうやって決めんの? —  PCI Configuration Spaceに設定