一、网卡驱动的添加
网络在uboot中的启动是在uboot的第二阶段启动代码中 /lib_arm/board.c
<span style="font-family:Courier New;font-size:12px;">void start_armboot (void){}</span>
里面有网络初始化函数
<span style="font-family:Courier New;font-size:12px;">eth_initialize(gd->bd);</span>
进入函数你会发现一系列的网卡初始化函数
<span style="font-family:Courier New;font-size:12px;">#if defined(CONFIG_MCFFEC) mcffec_initialize(bis); #endif #if defined(CONFIG_FSLDMAFEC) mcdmafec_initialize(bis); #endif #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ defined(CONFIG_AT91SAM9263) at91sam9_eth_initialize(bis); #endif #if defined(CONFIG_DRIVER_CS8900) cs8900_initialize(bis); #endif #if defined(CONFIG_DRIVER_SMC911X) smc911x_initialize(bis); #endif</span>
我的是smc9220的网卡,所以找到
<span style="font-family:Courier New;font-size:12px;">#if defined(CONFIG_DRIVER_SMC911X) smc911x_initialize(bis); #endif</span>
继续跟进
<span style="font-family:Courier New;font-size:12px;"> dev = (struct eth_device *) malloc (sizeof *dev); memcpy(dev->enetaddr, bis->bi_enetaddr, 6); sprintf(dev->name, DRIVERNAME); //设备名 dev->priv = (void *)NULL; /* this have to come before bus_to_phys() */ dev->iobase = CONFIG_DRIVER_SMC911X_BASE; dev->init = smc911x_eth_init; //对应底层的初始化 dev->halt = smc911x_eth_halt; dev->send = smc911x_eth_send; //对应底层的发生函数 dev->recv = smc911x_eth_rx; //对应底层的接收函数 eth_register (dev); //类似于内核中注册设备一样的方法,把设备添加到链表中</span>
<span style="font-family:Courier New;font-size:12px;">eth_current = eth_devices = dev;</span>
<span style="font-family:Courier New;font-size:12px;">int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { return netboot_common (TFTP, cmdtp, argc, argv); } U_BOOT_CMD( tftpboot, 3, 1, do_tftpb, "tftpboot- boot image via network using TFTP protocol\n", "[loadAddress] [[hostIPaddr:]bootfilename]\n" );</span>
U_BOOT_CMD就是使第一个参数的命令tftpboot执行对应的函数do_tftpb()而do_tftpb() 中netboot_common()函数中 使用NetLoop(proto)来启动tftp
NetLoop(proto_t protocol)函数在/net/net.c中
下面有根据参数协议类型来执行相应的函数,从上面的代码可以看到传递进来的是TFTP,所以会执行TFTP段代码
<span style="font-family:Courier New;font-size:12px;">switch (protocol) { case TFTP: /* always use ARP to get server ethernet address */ TftpStart(); break; 。。。 }</span>
接下来就是TftpStart()的事情了