追踪uboot下tftp命令的代码执行过程

本文详细介绍了U-Boot环境下网卡驱动的添加过程及TFTP命令的具体实现流程。从定义宏开始,逐步展示了如何将特定网卡(如smc9220)的驱动集成到U-Boot中,并深入分析了TFTP命令的内部工作原理,包括网络数据包的构造和传输机制。

一、网卡驱动的添加 

网络在uboot中的启动是在uboot的第二阶段启动代码中 /lib_arm/board.c

void start_armboot (void){}
里面有网络初始化函数
eth_initialize(gd->bd);
进入函数你会发现一系列的网卡初始化函数

#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

我的是smc9220的网卡,所以找到

#if defined(CONFIG_DRIVER_SMC911X)
 smc911x_initialize(bis);
#endif

那么需要添加这个网卡就需要定义前面的宏 CONFIG_DRIVER_SMC911X 
这个宏在/configs/unsp210.h 中定义就行了(不同型号的网卡,在移植的时候定义不同的宏就ok了)

继续跟进

smc911x_initialize(bis)每种网卡里面都会有这么一个函数,想配置不同的网卡时,在这个函数中进行注册就行了(其实不是注册,只是把设备放到了一个链表中,便于管理)
smc911x_initialize(bis)函数中关键在于这里
 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); //类似于内核中注册设备一样的方法,把设备添加到链表中
eth_register ()函数中有这么一句话
eth_current = eth_devices = dev;
到了这里,我们就可以使用eth_devices和eth_current通信了(具体底层的函数,可在u-boot\drivers\net\目录下看到相应的.c文件,这里不再跟进了)
跟到这里,大概知道网卡驱动是如何与上面关联起来的了,那么接下来就看看TFTP命令执行的过程

二、uboot下网络命令的实现过程
那么我们在UBOOT中用的最多的命令就是update 或者 tftp 通过网络下载内核和根文件系统了
这两个命令又是如何调用网络呢?
1、首先tftp命令在uboot下的实现过程    
   common/cmd_net.c中有定义
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"
);
U_BOOT_CMD就是使第一个参数的命令tftpboot执行对应的函数do_tftpb()
do_tftpb() 中netboot_common()函数中 使用NetLoop(proto)来启动tftp
NetLoop(proto_t protocol)函数在/net/net.c中
下面有根据参数协议类型来执行相应的函数,从上面的代码可以看到传递进来的是TFTP,所以会执行TFTP段代码
switch (protocol) {
  case TFTP:
   /* always use ARP to get server ethernet address */
   TftpStart();
   break;
。。。
}
接下来就是TftpStart()的事情了

2、tftp命令执行后,最先运行的函数是/net/tftp.c中TftpStart()函数中关键就两个地方,一个收一个发
NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
NetSetHandler (TftpHandler);
这两个函数就解决了收的问题了,TftpHandler函数在有数据的时候会自动的执行,毫无疑问TftpHandler里面就是接收处理函数了
最后一句TftpSend ();
发送数据是使用UDP的函数,一路跟下去你会发现最后使用的原始数据发送的(自己实现的UDP包头IP包头以太网包头)
NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);
如果想看明白这些个数据包是如何组成的,那么必须先看TCP/IP协议卷1吧

跟代码也这么累,先跟到这里了,不过基本上已经能够屡清楚TFTP命令的执行过程了。
在U-Boot环境下使用TFTP协议进行文件传输是嵌入式系统开发中常见的操作,特别是在加载Linux内核镜像或设备树文件时。以下是详细的配置与使用方法。 ### 配置TFTP服务器 在Linux主机上配置TFTP服务器是进行文件传输的前提。以下是基于Ubuntu系统的配置步骤: 1. 安装TFTP服务器相关软件包: ```bash sudo apt-get install tftp-hpa tftpd-hpa xinetd ``` 2. 创建TFTP工作目录并设置权限: ```bash mkdir /tftpboot chmod 777 /tftpboot ``` 3. 配置TFTP服务,编辑 `/etc/default/tftpd-hpa` 文件,确保内容如下: ``` TFTP_DIRECTORY="/tftpboot" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="--secure" ``` 4. 重启TFTP服务以应用配置: ```bash sudo systemctl restart tftpd-hpa ``` ### 配置U-Boot环境 在U-Boot中使用TFTP命令前,需要确保开发板与TFTP服务器在同一网络中,并正确设置IP地址: 1. 设置开发板的IP地址: ``` setenv ipaddr 192.168.1.100 ``` 2. 设置TFTP服务器的IP地址: ``` setenv serverip 192.168.1.1 ``` 3. 保存环境变量设置: ``` saveenv ``` ### 使用TFTP命令传输文件 在U-Boot命令行界面中,可以使用`ping`命令测试与TFTP服务器的连接,然后使用`tftp`命令下载文件到开发板的RAM中: 1. 测试网络连接: ``` ping 192.168.1.1 ``` 2. 下载文件到RAM: ``` tftp 0x80000000 Image ``` 此命令将从TFTP服务器下载名为`Image`的文件,并将其加载到内存地址`0x80000000`处[^2]。 ### 注意事项 - 确保TFTP服务器上的文件位于`/tftpboot`目录中,以便U-Boot可以通过TFTP协议访问这些文件。 - 检查并关闭Linux防火墙和SELinux,以避免阻止TFTP通信[^4]。 - 确保开发板与TFTP服务器之间的网络连接稳定。 - 在使用`tftp`命令时,确保指定的内存地址适合加载的文件大小,避免覆盖U-Boot或其他重要数据。 通过以上步骤,可以在U-Boot环境中成功配置并使用TFTP协议进行文件传输。这一过程对于嵌入式系统的开发和调试至关重要,因为它允许快速地更新和测试不同的内核镜像或设备树文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值