QEMUのエミュレートしているネットワークカードは
NE2000という
PCIカード。
(今はNE2000互換のネットワークカードが多いらしい?)
これを操作するためには、NE2000のレジスタを操作する。
NE2000はPCIなので、CPUのI/Oポート(I/O空間)を利用してアクセスする。
(一部のCPUやPCIバスなどでは、メインメモリとは別に存在するメモリ空間としてI/O空間があり、このメモリ空間のことをI/Oポートと呼ぶ場合もある。by Wikipedia)
→
PCI
アクセスした後、どう操作するか(どのレジスタに何の値を書きこむか)は、データシートを見る。
→
NE2000
デバイス番号:ベンダID:デバイスID
0:8086
1:8086
2:1234
3:10ec:8029 (REALTEK 8029)
REALTEK8029がNE2000互換のLANカード。
これを使う。
int io_pci32( int devicenum, int func, int bus, int regaddr )
{
int outport, outdata;
int inport, indata;
//PCIのI/Oポートを指定:CONFIG_ADDRESSレジスタ(0x0cf8、32bit、Read/Write可)
outport = PCI_CONFIG_ADDRESS_ADDRS;
//*** レジスタ:ビット位置 31,30,...,1,0 ***
//bit0-1:0に固定
//bit24-30:リザーブで、0に固定
//bit31:イネーブルビットで、1に固定
outdata = 0x80000000;
//bit2-7:レジスタアドレス
outdata |= (regaddr << 2);
//bit8-10:機能番号
outdata |= (func << 8);
//bit11-15:デバイス番号
outdata |= (devicenum << 11);
//bit16-23:バス番号
outdata |= (bus << 16);
io_out32(outport, outdata);
//PCIのI/Oポートを指定:CONFIG_DATAレジスタ(0x0cfc~0x0cff、任意のサイズ、Read/Write可)
inport = PCI_CONFIG_DATA_ADDRS;
indata = io_in32(inport);
//イネーブルビットのクリア
io_out32(outport, 0);
return indata;
}
_io_in32: ; int io_in32(int port);
MOV EDX,[ESP+4] ; port
IN EAX,DX
RET
_io_out32: ; void io_out32(int port, int data);
MOV EDX,[ESP+4] ; port
MOV EAX,[ESP+8] ; data
OUT DX,EAX
RET
最終更新:2012年01月28日 12:14