UNDI的驅(qū)動(dòng)程序結(jié)構(gòu):
struct
pci_driver undipci_driver __pci_driver = {
.ids = undipci_nics,
.id_count = ( sizeof ( undipci_nics ) /
sizeof ( undipci_nics[0] ) ),
.probe = undipci_probe, //undi探測,獲取創(chuàng)建設(shè)備的函數(shù)
.remove = undipci_remove, //
};
undipci_probe函數(shù)的主要功能及流程是
1.
通過undipci_find_rom函數(shù)來查找undi rom
2.
通過undinet_probe函數(shù)來記錄pxe的入口,然后完成設(shè)備注冊,并依次調(diào)用pxe的PXENV_START_UNDI,PXENV_UNDI_STARTUP,PXENV_UNDI_INITIALIZE,PXENV_UNDI_GET_INFORMATION,PXENV_UNDI_GET_IFACE_INFO來完成pxe的初始化,
3.
其中設(shè)備注冊會注冊如下結(jié)構(gòu)體指針
/** UNDI network device operations */
static struct net_device_operations
undinet_operations = {
.open = undinet_open,
.close = undinet_close,
.transmit =
undinet_transmit,
.poll =
undinet_poll,
.irq =
undinet_irq,
};
如此一來,但此時(shí)還不能收發(fā)包,必須先調(diào)用open來打開設(shè)備,當(dāng)調(diào)用open來打開設(shè)備的時(shí)候,undinet_open做了哪些操作呢?
1.
調(diào)用undinet_hook_isr函數(shù)來hook pci中斷的irq,即網(wǎng)卡產(chǎn)生的irq,那么該IRQ號是多少,從哪里來呢,該IRQ號由前面的undinet_probe函數(shù)中調(diào)用PXENV_UNDI_GET_INFORMATION來獲取,具體數(shù)值見s_PXENV_UNDI_GET_INFORMATION結(jié)構(gòu)體中的IntNumber。
2.
調(diào)用enable_irq來使能irq
3.
調(diào)用send_eoi來發(fā)送一個(gè)eoi到網(wǎng)卡
4.
依次調(diào)用PXENV_UNDI_SET_STATION_ADDRESS,PXENV_UNDI_OPEN來進(jìn)一步初始化UNDI
5.
此時(shí)網(wǎng)卡產(chǎn)生的中斷都會調(diào)用undinet_hook_isr函數(shù)注冊的irq handler了,該handler的實(shí)現(xiàn)在undiisr.S文件中,undiisr函數(shù)即是.
gpxe編譯vmware對應(yīng)的鏡像調(diào)試版本命令
make DEBUG=pcnet32 bin/pcnet32.dsk
gpxe通過顯示調(diào)試
http://etherboot.org/wiki/debug
還可以通過gdb調(diào)試