追踪uboot下tftp命令的代码执行过程
2015-06-26 13:48
274 查看
一、网卡驱动的添加
网络在uboot中的启动是在uboot的第二阶段启动代码中
/lib_arm/board.c
里面有网络初始化函数
进入函数你会发现一系列的网卡初始化函数
我的是smc9220的网卡,所以找到
那么需要添加这个网卡就需要定义前面的宏 CONFIG_DRIVER_SMC911X
这个宏在/configs/unsp210.h 中定义就行了(不同型号的网卡,在移植的时候定义不同的宏就ok了)
继续跟进
smc911x_initialize(bis)每种网卡里面都会有这么一个函数,想配置不同的网卡时,在这个函数中进行注册就行了(其实不是注册,只是把设备放到了一个链表中,便于管理)
smc911x_initialize(bis)函数中关键在于这里
eth_register ()函数中有这么一句话
到了这里,我们就可以使用eth_devices和eth_current通信了(具体底层的函数,可在u-boot\drivers\net\目录下看到相应的.c文件,这里不再跟进了)
跟到这里,大概知道网卡驱动是如何与上面关联起来的了,那么接下来就看看TFTP命令执行的过程
二、uboot下网络命令的实现过程
那么我们在UBOOT中用的最多的命令就是update 或者 tftp 通过网络下载内核和根文件系统了
这两个命令又是如何调用网络呢?
1、首先tftp命令在uboot下的实现过程
common/cmd_net.c中有定义
U_BOOT_CMD就是使第一个参数的命令tftpboot执行对应的函数do_tftpb()
而do_tftpb() 中netboot_common()函数中 使用NetLoop(proto)来启动tftp
NetLoop(proto_t protocol)函数在/net/net.c中
下面有根据参数协议类型来执行相应的函数,从上面的代码可以看到传递进来的是TFTP,所以会执行TFTP段代码
接下来就是TftpStart()的事情了
2、tftp命令执行后,最先运行的函数是/net/tftp.c中TftpStart()函数中关键就两个地方,一个收一个发
收
这两个函数就解决了收的问题了,TftpHandler函数在有数据的时候会自动的执行,毫无疑问TftpHandler里面就是接收处理函数了
最后一句TftpSend ();
发送数据是使用UDP的函数,一路跟下去你会发现最后使用的原始数据发送的(自己实现的UDP包头IP包头以太网包头)
如果想看明白这些个数据包是如何组成的,那么必须先看TCP/IP协议卷1吧
跟代码也这么累,先跟到这里了,不过基本上已经能够屡清楚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()的事情了
NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout); NetSetHandler (TftpHandler);
2、tftp命令执行后,最先运行的函数是/net/tftp.c中TftpStart()函数中关键就两个地方,一个收一个发
收
这两个函数就解决了收的问题了,TftpHandler函数在有数据的时候会自动的执行,毫无疑问TftpHandler里面就是接收处理函数了
最后一句TftpSend ();
发送数据是使用UDP的函数,一路跟下去你会发现最后使用的原始数据发送的(自己实现的UDP包头IP包头以太网包头)
NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);
如果想看明白这些个数据包是如何组成的,那么必须先看TCP/IP协议卷1吧
跟代码也这么累,先跟到这里了,不过基本上已经能够屡清楚TFTP命令的执行过程了。
相关文章推荐
- Java 截取反斜杠--java使用split拆分特殊字符
- Spring boot通过JPA和Mybatis同时连接2个关系数据库的例子
- 程序猿们,快用Emoji表情写代码吧
- php md5_file()
- JavaBean getter/setter命名规范[特例]
- asp.net自定义获取Get和Post请求的参数
- qt 的正则表达式 的使用
- 【Java基础】Jar包结构结构分析和操作详解
- QT5 编译makefile 如何添加编译选项
- 进程、线程同步互斥学习 —— 互斥器
- QT信号与槽
- 程序猿们,快用Emoji表情写代码吧
- quartz 定时任务与spring集成
- eclipse新建时显示no applicable items。
- Java代理实现方式详解
- 第十六周oj刷题——Problem B: 处理成绩(c++类训练)
- spring 管理cxf的客户端接口
- Spring框架
- Php在Window下的安装
- Android studio构建类似Eclipse的文件目录结构