OS起動編⑥ picinit() (Xv6を読む~OSコードリーディング~)
前回
jupiteroak.hatenablog.com
トップページ
jupiteroak.hatenablog.com
main.c(一部抜粋)
https://github.com/mit-pdos/xv6-public/blob/master/main.c#L25
int main(void) { ... picinit(); // disable pic ...
picirq.c
https://github.com/mit-pdos/xv6-public/blob/master/picirq.c#L10
void picinit(void) { // mask all interrupts outb(IO_PIC1+1, 0xFF); outb(IO_PIC2+1, 0xFF); }
picinit関数では、8259pic(レガシー割り込みコントローラ)を無効化しています。local APICやI/OAPICを利用する場合、8259picを無効化しなければなりません(https://wiki.osdev.org/8259_PIC#Disabling)。
処理の内容
outb(IO_PIC1+1, 0xFF);
out命令(ポート出力命令)でI/OポートアドレスIO_PIC1+1→0x21を指定することにより、マスタPICが持つOCW1レジスタへの書き込みを行なっています。
OCW1レジスタ(8bit)は、picが持つ各IRQピンへの割り込みの有効化・無効化を設定するレジスタです。OCW1レジスタ(8bit)の各bitが、picが持つ各IRQピンに対応していて、割り込みの有効化・無効化を設定できるようになっています(マスタpicでは、OCW1のbit0はIRQ0ピン、、、bit7はIRQ7ピンと対応しています)。
OCW1レジスタへ0xFFを書き込むことで(OCW1の全てのbitを1にセットすることで)、IRQ0〜IRQ7ピンへの割り込みをマスク(無効化)することができます。
(OCW1レジスタで設定した値はpicの内部レジスタであるIMR(Interrupt Mask Register)に設定されるので、実際にはIMRが割り込みマスクの設定(割り込みの有効化・無効化)を制御しています。)
outb(IO_PIC2+1, 0xFF);
out命令(ポート出力命令)でI/OポートアドレスIO_PIC2+1→0xA1を指定することにより、スレーブPICが持つOCW1レジスタへの書き込みを行なっています。
OCW1レジスタ(8bit)は、picが持つ各IRQピンへの割り込みの有効化・無効化を設定するレジスタです。OCW1レジスタ(8bit)の各bitが、picが持つ各IRQピンに対応していて、割り込みの有効化・無効化を設定できるようになっています(スレーブpicでは、OCW1のbit0はIRQ8、、、bit7はIRQ15と対応している)。
OCW1レジスタへ0xFFを書き込むことで(OCW1の全てのbitを1にセットすることで)、IRQ8〜IRQ15ピンへの割り込みをマスク(無効化)することができます。
(OCW1レジスタで設定した値はpicの内部レジスタであるIMR(Interrupt Mask Register)に設定されるので、実際にはIMRが割り込みマスクの設定(割り込みの有効化・無効化)を制御しています。)