UNDI的驱动程序结构:
struct
pci_driver undipci_driver __pci_driver = {
.ids = undipci_nics,
.id_count = ( sizeof ( undipci_nics ) /
sizeof ( undipci_nics[0] ) ),
.probe = undipci_probe, //undi探测,获取创建设备的函数
.remove = undipci_remove, //
};
undipci_probe函数的主要功能及流程是
1.
通过undipci_find_rom函数来查找undi rom
2.
通过undinet_probe函数来记录pxe的入口,然后完成设备注册,并依次调用pxe的PXENV_START_UNDI,PXENV_UNDI_STARTUP,PXENV_UNDI_INITIALIZE,PXENV_UNDI_GET_INFORMATION,PXENV_UNDI_GET_IFACE_INFO来完成pxe的初始化,
3.
其中设备注册会注册如下结构体指针
/** 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,
};
如此一来,但此时还不能收发包,必须先调用open来打开设备,当调用open来打开设备的时候,undinet_open做了哪些操作呢?
1.
调用undinet_hook_isr函数来hook pci中断的irq,即网卡产生的irq,那么该IRQ号是多少,从哪里来呢,该IRQ号由前面的undinet_probe函数中调用PXENV_UNDI_GET_INFORMATION来获取,具体数值见s_PXENV_UNDI_GET_INFORMATION结构体中的IntNumber。
2.
调用enable_irq来使能irq
3.
调用send_eoi来发送一个eoi到网卡
4.
依次调用PXENV_UNDI_SET_STATION_ADDRESS,PXENV_UNDI_OPEN来进一步初始化UNDI
5.
此时网卡产生的中断都会调用undinet_hook_isr函数注册的irq handler了,该handler的实现在undiisr.S文件中,undiisr函数即是.
gpxe编译vmware对应的镜像调试版本命令
make DEBUG=pcnet32 bin/pcnet32.dsk
gpxe通过显示调试
http://etherboot.org/wiki/debug
还可以通过gdb调试