uboot中 fastboot udp 协议分析

news2025/1/11 2:58:06

注: 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中如何扩展指令

可以看到到,这是厂商自己添加的两个命令,要实现添加自定义指令,首先需要在最开始定义指令的结构体数组中,添加字节定义的指令名称,并填好这个指令的处理函数的入口地址

接着在下面按照厂商的实现形式,仿写一个命令处理函数即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2063613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VM——轮廓/快速匹配中的多模版匹配

1、轮廓或者快速匹配中支持建立多个模型,按照从上而下的顺序进行匹配,匹配上了即停止后续模版的匹配。 2、如果要多个模版都参与匹配,则需要打开“全部搜索模式”。 3、延拓阈值 “延拓阈值”,看参数名字不知所云,文档…

CR-NeRF 代码eval.py解析

这段代码是一个用于CR-NeRF(Neural Radiance Fields)模型的推理脚本。它主要用于生成和保存渲染的图像,并计算图像质量的评价指标(如PSNR和SSIM)。以下是对这段代码的详细解析: (1)…

【亚马逊云科技】有手就能做到的Amazon Lightsail快速建站

文章目录 前言一、为什么选择Amazon Lightsail二、创建账号与登录注册亚马逊账号登录控制台 三、创建Amazon Lightsail进入控制台创建实例实例配置查看实例查看网站定制页面 总结 前言 不论是个人名片还是官方网站都离不开网站建设工作。计算机技术经历漫长的发展,…

2024年如何将低质量视频变成高质量视频

创建低质量的视频对您没有好处,尤其是当您打算将这些视频上传到社交媒体帐户时。观众不喜欢观看模糊和低质量的视频,而这个东西没有意义,不会为你的内容增加价值。 那么,您应该如何确保您的社交媒体观众喜欢您的视频内容呢&#x…

企业内部知识库意义何在?怎么搭建?

引言 在知识经济时代,企业竞争力的核心日益转向知识的管理与应用能力。随着企业规模的扩大和业务复杂性的增加,如何高效地收集、整理、存储并分享内部知识,成为了企业持续发展和创新的关键。企业内部知识库应运而生,它不仅帮助企…

自定义注解+拦截器实现,对部分敏感字段的加解密

上一篇,我用的自定义注解AOP的方式,实现敏感字段的加解密,这一篇换个方案,这个方案相比一个方案,节省了一部分的性能开销 第一步:新建自定义注解 /*** 敏感信息类注解*/ Inherited Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface EnableSe…

tomcat session共享

1. 日志监控工具 安装 tar xf goaccess-1.4.tar.gz cd goaccess-1.4/ yum install GeoIP-devel-1.5.0-13.el7.x86_64.rpm yum install -y ncurses-devel.x86_64 ./configure --enable-utf8 --enable-geoiplegacy make make install2. 使用 goaccess /usr/local/nginx/logs/a…

java多线程(六)关键字Volatile可见性、有序性以及单个变量的原子性

volatile关键字 作用 volatile 是 Java 虚拟机提供的轻量级的同步机制,主要用来确保变量被线程安全地读取和写入。 当一个变量定义为 volatile 后,它具备以下特性: 可见性:确保不同线程对这个变量操作的可见性,即一…

自存实践本地访问 nginx放前端打包好的项目

nginx 部署前端项目_哔哩哔哩_bilibili 将打包好的dits文件放到 配置nginx.conf文件的location 启动命令 start nginx.exe 输入localhost即可访问打包好的项目 nginx的特点 1.静态资源 2.转发 设置代理转发请求 关闭nginx .\nginx.exe -s quit

Kubernetes-Pod调度基础

一.复制控制器(ReplicationController,RC) RC用来确保Pod副本数达到预期值,这样可以确保一个或多个同类Pod总是可用的。可以通过扩缩来增加或减少pod。 (1)示例: vim replicationcontroller-ng…

Codeforces Round 967 (Div. 2)

文章目录 A. Make All Equal题目描述思路代码 B. Generate Permutation题目描述思路代码 C. Guess The Tree题目描述思路代码 A. Make All Equal 题目描述 一个数组,最多实行n-1次,计算最少多少次可以变为同一个数 思路 计算重复次数最多的数&#x…

产业园区数字化转型:面对挑战,我们如何把握机遇加速前行?

在当今数字化的时代浪潮中,产业园区数字化转型已成为推动经济发展和提升竞争力的关键举措。然而,这一进程并非坦途,充满了各种挑战。 产业园区数字化转型面临着技术更新换代快的压力。新技术不断涌现,如物联网、人工智能、大数据…

Mybatis 速通秘籍 节省回顾知识点和学习成本

目录 一、MyBatis简介 1、MyBatis历史 2、MyBatis特性 3、MyBatis下载 4、和其它持久层技术对比 二、搭建MyBatis 1、开发环境 2、创建maven工程 a>打包方式 b>引入依赖 3、创建MyBatis的核心配置文件 4、创建mapper接口 5、创建MyBatis的映射文件 6、通过j…

python学习之路 - python的异常、模块与包

目录 一、python的异常、模块与包1、了解异常2、异常的捕获方法a、捕获基本异常b、捕获指定异常c、捕获多个异常d、捕获异常后的finally 3、异常的传递4、python模块a、定义b、基础语法c、使用方法d、补充 5、python包a、定义b、操作方法c、使用方法 6、安装第三方python包a、命…

MVC和三层架构

👉参考文章:mvc简介,mvc与三层架构的区别 一.MVC是什么? Model-View-Controller(MVC)是一种软件架构模式,是软件设计模式的体现 ,用于组织代码并分离关注点,广泛应用于…

GPS和桩号互转

文章目录 前言一、通过bigmap软件生成坐标信息csv二、Java实现1.CSV分隔2.计算2.1 读取gps_data.csv2.2 读取piles.csv2.3 进行线性插值2.4 返回值实体2.5 根据GPS坐标计算距离工具2.6 根据GPS坐标读取桩号2.7 根据桩号读取GPS坐标(根据距离计算,找到最近的桩号) 前…

短视频SDK解决方案,智能技术加持,提升创作效率

随着社交媒体、直播电商、在线教育等领域的蓬勃发展,短视频以其独特的魅力迅速崛起,成为内容创作与传播的新风口。为了助力企业和个人轻松拥抱视频化趋势,美摄科技匠心打造了一套高效、易用的短视频SDK解决方案,以“轻编辑&#x…

【高级IO-2】IO多路转接之Select(概念及代码实例)

文章目录 I/O 多路转接 之 Select1. 了解select2. select 函数原型① fd_set 结构② 详细理解参数(readfds为例) 3. 理解select的执行过程4. select代码实例:监视多个文件描述符5. Socket就绪条件6. select代码实例:多路复用服务器…

每日掌握一个科研插图·2D密度图|24-08-21

小罗碎碎念 在统计学和数据可视化领域,探索两个定量变量之间的关系是一种常见的需求。为了更深入地理解这种关系,我们可以使用多种图形表示方法,这些方法在本质上是对传统图形的扩展和变体。 散点图:这是最基本的图形&#xff0c…

什么是 JavaConfig?

什么是 JavaConfig? 💖The Begin💖点点关注,收藏不迷路💖 JavaConfig是Spring框架的一项创新,它允许开发者使用纯Java代码来配置Spring IoC容器,从而避免了繁琐的XML配置。这一特性带来了诸多优…