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

2024-09-03 15:32

本文主要是介绍追踪uboot下tftp命令的代码执行过程-Nagul,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、网卡驱动的添加 

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void start_armboot (void){}  
里面有网络初始化函数
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. eth_initialize(gd->bd);  
进入函数你会发现一系列的网卡初始化函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #if defined(CONFIG_MCFFEC)  
  2.     mcffec_initialize(bis);  
  3. #endif  
  4. #if defined(CONFIG_FSLDMAFEC)  
  5.     mcdmafec_initialize(bis);  
  6. #endif  
  7. #if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \  
  8.     defined(CONFIG_AT91SAM9263)  
  9.     at91sam9_eth_initialize(bis);  
  10. #endif  
  11.   
  12. #if defined(CONFIG_DRIVER_CS8900)  
  13.     cs8900_initialize(bis);  
  14. #endif  
  15.   
  16. #if defined(CONFIG_DRIVER_SMC911X)  
  17.     smc911x_initialize(bis);  
  18. #endif  

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #if defined(CONFIG_DRIVER_SMC911X)  
  2.  smc911x_initialize(bis);  
  3. #endif  

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

继续跟进

smc911x_initialize(bis)每种网卡里面都会有这么一个函数,想配置不同的网卡时,在这个函数中进行注册就行了(其实不是注册,只是把设备放到了一个链表中,便于管理)
smc911x_initialize(bis)函数中关键在于这里
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. dev = (struct eth_device *) malloc (sizeof *dev);  
  2. memcpy(dev->enetaddr, bis->bi_enetaddr, 6);  
  3. sprintf(dev->name, DRIVERNAME); //设备名  
  4. dev->priv = (void *)NULL; /* this have to come before bus_to_phys() */  
  5. dev->iobase = CONFIG_DRIVER_SMC911X_BASE;  
  6. dev->init = smc911x_eth_init;    //对应底层的初始化  
  7. dev->halt = smc911x_eth_halt;  
  8. dev->send = smc911x_eth_send;     //对应底层的发生函数  
  9. dev->recv = smc911x_eth_rx;    //对应底层的接收函数  
  10. eth_register (dev); //类似于内核中注册设备一样的方法,把设备添加到链表中  
eth_register ()函数中有这么一句话
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 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中有定义
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  
  2. {  
  3.  return netboot_common (TFTP, cmdtp, argc, argv);  
  4. }  
  5.   
  6. U_BOOT_CMD(  
  7.  tftpboot,  3,  1,  do_tftpb,  
  8.  "tftpboot- boot image via network using TFTP protocol\n",  
  9.  "[loadAddress] [[hostIPaddr:]bootfilename]\n"  
  10. );  
U_BOOT_CMD就是使第一个参数的命令tftpboot执行对应的函数do_tftpb()
do_tftpb() 中netboot_common()函数中 使用NetLoop(proto)来启动tftp
NetLoop(proto_t protocol)函数在/net/net.c中
下面有根据参数协议类型来执行相应的函数,从上面的代码可以看到传递进来的是TFTP,所以会执行TFTP段代码
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. switch (protocol) {  
  2.   case TFTP:  
  3.    /* always use ARP to get server ethernet address */  
  4.    TftpStart();  
  5.    break;  
  6. 。。。  
  7. }  
接下来就是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命令的执行过程了。

这篇关于追踪uboot下tftp命令的代码执行过程-Nagul的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133351

相关文章

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Oracle存储过程里操作BLOB的字节数据的办法

《Oracle存储过程里操作BLOB的字节数据的办法》该篇文章介绍了如何在Oracle存储过程中操作BLOB的字节数据,作者研究了如何获取BLOB的字节长度、如何使用DBMS_LOB包进行BLOB操作... 目录一、缘由二、办法2.1 基本操作2.2 DBMS_LOB包2.3 字节级操作与RAW数据类型2.

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

使用mvn deploy命令上传jar包的实现

《使用mvndeploy命令上传jar包的实现》本文介绍了使用mvndeploy:deploy-file命令将本地仓库中的JAR包重新发布到Maven私服,文中通过示例代码介绍的非常详细,对大家的学... 目录一、背景二、环境三、配置nexus上传账号四、执行deploy命令上传包1. 首先需要把本地仓中要

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us