111.龙芯2k1000-pmon(11)- gzrom-dtb.bin 文件的组成

最近又要折腾2k1000的设备了,研究了一下gzrom文件组成部分。

pmon的编译可以参考之前的文档,这里我就不详述了

源码:GitHub - zhaozhi0810/pmon-ls2k1000-2022

gzrom-dtb.bin的生成命令在Makefile.inc(zloader.ls2k-hj20004目录)中

截取出来如下:

[ -f gzrom.bin ] && cp gzrom.bin gzrom-dtb.bin && python ../tools/pmonenv.py -f gzrom-dtb.bin -d ${TARGET}.dtb -w  al=\(usb0,0\)/boot/vmlinuz al1=\(wd0,0\)/vmlinuz append="'console=ttyS0,115200 noinitrd root=/dev/sda2  rootfstype=ext4 rootwait rw'" FR=1  

  1. [ -f gzrom.bin ] && cp gzrom.bin gzrom-dtb.bin 存在gzrom.bin这个文件,复制这个文件为gzrom-dtb.bin,相当于重命名了。

     2. python ../tools/pmonenv.py   用这个脚本来处理。(1.把dtb合并起来,2.加入一些环境变量)

     3. gzrom-dtb.bin = gzrom.bin + dtb + env

     4. pmonenv.py 注意这个命令之后的几个选项,这里有-f -d -w

     5. pmonenv.py 可以看到源码,在tools目录中

一、加入env变量

1.1  从main函数入口。

if __name__ == '__main__':
	opt,argv=getopt.getopt(sys.argv[1:],'b:o:s:f:wd:')
	opt=dict(opt)
	foff = int(opt['-o'],0) if '-o' in opt  else 0x000ff000  
	fsz = int(opt['-s'],0) if '-s' in opt else 500  
	fname = opt['-f'] if '-f' in opt else 'gzrom.bin' 
    
	d=readenv(fname,foff,fsz,argv)
	print(d) 
	if '-w' in opt:  
		writeenv(fname,foff,fsz,d)   
		if '-b' in opt: writehexenv(fname, opt['-b'])
		if '-d' in opt: writedtb(fname, opt['-d'], foff)

1.1.1 分析一下foff,fsz,fname

实际没有-o 选项,所以foff = 0x000ff000    (十进制1044480)

实际没有-o 选项 ,所以fsz = 500

有-f 选项 fname = gzrom-dtb.bin

可以使用打印语句打印出来看看

1.1.2 gzrom-dtb.bin的文件大小正好等于foff + fsz;

打开gzrom-dtb.bin,果然是这个位置开始放置环境变量

1.2  继续往下,看到writeenv

def writeenv(fname,foff,fsz,d):
	# print("\nwriteenv start*******************")
	# print("7 d = ",d)   # 8
	a=b'\x00\x00'   
	for i in d.keys():   
		a += i+b'='+d[i]+b'\x00' 
		# print("8 a = ",a)   # 9
	a=a.ljust(fsz,b'\x00')   
	b = struct.pack('!H',(-sum(struct.unpack('!'+str(len(a)//2)+'H',a)))&0xffff)
	# print("9 b = ",b)   # 10
	a=b+a[2:]
	# print("10 a = ",a)   # 11
	f=open(fname,'rb+')
	f.seek(foff,0)
	f.write(a)  
	f.close()

1.2.1 可以打开其中的注释,看到一些打印信息

打开 9,10,11 处的打印

('8 a = ', '\x00\x00FR=1\x00')

('8 a = ', '\x00\x00FR=1\x00al=(usb0,0)/boot/vmlinuz\x00')

('8 a = ', "\x00\x00FR=1\x00al=(usb0,0)/boot/vmlinuz\x00append='console=ttyS0,115200 noinitrd root=/dev/sda2  rootfstype=ext4 rootwait rw'\x00")

('8 a = ', "\x00\x00FR=1\x00al=(usb0,0)/boot/vmlinuz\x00append='console=ttyS0,115200 noinitrd root=/dev/sda2  rootfstype=ext4 rootwait rw'\x00al1=(wd0,0)/vmlinuz\x00")

('9 b = ', ')\x0e')    # 这个位置应该是0x290e 转为两个字节存放,0x29 正好对应一个右括号

('10 a = ', ")\x0eFR=1\x00al=(usb0,0)/boot/vmlinuz\x00append='console=ttyS0,115200 noinitrd root=/dev/sda2  rootfstype=ext4 rootwait rw'\x00al1=(wd0,0)/vmlinuz\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")

1.2.2 简要分析

通过加入打印信息,做出如下解析

1.2.2.1 struct.unpack('!'+str(len(a)//2)+'H',a)   //这个!指的是大端模式,H表示unsigned short类型

这里的意思是把两个字节按大端的形式,组合,得到一个250个数的数组,类型为unsigned short

(0, 18002, 15665, 97, 27709, 10357, 29538, 12332, 12329, 12130, 28527, 29743, 30317, 27753, 28277, 31232, 24944, 28773, 28260, 15655, 25455, 28275, 28524, 25917, 29812, 31059, 12332, 12593, 13618, 12336, 8302, 28521, 28265, 29810, 25632, 29295, 28532, 15663, 25701, 30255, 29540, 24882, 8224, 29295, 28532, 26227, 29817, 28773, 15717, 30836, 13344, 29295, 28532, 30561, 26996, 8306, 30503, 97, 27697, 15656, 30564, 12332, 12329, 12150, 28012, 26990, 30074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

注意18002  十六进制  0x4652  跟上面的截图(0xff002)能对上。其他就不看了

1.2.2.2 Sum   把他们加起来,按照unsigned short的类型,总共250个数  加起来等于1496818

1.2.2.3 - 把得到的校验和取负数,  等于-1496818

1.2.2.4 &0xffff 只取负数的最低16位    等于0x290e

 1.2.2.5 struct.pack('!H',…) 再用大端模式,打包unsigned short类型

0x290e,按大端解析为字节,data[0]=0x29,data[1]=0x0e   ,这个就是校验和!!!!写在最开始的两个字节,跟上面的截图(0xff000)能对上

1.2.2.6 尾部没有校验和,检验和在最开始的两个字节。校验的方法参考前面的描述

1.2.2.7 a=a.ljust(fsz,b'\x00') 对数据字节数进行补全,不足的位置补0.

二、加入dtb文件

2.1 明白env的加入之后,dtb 就比较简单了,

def writedtb(fname,dtb,foff):
	# print("\n writedtb start----------------------")
	f=open(dtb,'rb')
	a=f.read();
	# print("a.len= ",len(a))  # 12
	f.close()
	a=a.ljust(0x4000-8,'\x00')
	# print("a = ",a)
	b = struct.pack('I',(-sum(struct.unpack(''+str(len(a)//4)+'I',a)))&0xffffffff)
	a=b+a+b
	# print("a.len= ",len(a))  # 13
	# print("a = ",a)

	f=open(fname,'rb+')
	f.seek(foff-0x4000,0)
	f.write(a)
	f.close()

首先dtb能够保存的大小是0x4000-8个字节   (16K-8个字节),字节不足的地方填充0

文件偏移 0x000ff000 - 0x4000  = 0xfb000

前4个字节是校验和

 最末尾也是校验和(4个字节)

 

2.2 校验和的计算

经过上面的折腾,校验和计算比较简单了吧,小端的4个字节(unsigned int类型)组合,加起来,然后取负数,然后取低4个字节,即校验和了。

三、思考

最后,看到bin文件中env 和dtb 都是自己独立检验和,并且没有整体校验!!

3.1  env写的位置是ff000 后面的500字节,这个位置能否改动呢?

3.2  dtb写的位置是fb000 ,大小是0x4000(16k),这个位置能否改动呢?

3.3  能否只修改flash中的某个部分呢?这就提供了可行性。

(回答上面问题,就要看pmon怎么解析这几个部分了,看源码吧)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue+SpringBoot打造农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理:2.2.2 位置信息管理:2.2.3 配送人员分配:2.2.4 路线规划:2.2.5 个人中心:2.2.6 退换快递处理:…

冒泡、插入、希尔、选择、堆排序、快速排序(附源码)

目录 插入排序: 核心思想: 时间复杂度: 冒泡排序: 核心思想: 时间复杂度: 希尔排序: 核心思想: 时间复杂度: 选择排序: 核心思想: 时间…

YOLO目标检测——斑马线目标检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用:自动驾驶系统、智能交通监控、行人保护系统、辅助驾驶功能数据集说明:真实场景的高质量图片数据,数据场景丰富标签说明:使用lableimg标注软件标注,标注框质量高,含voc(xml)、coco(json)和yolo…

NVIDIA\CUDA\cudnn安装以及visual studio2022编译安装ceres2.2.0库

一、NVIDIA驱动安装 网址:官方驱动 | NVIDIA 因为本文之后需要visual studio2022进行编译,所以在安装NVIDIA\CUDA\cudnn之前你先得安装visual studio2022 点击NVIDIA控制面板,NVIDIA Control Panel 查看产品家族 根据产品家族选择驱动,点…

【QT 5 +Linux下软件qt软件打包+qt生成软件创建可以安装压缩包+学习他人文章+第三篇:学习打包】

【QT 5 Linux下软件qt软件打包qt生成软件创建可以安装压缩包学习他人文章第三篇:学习打包】 1、前言2、实验环境3、自我学习总结-本篇总结(1)了解安装包的目录结构(2)了解要编写文件与编写脚本1. control文件2. postin…

一封来自 DatenLord 关于GSoC 2024的挑战书

Google Summer of Code 是一项全球性的在线计划,致力于将新的contributor引入开源软件开发领域。GSoC 参与者在导师的指导下,与开源组织合作开展为期 12 周以上的编程项目。今年,达坦科技入选作为开源社区组织,携CNCF Sandbox项目…

比亚迪领航新能源时代:汉唐传承,品牌力量

比亚迪,以中国文化的深度与自信,为新能源汽车领域注入强大动力。汉唐车型,不仅承载着中国古代文明的辉煌,更以其创新技术和环保理念,终结油电之争,让燃油车再次破防。作为销量冠军,比亚迪品牌的…

中间件-Nginx加固(控制超时时间限制客户端下载速度并发连接数)

中间件-Nginx加固(控制超时时间&限制客户端下载速度&并发连接数) 1.1 Nginx 控制超时时间配置1.2 Nginx 限制客户端下载速度&并发连接数 💖The Begin💖点点关注,收藏不迷路💖 1.1 Nginx 控制超…

SD NAND:为车载显示器注入智能与安全的心脏

SD NAND 在车载显示器的应用 在车载显示器上,SD NAND(Secure Digital NAND)可以有多种应用,其中一些可能包括: 导航数据存储: SD NAND 可以用于存储地图数据、导航软件以及车载系统的相关信息。这有助于提…

自主研发!军事医学研究院团队提出 MIDAS,可用于单细胞多组学数据马赛克整合

众所周知,细胞是生命体的最小组成单位,人体内含有 40-60 万亿个细胞,构成了我们生长、发育的基础,在单细胞层面开展研究对于精确理解细胞的生长发育以及疾病的诊断与治疗至关重要。 近年来,单细胞测序技术异军突起&am…

请问如何用busctl命令列出会话总线?

在fedora39中启动ipmid时,如果不带输入参数,根据ipmid中的代码,此时注册的是系统总线,可以通过以下命令看到这条总线: $ busctl list | grep xyz xyz.openbmc_project.Ipmi.Host 199524 try2.out logic…

【菜鸟入门!】Matlab零基础快速入门教程

数学建模竞赛中,编程软件是必不可缺少的,比如大家都熟知的MATLAB多数同学们都会经常用到,今天给大家介绍一些MATLAB的基本元素,希望帮助大家更好的掌握编写基本的函数! 变量和数组 MATLAB 程序的基本数据单元是数组。一…

企业微信变更主体怎么改?

企业微信变更主体有什么作用?做过企业运营的小伙伴都知道,很多时候经常会遇到现有的企业需要注销,切换成新的企业进行经营的情况,但是原来企业申请的企业微信上面却积累了很多客户,肯定不能直接丢弃,所以这…

Linux 模拟实现shell【简单实现】

shell的模拟实现 我们知道shell是一个永不退出的程序,所以他应该是一个死循环,并且shell为了防止影响到自己,我们在命令行上输入的所有命令都是由shell的子进程来执行的,所以它应该要有创建子进程的相关函数,当然也会…

MySQL Strict Mode is not set for database connection ‘default‘

在使用 DJango 框架执行迁移文件的命令时,可以看到出现如下警告: (ll_env) D:\workspace\workspace-mengll\learning-log>python manage.py migrate System check identified some issues: WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set …

springboot232青年公寓服务平台

青年公寓服务平台的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,房屋信息因为其管理内容繁杂,管理数量繁…

android Service 与 activity 通信 并不断传数据

注:这只是个Demo 以下载为案例,实现开启下载,暂停下载,下载进度不断发送给activity class DownloadService : Service() {override fun onBind(intent: Intent?): IBinder? {return MyBinder()}inner class MyBinder : Binder…

IDEA中的Structure模块使用详解

IDEA中的Structure模块使用详解 类方法的展示 从左往右介绍: 1、最开头的 m 标识是表示为方法,如出现 f 标识则表示为属性; 2、m后面跟着的是方法或者属性的访问修饰符: #红色关闭的锁表示为private; #圆圈表示不带…

postman切换成黑色主题

postman安装以后默认是白色背景,如果想要切换成黑色的,大家可以按照下图箭头指示来操作。 1打开设置 2在Themes页面选择黑色主题

VR危险环境模拟介绍|VR虚拟现实设备

VR危险环境模拟是指利用虚拟现实技术来模拟和展现各种危险环境,以便训练人员应对紧急情况、提高安全意识和应急反应能力。这种模拟可以涉及到工业、医疗、紧急救援等多个领域,旨在帮助人们在真实环境中面对危险时能够做出正确的应对和决策。 VR危险环境…