デバイスドライバ


  • メモリとポートの概念

  • デバイスドライバ講座

  • ネットワークカードのデバイスドライバ

QEMUのエミュレートしているネットワークカードはNE2000というPCIカード。
(今はNE2000互換のネットワークカードが多いらしい?)

これを操作するためには、NE2000のレジスタを操作する。
NE2000はPCIなので、CPUのI/Oポート(I/O空間)を利用してアクセスする。
(一部のCPUやPCIバスなどでは、メインメモリとは別に存在するメモリ空間としてI/O空間があり、このメモリ空間のことをI/Oポートと呼ぶ場合もある。by Wikipedia)
PCI

アクセスした後、どう操作するか(どのレジスタに何の値を書きこむか)は、データシートを見る。
NE2000

  • QEMUのPCI
デバイス番号:ベンダ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
 


NE2000の実装ブログ
http://d.hatena.ne.jp/Yamami/20040723


最終更新:2012年01月28日 12:14
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。