uboot-uboot ping分析


前言

@和原子哥一起学习Linux

开发环境:I.MX6Ull开发板
参考内容:正点原子的驱动开发教程,并完成uboot移植部分,使用自己移植的代码。
参考:https://blog.csdn.net/cupid99/article/details/54896971

一、ping命令的使用

在这里插入图片描述
从这里可以看出这应该是uboot命令中的一个:
在这里插入图片描述
命令原理如正点原子的驱动开发指南讲的一致,当我们在 uboot 的命令行中输入“ping”这个命令的时候,最终执行的是 do_ping 这个函数。 uboot 中使用 U_BOOT_CMD 来定义一个命令,最终的目的就是为了定义一个cmd_tbl_t 类型的变量,并初始化这个变量的各个成员。 uboot 中的每个命令都存储在.u_boot_list段中,每个命令都有一个名为 do_xxx(xxx 为具体的命令名)的函数,这个 do_xxx 函数就是具体的命令处理函数。

二、do_ping命令分析

1.准备阶段

string_to_ip
——》将收到的ip存在net_ping_ip中
net_loop(PING)
——》有三个全局变量先初始化
——》net_restarted = 0;
——》net_dev_exists = 0;
——》net_try_count = 1;
	net_init
	——》net_tx_packet、net_rx_packets指向net_pkt_buf
	——》初始化arp,net_clear_handlers
	net_init_loop
	——》判断设备是否存在,若存在则给net_ethaddr赋值-mac地址
	eth_halt
	——》调用网络设备的fec_halt(详见网络初始化分析)函数,停止FEC引擎
	——》把网卡状态设置为 passive
	eth_set_current
	——》根据环境变量名称获取网络设备
	eth_init
	——》调用网络设备的fec_init(详见网络初始化分析)函数,初始化网络
——》设置网络状态NETLOOP_CONTINUE
	net_init_loop——》在上面的net_init调用过
	net_check_prereq
	——》检查net_ping_ip.s_addr、net_ip.s_addr地址,net_ethaddr不能全0
	——》检查通过net_dev_exists = 1

2.发送阶段

ping_start
	——》调用 NetSetTimeout 设置超时时间和超时处理函数
	ping_timeout_handler——》关闭FEC引擎和设置net_state状态为NETLOOP_FAIL
	ping_send()
	net_set_ether(发送包net_tx_packet,空mac,ipv4报文类型)

此处应贴图:
在这里插入图片描述
——》组帧头ethernet_hdr,目的mac为空mac,源地址为自己的mac地址,还需要检查VLan,没有VLAN则加上报文类型,最后是存在发送包中

	set_icmp_header(发送包+14字节=pkt,目的ip)

此处再贴图:
在这里插入图片描述
——》组二层头
版本4,头部长度5(5*4),优先级和服务0,IP头长度为结构体sizeoff,标识net_ip_id++,片偏移0x4000,生存时间255,头部校验0,源ip为net_ip,目的ip为net_ping_ip;协议1(ICMP),ip长度为结构体sizeoff,重新生成校验。最后 8 个字节实际上不是 IP 层的协议,是ICMP协议的数据,U-Boot 中这样做肯能是为了处理数据方便,因为上层的 UDP 协议很简单,就定义到 IP 数据结构当中一起来了。

	——》设置重试次数,获取当前时间
	arp_request
		——》判断arp送网关还是直连
		arp_raw_request
			net_set_ether——》创建ARP的报文头
			net_send_packet
				eth_send
				——》调用网络设备的fec_send(详见网络初始化分析)函数,发送一帧

3.接收阶段

	for (;;) 
	——》等待回复
	——》复位了看门狗,怕咬死
	——》检查超时
	——》调用eth_rx
		——》调用网络设备的fec_recv(详见网络初始化分析)函数,读出一帧
			net_process_received_packet
			——》net_rx_packet收到的帧
			——》net_rx_packet_len收到的长度,要检查
			——》normal packet处理,跳过以太头
			——》switch (eth_proto) 根据的报文类型进行处理	

-----------------------ARP报文类型--------------------------------
PROT_ARP–arp_receive
——》首先做一些基本的检查
——》检查动作-本机已经发送了 ARP 请求,这里收到的是其他主机的返回信息
——》首先是从收到的 ARP 数据包当中读取出发出这个包的主机的 IP 地址,若它不是我们等待的主机的 IP,那么直接返回,不用进一步处理了
——》若是,那就继续发送 ICMP 请求。因为 ARP 请求的目的就是为了得到目标 IP 对应的 mac 地址,所以把目标地址的 mac 地址拷贝到 arp_wait_packet_ethaddr地址,以便后面使用。然后就是把这个 mac 地址填充到已经准备好的 ICMP 信息的相应字段
——》net_send_packet发出net_tx_packet
-----------------------ICMP报文类型--------------------------------
PROT_IP–
——》首先做一些基本的检查
ping_receive
——》switch (icmph->type)—ICMP_ECHO_REPLY
——》若发送这个包的主机的 IP 地址和net_ping_ip一样则把net_state设置为 NETLOOP_SUCCESS

----------------------for (; ; ) -------------------------------------

	——》Abort if ctrl-c was pressed
	——》当switch (net_state)为NETLOOP_SUCCESS时,网络驱动收尾,并返回net_boot_file_size传输的字节数

——》结合 do_ping()函数,我们就能看到返回大于 0 的时候为 ping 成功的消息。

总结

下面把 ping 的流程梳理一下,理解起来清晰一点:
1、准备 ICMP 数据包,但是这个时候还不知道目标 IP 的地址,因此不能直接发送 ICMP 数据。
2、准备 ARP 数据包,发送 ARP 数据包,然后等到目标机的返回。
3、处理目标机的返回信息,提取目标主机的 mac 地址,填充到第一步当中的 ICMP 数据包当
中去。
4、发送 ICMP 数据包到目标机。
5、等待 ICMP 数据包的返回。
6、完成流程。

最后感谢参考的博客的作者,让我更加深刻的理解了uboot的ping原理

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值