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が割り込みマスクの設定(割り込みの有効化・無効化)を制御しています。)




次回
jupiteroak.hatenablog.com