4章 linuxカーネル - 割り込み・例外 2
TRANSCRIPT
4 章 Linux カーネル – 割り込み・例外 2・ IRQ と PIC・ PIC:8259A
maoWeb >https://www.pridact.comTwitter >https://twitter.com/rivartenMail >[email protected]
はじめに
割り込み・例外の話
視点・概要・ハードウェアの動作・データ構造・データ構造の操作の仕方・ソースコード
ソースコードの情報が載っている場合は ,実際にソースコードに目を通しながら資料を見ていったほうがいいかもしれません。
今回はハードウェアの話が多いかもしれません
この資料について
・間違っていたらご指摘をお願い致します。・ Linux Kernel のバージョンは 4.9.16 です。・ページタイトルに * 印が付いているページは、 少し踏み込んだ内容になっています。 ざっと全体に目を通したければ、読み飛ばして もらっても構いません。
カーネル参考文献
< 参考書 > 〜基本的に古い情報だが、基本は学べる〜
・詳解 LINUX カーネル 第 3 版 (O’REILLY・ Linux カーネル 2.6 解読室 (Softbank Creative・ Linux カーネル解析入門 ( 工学社・ Modern Operating Systems 3e International
(Pearson, Andrew S. Tanenbaum) 〜初期化部分を知りたいなら〜
・新装改訂版 Linux のブートプロセスを見る( アスキー・メディアワークス )
< 参考 Web>・ Linux Cross Reference[http://lxr.free-electrons.com]・ Wikipedia
IRQ と PIC(1)
・割り込み要求を生成できる周辺デバイスのコントローラには , 通常 ,IRQ ラインと呼ばれる 1 本の出力ラインがある .・高機能なデバイスには複数の IRQ ラインがある . PCI カードは IRQ ラインを 4 本まで利用可 .
・周辺デバイスのIRQラインは , プログラマブル割り込みコントローラ (Programmable Interrupt Controller:PIC) と呼ばれるハードウェア回路の入力ピンに接続されている .
IRQ と PIC(2)
・ PIC の動作概要
1.IRQ ラインを監視し , 信号の発生を調べる . 2 本以上の IRQ ラインがアサートされている場合には , ( より優先度の高い )小さいピン番号の IRQ ラインを選択 .
2.IRQ ラインの信号を検知した場合には , a. 発生した信号を ,対応するベクタに変換 . b.INT ピンがプロセッサの INTR ピンに接続されている PIC は , INT ピンをアサートして割り込み発行 . c.CPU が割り込み信号を検知したら , PIC は特別なバスサイクルで CPU にベクタを通知する . d.PIC は ,CPU からの EOI(End Of Interrupt,ACK相当 ) を待つ . EOI は ,CPU がPICの I/Oポートに書き込むことにより行う . EOI が返れば ,INTR ラインをクリア .
3. ステップ 1 に戻る .
IRQ と PIC(3)
・周辺デバイス – PIC – CPU 間の動作概要
1. 周辺デバイスが PIC に割り込み要求をする .IRQ ラインをアサート
2.PIC が CPU に割り込み信号を送る .INT ピンをアサート
2.CPU が PIC からの割り込みを受付ける .INTA ピンを 2 回アサート
3.CPU が割り込みハンドラを実行する .4.CPU が PIC に EOI を発行する
IRQ と PIC(4)
・ IRQ ラインと割り込みベクタIRQ ラインは 0から順番に番号が割り当てられている (IRQ0~ ).Intel の場合 ,
割り込みベクタ n = IRQn + 32 (0~31 は例外ベクタが使っている )
PIC のポートに I/O命令を発行することで ,IRQ とベクタのマッピングを変更できる .
・PICを操作することで ,特定の IRQ に対応する割り込み発行を 止めたり再開させたりができる . ほとんどの割り込みハンドラは , この機能を利用して同じ種類の IRQ を 順次処理している . マスク可能割り込みをマスク・マスク解除する事とは違う .
・ CPU の eflagsレジスタの ifフラグ ( 割り込み許可フラグ ) を 0にすると , PIC が発行したマスク可能割り込みを CPU が一時的に無視する . CPUレベルの割り込み禁止処理 . アセンブリ命令 cli → eflags.if=0 アセンブリ命令 sti → eflags.if=1
PIC:8259A (1)
・概要・ Intel 8259 Programmable Interrupt Controller Intel 82C59A-2 かその派生 . ・シングルプロセッサ用 . 今はチップセットに内蔵 . マルチプロセッサ対応の APIC はシステム起動時に PIC互換モードで動作する為 , 知っておくといいかも .
・データシート: https://pdos.csail.mit.edu/6.828/2005/readings/hardware/8259A.pdf ・ピンアサイン 主要なもの
シンボル ピン番号 説明
CS 1 チップセレクト (L アクティブ )
WR 2 ライト (L アクティブ )
RD 3 リード (L アクティブ )
D7-D0 4-11 双方向データバス
CAS0-CAS2 12,13,15 カスケードライン
INT 17 割り込み
IR0-IR7 18-25 割り込み要求 .周辺デバイスに接続 .周辺デバイスが割り込み要求する時 ,H → L にする .CPU の応答が INTA に返ってくるまで L のまま
INTA 26 割り込み応答 .CPU の割り込み応答ピンに接続 .
今時こんなのMBに載ってない
PIC:8259A (2)
・概要・ 1 つのチップには 8個の IRQ ラインがある .・ x86 では ,チップ 2個をカスケード接続して使用する . (OS がブート時に決定していて ,物理的に結線されているのではない . 詳細は ICW コマンドを参照 )・マスタ側の INT 出力ピンは ,CPU側の INTR に接続されている .・ INTA(Interrupt Acknowledge) は , CPU が割り込みを受け付けると Hになる .・スレーブ側の INT 出力ピンは , マスタ側の IRQ2 ピンに接続されている .・カスケード接続で利用可能な IRQ ラインは 16個になる .(正確には 15個 )
データシートより
PIC:8259A (3)
・ IRQ番号の割り当て
だいたい , こういう割り当てになっている .
IRQ番号と I/O デバイスの対応関係は ,デバイスドライバの初期化時に決定される .
IRQ 割り当て IRQ 割り当て
IRQ0 Timer IRQ8 RTC
IRQ1 Keyboard IRQ9 N/A (ACPI SCI)
IRQ2 Slave PIC IRQ10 N/A (Network Interface)
IRQ3 COM B IRQ11 N/A (USB Port,Sound Card)
IRQ4 COM A IRQ12 PS/2 Mouse
IRQ5 LPT B IRQ13 FPU
IRQ6 Floppy Disk Controller IRQ14 Primary IDE Controller
IRQ7 LPT A IRQ15 Secondary IDE Controller
PIC:8259A (4)
・レジスタ・コマンドレジスタ・ステータスレジスタ
・ IRR(Interrupt Request Register): 割り込み要求レジスタ IRQ 発生を記録しておくレジスタ .・ ISR(In-Service Register): 割り込み中レジスタ
・ IMR(Interrupt Mask Register): 割り込みマスクレジスタ
・ ISA アドレス空間にマッピングされている為 , IN/OUT命令で I/Oポートを通してレジスタにアクセスする . 0x20~0x23:PIC マスタ 0xA0~0xA3:PIC スレーブ
・ 0x20/0x21 と 0xA0/0xA1 の仕様は大差ない
I/Oポートアドレス 内容
0x20 マスタ PIC のコマンドレジスタ (WR時 ), ステータスレジスタ ISR/IRR(RD時 )
0x21 マスタ PIC のコマンドレジスタ (WR時 ), 割り込みマスクレジスタ IMR(RD時 )
0xA0 スレーブ PIC のコマンドレジスタ (WR時 ), ステータスレジスタ ISR/IRR(RD時 )
0xA1 スレーブ PIC のコマンドレジスタ (WR時 ), 割り込みマスクレジスタ IMR(RD時 )
PIC:8259A (5)
・コマンド・初期化コマンド ICW(Initialization Control Words)
・ ICW1 初期化手順の決定・ ICW2 割り込みベクタと IRQ の関連付け . ( 割り込み番号のベクタアドレスのベース値指定 )・ ICW3 カスケード接続する IRQ の指定 ( マスタ・スレーブの連結方法の指定 )・ ICW4 EOI のモード設定
・制御コマンド OCW(Operation Command Words)・ OCW1・ OCW2・ EOI Linux では Specific EOI を用いる .
PIC:8259A (6)
・初期化順基本的には以下の順番で連続して書き込みを行うことで初期化する .・マスタ 0x20(ICW1) → 0x21(ICW2) → 0x21(ICW3) → 0x21(ICW4)・スレーブ 0xA0(ICW2) → 0xA1(ICW2) → 0xA1(ICW3) → 0xA1(ICW4)
Linux における初期化処理 ICW1:0x11 ICW2(Master/Slave):0x30/0x38 IRQ0~7 → 割り込みベクタ番号 48~55 IRQ8~15 → 割り込みベクタ番号 56~63 ICW3(Master/Slave):0x04/0x02 ICW4(Master/Slave):0x01[ver4.9.16 arch/x86/kernel/i8259.c:324]init_8259A()
・ EOI(End Of Interrupt) 発行1.ダミーリード (0x21,0xA1)2. 割り込みマスク (0x21,0xA1)3.EOI 発行 (0x20,0xA0)4.PIC スレーブは PIC マスタに EOI 発行 (0x20)
PIC:8259A (7)
・初期化 - PIC Master start_kernel() -> init_IRQ() -> x86_init.irqs.intr_init() -> native_init_IRQ() -> x86_init.irqs.pre_vector_init() = init_ISA_irqs() -> legacy_pic.init(0) -> init_8259A(0)[ver4.9.16 arch/x86/kernel/i8259.c:324] 324 static void init_8259A(int auto_eoi) 325 { 332 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ #outb(0xff,0x21) 337 outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ #outb(0x11,0x20) 338 339 /* ICW2: 8259A-1 IR0-7 mapped to ISA_IRQ_VECTOR(0) */ 340 outb_pic(ISA_IRQ_VECTOR(0), PIC_MASTER_IMR); #oub(0x30,0x21) 341 342 /* 8259A-1 (the master) has a slave on IR2 */ 343 outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); #outb(0x4,0x21) 344 345 if (auto_eoi) /* master does Auto EOI */ 346 outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); 347 else /* master expects normal EOI */ 348 outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); #outb(0x01,0x21)PIC_MASTER_IMR :0x21 [ver4.9.16 arch/x86/include/asm/i8259.h:14]PIC_MASTER_CMD :0x20 [ver4.9.16 arch/x86/include/asm/i8259.h:13]ISA_IRQ_VECTOR :0x30 [ver4.9.16 arch/x86/include/asm/irq_vectors.h:55]PIC_CASCADE_IR :0x02 [ver4.9.16 arch/x86/include/asm/i8259.h:22]MASTER_ICW4_DEFAULT :0x01 [ver4.9.16 arch/x86/include/asm/i8259.h:23]PIC_ICW4_AEOI :2 [ver4.9.16 arch/x86/include/asm/i8259.h:25]
PIC:8259A (8)
・初期化 - PIC Slave[ver4.9.16 arch/x86/kernel/i8259.c:324] 324 static void init_8259A(int auto_eoi) 325 { 350 outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ #outb(0x11,0xa0) 352 /* ICW2: 8259A-2 IR0-7 mapped to ISA_IRQ_VECTOR(8) */ 353 outb_pic(ISA_IRQ_VECTOR(8), PIC_SLAVE_IMR); #outb(0x38,0xa1) 354 /* 8259A-2 is a slave on master's IR2 */ 355 outb_pic(PIC_CASCADE_IR, PIC_SLAVE_IMR); #outb(0x02,0xa1) 356 /* (slave's support for AEOI in flat mode is to be investigated) */ 357 outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); #outb(0x01,0xa1) 359 if (auto_eoi) 360 /* 361 * In AEOI mode we just have to mask the interrupt 362 * when acking. 363 */ 364 i8259A_chip.irq_mask_ack = disable_8259A_irq; 365 else 366 i8259A_chip.irq_mask_ack = mask_and_ack_8259A; 368 udelay(100); /* wait for 8259A to initialize */ 370 outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ 371 outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ 374 }PIC_SLAVE_IMR :0xa1 [ver4.9.16 arch/x86/include/asm/i8259.h:19]PIC_SLAVE_CMD :0xa0 [ver4.9.16 arch/x86/include/asm/i8259.h:18]SLAVE_ICW4_DEFAULT :0x01 [ver4.9.16 arch/x86/include/asm/i8259.h:24]cached_master_mask,cached_slave_mask は , デバイスアクセスせずにマスク情報を得る為のもの
PIC:8259A (9)
・信号検出エッジトリガ :立ち上がり ,立ち下りで信号検出レベルトリガ :H状態であるかどうかで信号検出
・ PIC における信号検出・ PIC は ,エッジトリガかレベルトリガで割り込み信号を検出する .・ ISA バスはエッジトリガのみサポート .・ PCI バスはエッジトリガ /レベルトリガの両方をサポート .・ ELCR(エッジ /レベルコントロールレジスタ ) EISA,PCI,その他後継システムでは ,ELCR が IRQ ラインを制御し , ISA バスがあるようなシステムに対して , 8259 のモードとは無関係に効果的に制御を行う . 正しく制御を行うために ,ELCR は BIOS によって起動時に設定される . I/Oポートは 0x4d0,0x4d1. レジスタは 8bit. 8259 から出ている IRQ とそれぞれのビットが一致 . あるビットをセットすると ,その IRQ はレベルトリガモードになり , リセットするとエッジトリガモードになる .
https://ja.wikipedia.org/wiki/Intel_8259
PIC:8259A (10)
・周辺デバイスが PIC に割り込み要求した時の動作
1. 周辺デバイスが IRn ピンを H → L にして ,PIC に割り込みを要求 .2.PIC は ,IRR の IRn に対応するビットを 1 にする .3.PIC は ,IMR を見て , デバイスから IRQ を受付けるかどうか判断 . ・受付可能な場合 , より優先度の高い IRQ が発生しているか確認 . 優先度が高い IRQ が発生中であれば ,その IRQ が終わるまで保留 . マスク . ・受付可能な場合かつより優先度の高い IRQ が発生していない場合 , その IRQ を受付ける .4.PIC は ,INT ピンを L → Hにして ,CPU に割り込みが入ったことを通知 .
PIC:8259A (11)
・ CPU が PIC から割り込みを受け付ける時の動作
CPU は ,PIC の INT ピンに接続されている INTR ピンに割り込みが入った事が分かると ,割り込みハンドラを実行する為に必要な割り込みベクタ番号を取得する .
1.CPU は ,eflags.if をチェックする . ・ if=1:INTA ピンにパルスを出力して , 割り込みを受付ける事を PIC に通知 . ・ if=0: 割り込みを無視する .2.PIC は ,1 回目の INTAパルスを受取ると , ISR の IRn に対応するビットを 1(受付中 ), IRR の IRn に対応するビットを 0( 割り込みなし ) にする .3.PIC は ,2 回目の INTAパルスを受取ると ,D0-D7データバスに 割り込みベクタ番号を出力する .
この処理が終わった時点で ,CPU はデータバス (システムバス ) から割り込みベクタ番号を取得可能になる .
PIC:8259A (12)
・ポート 0x20の仕様 (PIC マスタのコマンドレジスタ , ICW1)
Linux の場合0x11: 00010001
bit0 - ICW4 までつかうbit1 - カスケードモードbit3 - エッジトリガbit4 - 初期化
アクセス 機能 bit 意味
書き込み ICW1
7 未使用
6 未使用
5 未使用
4 初期化
3 0:エッジトリガ ,1:レベルトリガ
2 未使用
1 0: カスケードモード ,1:シングルモード
0 ICW4 まで使う
PIC:8259A (13)
・ポート 0x20の仕様 (PIC マスタのコマンドレジスタ , EOI 発行 モード設定 bit)
アクセス 機能 bit7 6 5
意味
書き込み Operation Command 2
0 0 0 rotate in auto-EOI mode(clear)
0 0 1 nonspecific EOI
0 1 0 no operation
0 1 1 specific EOI
1 0 0 rotate in auto-EOI mode
1 0 1 rotate on unspecific EOI
1 1 0 set priority command
1 1 1 rotate on specific EOI
bit4 3
Command Type
0 0 Operation Command 2 を表す
PIC:8259A (14)
・ポート 0x20の仕様 (PIC マスタのコマンドレジスタ , EOI 発行 [set priority command]/[rotate on specific EOI] の場合 )
アクセス 機能 bit2 1 0
意味最低 最高
書き込み Operation Command 2
0 0 0 IRQ0 IRQ1
0 0 1 IRQ1 IRQ2
0 1 0 IRQ2 IRQ3
0 1 1 IRQ3 IRQ4
1 0 0 IRQ4 IRQ5
1 0 1 IRQ5 IRQ6
1 1 0 IRQ6 IRQ7
1 1 1 IRQ7 IRQ0
PIC:8259A (15)
・ポート 0x20の仕様 (PIC マスタのコマンドレジスタ , EOI 発行 [specific EOI] の場合のサービスリセット )
Linux の場合0x6[X] :01100[X]
bit7-5 : specific EOIbit2-0 :リセット IRQ
アクセス 機能 bit2 1 0
意味
書き込み Operation Command 2
0 0 0 IRQ0をリセットする
0 0 1 IRQ1 をリセットする
0 1 0 IRQ2 をリセットする
0 1 1 IRQ3 をリセットする
1 0 0 IRQ4 をリセットする
1 0 1 IRQ5 をリセットする
1 1 0 IRQ6 をリセットする
1 1 1 IRQ7をリセットする
PIC:8259A (16)
・ポート 0x20の仕様 (PIC マスタのコマンドレジスタ , その他コマンド )
アクセス 機能 bit7 意味
書き込み Operation Command 3
0 0で固定
bit6 5
スペシャルマスクモード
0 x 何もしない
1 0 スペシャルマスクモードを解除
1 1 スペシャルマスクモードに設定
bit4 3
Command Type
0 1 Operation Command 3
bit2
0 0: no poll command
bit1 0
0 x 何もしない
1 0 割り込みリクエストレジスタ IRR を読む
1 1 サービスレジスタ ISR を読む
PIC:8259A (17)
・ポート 0x20の仕様
(PIC マスタのステータス・レジスタ )
アクセス bit IRQ の状態 (1:有効 ,0:無効 )OP3 の bit1-0 [1 0] = IRR/[1 1]=ISR
読み込み
7 IRQ7
6 IRQ6
5 IRQ5
4 IRQ4
3 IRQ3
2 IRQ2
1 IRQ1
0 IRQ0
PIC:8259A (18)
・ポート 0x21 の仕様
(PIC マスタの IMR)
アクセス bit IRQ のマスク状態 (1: マスクあり ,0: マスクなし )
読み込み
7 IRQ7
6 IRQ6
5 IRQ5
4 IRQ4
3 IRQ3
2 IRQ2
1 IRQ1
0 IRQ0
PIC:8259A (19)
・ポート 0x21 の仕様
(PIC マスタのコマンドレジスタ , ICW2)
Linux の場合master :ベクタ番号ベース値 0x30 - 00110000
ベクタ番号範囲 0x30~0x37 (48~55)slave :ベクタ番号ベース値 0x38 - 00111000
ベクタ番号範囲 0x38~0x3F (56~63)
アクセス 機能 bit7 6 5 4 3
ベクタ番号
書き込み ICW2
0 0 0 0 0 0x00 ~ 0x07
0 0 0 0 1 0x08 ~ 0x0F
0 0 0 1 0 0x10 ~ 0x17
… …
0 0 1 1 0 0x30 ~ 0x37 (48~55)
0 0 1 1 1 0x38 ~ 0x3F (56~63)
… …
1 1 1 1 1 0xF8 ~ 0xFF
bit2 1 0
0 0 0 未使用
PIC:8259A (20)
・ポート 0x21 の仕様
(PIC マスタのコマンドレジスタ , ICW3)
Linux の場合master :0x04 - 00000100 - IRQ2 からのスレーブ接続slave :0x02 - 00000010 - スレーブ ID = 2
アクセス 機能 bit IRQ からのスレーブ接続 (1: する ,0: しない )
書き込み ICW3
7 IRQ7
6 IRQ6
5 IRQ5
4 IRQ4
3 IRQ3
2 IRQ2(0xA1 の場合 , スレーブ IDbit2)
1 IRQ1(0xA1 の場合 , スレーブ IDbit1)
0 IRQ0(0xA1 の場合 , スレーブ IDbit0)
PIC:8259A (21)
・ポート 0x21 の仕様
(PIC マスタのコマンドレジスタ , ICW4)
Linux の場合0x01 - 00000001 : バッファなし ,EOI, x86モード
アクセス 機能 bit 意味
書き込み ICW4
7 未使用
6 未使用
5 未使用
4 Not specified fully nested mode
bit3 2
バッファモード
0 x バッファなし
1 0 バッファあり
bit 意味
1 0:EOI,1: 自動 EOI
0 x86 モード