uboot中 fastboot udp 协议分析
注: 1. 本文所分析的fastboot源码不是android下的源码,而是恩智浦芯片厂商在IMX6UL芯片的uboot源码中自己实现的源码,二者不同,请读者注意区分。一些图片是网上找到的,出处不好注明,请见谅。
2. 分析fastboot udp 是为了后面设计自定义通信协议打基础,在自定义通信协议前,要考虑的设计细节有很多,借鉴现有的好的设计思路对后续设计是很有帮助的。
一、什么是fastboot
fastboot是android系统常用的一种刷机方法。android系统设计了2种刷机方式:fastboot和recovery。不论是二者中的哪一个,都是用来给设备刷写固件的。而刷机其实就是镜像传输+烧录,fastboot刷机时使用usb来传输镜像文件,然后写入对应分区
(可以拿过来用,需要芯片厂商在底层提供原始实现)
fastboot是一种通信协议。基本工作原理就是上位机(pc)通过 USB 或以太网(UDP)与引导加载程序(uboot)通信。它的设计兼容性很好,可以在各种设备上运行如 Linux、 Windows 的主机上使用。
(就是一种上位机利用USB或者网口和板子通信的机制)
fastboot是uboot中的一个命令。在uboot控制台中执行fastboot命令就可以让uboot进入fastboot模式。要实现fastboot刷机,只有开发板端uboot是不行的,还需要在主机有fastboot.exe配合。
(需要pc这边有一个控制软件配合使用)
二、fastboot原理
uboot的fastboot的命令会将开发板伪装成一个usb设备。因为开发板本身并不是一个usb设备,所以开发板直接插到电脑是没有反应的。伪装之后开发板就被主机windows识别成一个usb设备。
fastboot在开发板和主机间定义了一套协议(fastboot协议),这套协议以usb为底层传输物理层,协议规定了主机fastbooot软件和开发板fastboot软件之间的信息传输规则。在该规则下,消息传递可以实现的功能有:主机可以向开发板发送命令、开发板可以向主机发送回复、主机可以向开发板发送文件(download)
Fastboot实现方式
主机的fastboot软件和开发板的fastboot程序是怎样通信来工作的呢。平时工作时,开发板端只要执行了fastboot命令进入fastboot模式即可,开发板这一侧剩下的就不用管了。之后主机端通过运行fastboot命令,传递不同的参数来实现主机端和开发板端的通信。 譬如主机端执行fastboot devices,则这个命令通过usb线被传递到开发板中被开发板的fastboot程序接收,接收后去处理向主机端发送发送信息,主机端接收到反馈信息后显示出来。
Fastboot命令执行过程
三、fastboot udp 源码分析
fastboot代码的分析思路:
主机端:fastboot.exe的源代码是没有的,所以主机端不是分析的重点。
开发板端:主要分析点就是uboot如何进入fastboot模式,fastboot模式下如何响应主机发送的各种命令。
Uboot控制台输入fastboot命令之后会执行 do_fastboot函数
在do_fastboot函数中有两个分支,如果终端输入fastboot usb会使用usb进行更新,如果输入fastboot udp会使用网口来进行更新。
如果走udp会调用do_fastboot_udp()函数,来看一下
在do_fastboot_udp()函数中又调用了网络循环发送函数net_loop(),在这个函数中会匹配我们使用的网络协议,从而执行相应的函数。
可以看到这里调用了fastboot_start_server()函数,定位该函数,发现在neet/fastboot.c中,打开fastboot.c会发现,该文件是对fastboot udp方式的核心实现
在fastboot_start_server 函数中,首先会打印出使用的网络设备名称,以及正在监听的 IP 地址。
fastboot_our_port 被设置为预定义的常量 CONFIG_UDP_FUNCTION_FASTBOOT_PORT,这个端口用于接收控制台输入的 fastboot 命令。
如果配置了 CONFIG_IS_ENABLED(FASTBOOT_FLASH),那么会设置一个进度回调函数 fastboot_set_progress_callback(fastboot_timed_send_info)。会在 fastboot 操作过程中定时向主机发送信息。
接着设置 UDP 包的处理函数,使用 net_set_udp_handler(fastboot_handler) 设置了一个 UDP 数据包处理函数为fastboot_handler()。到时所有接收到的 UDP 数据包都会被 fastboot_handler 函数处理。
最后,清空服务器 MAC 地址。使用 memset 函数将 net_server_ethaddr 数组中的内容全部置零。这是为了在服务器 IP 地址发生变化时清除旧的 MAC 地址信息。
可以看到在fastboot_handler中,前半段都是一些必要的初始化和拆包处理,注意这里把数据包头部的信息复制到 header 结构体中就行。重点看switch中的执行逻辑,这里通过检查数据包的头部信息,然后会根据不同的请求类型采取相应的动作。如果是查询请求 (FASTBOOT_QUERY),则直接响应;如果是初始化 (FASTBOOT_INIT) 或者执行 (FASTBOOT_FASTBOOT) 请求,则根据序列号来确定是否需要发送响应或者重发数据包。如果接收到的数据包类型不被识别,则会反馈一个错误信息给对方。
这里面都调用了fastboot_send()函数,来看看这个函数
在fastboot_send()中首先进行了一些初始化准备工作,让packet指针偏移到填充数据的地方,以及判断是否要重传上一次数据包。接着为待发送的数据做准备工作,先将本地字节序转换为网络字节序,将response_header(回复包的头部信息)拷贝到待发送的packet指针所指向的空间中,指针继续向后偏移
接着会根据接收到的数据包的头部信息,去构造不同的响应数据包,如果是查询请求 (FASTBOOT_QUERY),则构造一个包含sequence_number的响应包;如果是初始化请求 (FASTBOOT_INIT) ,则构造一个包含udp_version和其长度信息的响应包;如果是出错请求(FASTBOOT_ERROR)则会构造一个包含错误信息的响应包;
如果是 (FASTBOOT_FASTBOOT) 请求,先判断当前命令是否是FASTBOOT_COMMAND_DOWNLOAD,是的话再看当前有没有剩余数据,没有数据的话调用fastboot_data_complete()函数,来处理数据下载完成的情况,包括发送响应、输出日志、设置环境变量以及重置状态等操作。如果还有数据的话会调用fastboot_data_download()函数,来接收主机传过来的数据。
如果当前没有待处理的命令,则复制命令到 command 并设置 pending_command 为真。
否则,调用 fastboot_handle_command 来处理命令,并更新 pending_command
如果接收到的数据包类型不被识别,则会打印出错误信息。
将响应字符串response拷贝到响应包pkcket中,最后调用uboot自带的一个底层udp包发送函数net_send_udp_packet()将构建好的响应包发送出去。
如果响应字符串的前四位是“OKAY“会匹配当前cmd去执行对应操作。如果响应字符串以 "OKAY" 或 "FAIL" 开头,则重置 cmd。
四、fastboot udp中的帧格式
其中id是一个枚举,
FASTBOOT_QUERY代表了是一个快速请求类型的数据包,(告诉我你当前待接收的包序号)
FASTBOOT_INIT 代表了是一个获得初始化信息类型的数据包,(告诉我你的udp版本,以及你一包数据是接多大)
FASTBOOT_FASTBOOT代表了是一个命令或者文件类型的数据包,
flags在发送端发出的包中为1,在接收端发出的包中为0
seq代表当前包的一个序号
包的结构大概是这样的
五、fastboot udp中的重传机制
接收端的udp包处理函数fastboot_handler()在接收到udp包后,会先对比包头中的seq序号,和我本地这边等待接收的包序号seq_num做一个对比,如果二者一致,说明是我想要的包,调用fastboot_send(,,,0),在send函数中做数据的一个处理,并构建相应的反馈包发送给发送端;如果seq=seq_num – 1,则认为发送端没有收到我的反馈包,会调用fastboot(,,,1),在send函数中重发上一次发送的反馈包。在fastboot接收端中从头到尾,不论是命令包还是数据包都有包序号,都是根据包序号是否匹配来唯一判断是否接收正确(虽然拿不到上位机侧的协议源码,但可以推测发送端也一定是这样,只看序列号对不对)。
六、fastboot udp 命令底层怎么执行
在这个函数中,会循环对比预先定义的命令结构体数组中是否有传进来的命令相同的,如果有则会调用对应结构体中的命令处理函数。
七、fastboot udp中如何扩展指令
可以看到到,这是厂商自己添加的两个命令,要实现添加自定义指令,首先需要在最开始定义指令的结构体数组中,添加字节定义的指令名称,并填好这个指令的处理函数的入口地址
接着在下面按照厂商的实现形式,仿写一个命令处理函数即可。
相关文章:

uboot中 fastboot udp 协议分析
注: 1. 本文所分析的fastboot源码不是android下的源码,而是恩智浦芯片厂商在IMX6UL芯片的uboot源码中自己实现的源码,二者不同,请读者注意区分。一些图片是网上找到的,出处不好注明,请见谅。 2. 分析fastbo…...

redis hash类型的命令
1.hset 格式: hset key field value [field value ...](value是字符串) 返回值:设置成功的键值对的个数 2.hget:获取键值对 格式:hget key field 3.hexists:判断hash中是否存在指定 格式:…...

【OpenCV】 中使用 Lucas-Kanade 光流进行对象跟踪和路径映射
文章目录 一、说明二、什么是Lucas-Kanade 方法三、Lucas-Kanade 原理四、代码实现4.1 第 1 步:用户在第一帧绘制一个矩形4.2 第 2 步:从图像中提取关键点4.3 第 3 步:跟踪每一帧的关键点 一、说明 本文针对基于光流法的目标追踪进行叙述&am…...

ES 支持乐观锁吗?如何实现的?
本篇主要介绍一下Elasticsearch的并发控制和乐观锁的实现原理,列举常见的电商场景,关系型数据库的并发控制、ES的并发控制实践。 并发场景 不论是关系型数据库的应用,还是使用Elasticsearch做搜索加速的场景,只要有数据更新&…...

前端宝典十一:前端工程化稳定性方案
一、工程化体系介绍 1、什么是前端工程化 前端工程化 前端 软件工程;前端工程化 将工程方法系统化地应用到前端开发中;前端工程化 系统、严谨、可量化的方法开发、运营和维护前端应用程序;前端工程化 基于业务诉求,梳理出最…...

yum 数据源的切换
本来准备安装一个ntp 服务器时间进行同步,但是使用yum install ntp -y 但是却失败了 原因是yum自带的镜像源不能用了,所以要想使用yum 多功能只能切换yum 对应的镜像源了 如果你的服务商是可以使用wget命令的: wget -O /etc/yum.repos.d/Ce…...

MySQL入门学习-命令行工具.mysqlbinlog
MySQL 命令行工具mysqlbinlog用于处理二进制日志文件。 一、关于mysqlbinlog工具的详细介绍: 1、命令行工具mysqlbinlog的特点和使用方法: - 特点: - 可以解析和查看二进制日志文件的内容。 - 支持多种输出格式,如文本、SQ…...

WARNING XXX is not overriding the create method in batch
WARNING XXX is not overriding the create method in batch api.modeldef create(self, vals):quvals[name]youqu self.env[crm.qu].sudo().search([(name, , qu),(shi_id,,vals[shi_id])])if len(youqu)>0:raise UserError(_("该区名已存在,无需再填加…...

使用预训练的 ONNX 格式的目标检测模型(基于 YOLOv8n-pose)姿态监测
具体步骤如下: 加载图像: 从指定路径读取一张图像(这里假设图像名为bus.jpg)。将图像从 BGR 颜色空间转换为 RGB 颜色空间。 图像预处理: 计算图像的高度、宽度,并确定其中的最大值作为新图像的边长。创建一…...

matlab实现模拟退火算法
模拟退火算法(Simulated Annealing, SA)是一种通用概率优化算法,用于在给定的大搜索空间内寻找问题的近似全局最优解。该算法灵感来源于物理学中固体物质的退火过程,其中温度逐渐降低,粒子逐渐趋于能量最低状态。 在M…...

【Prettier】代码格式化工具Prettier的使用和配置介绍
前言 前段时间,因为项目的prettier的配置和eslint格式检查有些冲突,在其prettier官网和百度了一些配置相关的资料,在此做一些总结,以备不时之需。 Prettier官网 Prettier Prettier 是一种前端代码格式化工具,支持ja…...

【计算机网络】网络基础
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…...

MFC在对话框中实现打印和打印预览
首先在这里感谢互联网的大哥们!同时我讨厌动不动就是要vip才能查看!所以我写的不需要vip就能看。只求点个赞。 直接上代码,新建6个文件CPrintFrame.cpp;CPrintFrame.h;CPrintPreviewView.cpp;CPrintPrevie…...

移动端页面出现闪屏
v-cloak 的作用和用法 用法: 这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。官方API {{msg}} HTML 绑定 Vue实例,在页面加载时…...

elasticsearch的高亮查询三种模式查询及可能存在的问题
目录 高亮查询使用介绍 高亮参数 三种分析器 可能存在的查询问题 fvh查询时出现StringIndexOutOfBoundsException越界 检索高亮不正确 参考文档 高亮查询使用介绍 Elasticsearch 的高亮(highlight)可以从搜索结果中的一个或多个字段中获取突出显…...

【精品实战项目】深度学习预测、深度强化学习优化、附源码数据手把手教学
目录 前言 一、预测算法数据与代码介绍(torch和mxnet都有) 1.1 数据介绍 1.2 代码介绍 1.3 优化介绍 二、深度强化学习算法优化 2.1 DDPG 介绍 DPG--deterministic policy gradient DQN--deep Q-network DDPG--deep deterministic policy gradient 三、其他算法 总结…...

JavaScript 手写仿深拷贝
实现对象参数的深拷贝并返回拷贝之后的新对象,因为参数对象和参数对象的每个数据项的数据类型范围仅在数组、普通对象({})、基本数据类型中且无需考虑循环引用问题,所以不需要做过多的数据类型判断,核心步骤有…...

spring低版本设置cookie的samesite属性
场景:比较古老的项目了,ssh架子,Chrome 51 开始,浏览器的 Cookie 新增加了一个SameSite属性,可用于防止 CSRF 攻击和用户追踪。因此需要给其字段赋值。 网上找了很多资源,由于jar版本比较低,没有…...

GPT4o编写步进电机控制代码
我给出的要求如下: 基于STM32F407 HAL库,写一个步进电机控制程序,需要控制8个步进电机,我会给出描述步进电机的结构体变量,基于这些变量需要你做出以下功能,电机脉冲通过定时器中断翻转脉冲引脚的电平实现…...

关于Spring Boot的自动配置
目录 1.EnableAutoConfiguration注解 2.SpringBootConfiguration注解 3.Import注解 4.spring.factories 5.总结 (1)EnableAutoConfiguration (2)AutoConfigurationImportSelector (3) SpringFactoriesLoade…...

## 已解决:`java.sql.SQLSyntaxErrorException: SQL语法错误` 异常的正确解决方法,亲测有效!!! ###
1. 问题描述 java.sql.SQLSyntaxErrorException 是 Java 程序在执行 SQL 查询时,因 SQL 语法错误而抛出的异常。通常情况下,错误信息会指示出错的 SQL 语句及错误原因,如拼写错误、关键字遗漏、字段名称错误等。 典型的错误信息如下&#x…...

备战秋招60天算法挑战,Day22
题目链接: https://leetcode.cn/problems/missing-number/ 视频题解: https://www.bilibili.com/video/BV1HS42197Hc/ LeetCode 268.丢失的数字 题目描述 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组…...

在Linux下搭建go环境
下载go go官网:All releases - The Go Programming Language 我们可以吧压缩包下载到Windows上再传到Linux上,也可以直接web下载: wget https://golang.google.cn/dl/go1.23.0.linux-amd64.tar.gz 解压 使用命令解压: tar -x…...

738.单调递增的数字
738.单调递增的数字 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时,我们称这个整数是单调递增的。 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9示例 2: 输入: n 1234 输…...

近年国际重大网络安全事件深度剖析:安全之路任重道远
引言 在当今数字化时代,网络安全已成为全球关注的焦点。随着信息技术的飞速发展,网络攻击的手段和规模也在不断升级,给个人、企业和国家带来了巨大的威胁。本文将盘点近年来国际上发生的重大网络安全事件,分析其影响和教训&#…...

Windows C++控制台菜单库开发与源码展示
Windows C控制台菜单库 声明:演示视频:一、前言二、具体框架三、源码展示console_screen_set.hframeconsole_screen_frame_base.hconsole_screen_frame_char.hconsole_screen_frame_wchar_t.hconsole_screen_frame.h menuconsole_screen_menu_base.hcons…...

ARM——驱动——Linux启动流程和Linux启动
一、flash存储器 lash存储器,全称为Flash EEPROM Memory,又名闪存,是一种长寿命的非易失性存储器。它能够在断电情况下保持所存储的数据信息,因此非常适合用于存储需要持久保存的数据。Flash存储器的数据删除不是以单个的字节为单…...

Docker和虚拟机的区别详细讲解
Docker 和虚拟机(VM)是现代 IT 基础设施中常见的技术,它们都用于在单一硬件上运行多个操作环境,但它们的工作原理、性能、资源利用和使用场景存在显著差异。以下是对 Docker 和虚拟机区别的详细讲解。 一、基础概念 1. Docker …...

leetcode_68. 文本左右对齐
68. 文本左右对齐 题目描述:给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词;也就是说,…...

python探索分形和混沌
简单产生复杂,混沌孕育秩序 0. 引言 a. 分形 fractal 【也叫碎形】 分形是一种具有自相似性和复杂结构的几何图形。在分形结构中,无论放大多少次,局部的结构特征都与整体结构相似。这种特性在自然界中广泛存在,比如树木枝干、山…...