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)用pxePXENV_START_UNDIPXENV_UNDI_STARTUPPXENV_UNDI_INITIALIZEPXENV_UNDI_GET_INFORMATIONPXENV_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_ADDRESSPXENV_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)試