能进外国网站看视频的浏览器/网站推广优化排名公司
解决QEMU无法从非0x80000000处开始执行
- 1 背景介绍
- 2 问题描述
- 3 原因分析
- 4 解决办法
- 5 踩坑回忆
- 5.1 坑1 - 怀疑设备树有问题
- 5.2 坑2 - 怀疑QEMU中内存未写入成功
- 5.3 QEMU地址空间分析过程
1 背景介绍
在使用NEMU与QEMU做DiffTest的场景下,运行的固件为《RISC-V体系结构编程与实践》中示例代码chapter_2,编译出来的固件二进制文件为:benos_payload.bin
。
将benos_payload.bin,放置在NEMU中内存0x80000000处,NEMU通过Socket发送放置到QEMU中内存0x31e00000处。
计划让QEMU直接从0x31e00000开始执行,而不是常规的0x80000000。
对NEMU源码,做了如下修改。将nemu/src/cpu/difftest/dut.c文件,init_difftest函数,修改为如下:
void init_difftest(char *ref_so_file, long img_size, int port) {...ref_difftest_init(port);// 将benos_payload.bin发送到QEMU的0x31e00000内存处ref_difftest_memcpy(0x31e00000, guest_to_host(RESET_VECTOR), img_size, DIFFTEST_TO_REF);// pc寄存器设置为0x31e00000cpu.pc = 0x31e00000;// 将NEMU的x0 ~ x31和pc寄存器值,发送到QEMU中,覆盖QEMU原有寄存器ref_difftest_regcpy(&cpu, DIFFTEST_TO_REF);// 让QEMU执行3000条指令ref_difftest_exec(3000);
}
只要NEMU执行了上述代码,那么QEMU的0x31e00000处保存的就是benos_payload.bin,并且pc寄存器值为0x31e00000,当执行ref_difftest_exec函数时,预期QEMU就可以从0x31e00000开始执行。
2 问题描述
QEMU无法从0x31e00000开始执行,甚至一条指令都取不出来(qemu-7.1.0/target/riscv/translate.c中decode_opc函数第1052行,不会中断停下来)。
3 原因分析
我们调试QEMU源码,发现NEMU通过Socket发给QEMU的二进制镜像,并没有被写入QEMU的0x31e00000内存中,而是跳过了。
这点找一个正常向0x80000000写入成功的例子,来对照一下,就很容易定位。
因此,内存中没有该二进制可执行内容,故无法取指执行。
4 解决办法
在qemu-7.1.0/hw/riscv/spike.c文件,spike_board_init函数中,有如下调用:
/* register system main memory (actual RAM) */
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base, machine->ram);
注册系统主内存时,默认使用spike.c文件中spike_memmap数组,第SPIKE_DRAM个元素,该数组定义如下:
static const MemMapEntry spike_memmap[] = {[SPIKE_MROM] = { 0x1000, 0xf000 },[SPIKE_HTIF] = { 0x1000000, 0x1000 },[SPIKE_CLINT] = { 0x2000000, 0x10000 },[SPIKE_DRAM] = { 0x80000000, 0x0 },
};
因此,QEMU只认为0x80000000开始为DRAM,其他不认。
我们只需要,将0x80000000修改为0x30000000,再次尝试从0x31e00000运行,就成功了。
5 踩坑回忆
5.1 坑1 - 怀疑设备树有问题
当时第一反应,是以为设备树不对,因此修改了设备树中memory地址定义。事实证明没用。
后面看了QEMU的spike_board_init函数代码,其实QEMU会默认创建一个设备树,该设备树中memory地址,默认使用的是spike_memmap数组,因此我们只要改了spike_memmap数组,那设备树中memory地址也会改变。
以下,附一些设备树的常用命令。
从QEMU中导出设备树,启动QEMU时,添加如下选项:
-M virt,dumpdtb=123.dtb
将DTS编译为DTB:
dtc -I dts -O dtb -o 123.dtb 123.dts
将DTB转为DTS:
dtc -I dtb -O dts 123.dtb -o 123.dts
5.2 坑2 - 怀疑QEMU中内存未写入成功
真实原因就是这个。
其实在qemu-7.1.0/gdbstub.c中有一对函数:
- handle_write_mem函数
- handle_read_mem函数
NEMU发送数据给QEMU时,会调用handle_write_mem,如果在NEMU中再实现一个读内存的发包函数,那么就可以从QEMU中读取内存,在NEMU中将读到的数据与之前写入的数据,进行比较,很容易定位,两次数据不一致,内存写入有问题。
附,写内存数据包格式:
// 写入内存,数据包
"M0x31e00000,5dc:1711000013010100b7120000330151006f00001e1301..."
- M表示写入内存,m表示读取内存。
- 0x31e00000:表示写入内存的地址为0x31e00000。
- 0x5dc:表示后面跟的,数据长度为1500字节,实际数据包中因为是2个字符表示一个字节,因此后面实际字符串数据长度为1500*2。
- 1711000013010…:表示数据,"171100"解析后,就是0x17 0x11 0x00,低字节在前,高字节在后。
5.3 QEMU地址空间分析过程
以下内容很乱,请忽略,纯记录。
QEMU中有一个结构GDBState,包含了很多信息,就包含CPU的地址空间。
该结构中有个成员g_cpu,层次关系如下:
// 是否为DRAM地址
g_cpu->cpu_ases[0].as->current_map->dispatch->mru_section->mr->ram
// DRAM基址
g_cpu->cpu_ases[0].as->current_map->dispatch->mru_section->offset_within_address_space
// DRAM空间大小
g_cpu->cpu_ases[0].as->current_map->dispatch->mru_section->size
MemoryRegionSection表示一个地址范围,如[0x80000000, 0x88000000]。
其offset_within_address_space表示基址,size表示大小。
typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
// 展开后为:
typedef union CPUTailQ {struct CPUState* tqh_first; // first elementQTailQLink tqh_circ; // last element
} CPUTailQ;extern CPUTailQ cpus;
CPUState* cpu = first_cpu = (&cpus)->tqh_first
打的一些断点:
- b gdbstub.c:836,gdbstub.c中gdb_first_attached_cpu()
- b cpus-common.c:92
相关文章:

解决QEMU无法从非0x80000000处开始执行
解决QEMU无法从非0x80000000处开始执行 1 背景介绍2 问题描述3 原因分析4 解决办法5 踩坑回忆5.1 坑1 - 怀疑设备树有问题5.2 坑2 - 怀疑QEMU中内存未写入成功5.3 QEMU地址空间分析过程 1 背景介绍 在使用NEMU与QEMU做DiffTest的场景下,运行的固件为《RISC-V体系结…...

AI在候选人评估中的作用:精准筛选与HR决策的助力
一、引言 随着科技的迅猛发展,人工智能(AI)技术已逐渐渗透到各个行业和领域,人力资源管理(HRM)亦不例外。在候选人评估的环节中,AI技术以其高效、精准的特性,正在逐步改变着传统的招…...

自动化测试的艺术:Xcode中GUI测试的全面指南
自动化测试的艺术:Xcode中GUI测试的全面指南 在软件开发过程中,图形用户界面(GUI)测试是确保应用质量和用户体验的关键环节。Xcode,作为苹果的官方集成开发环境(IDE),提供了一套强大…...

uniapp封装请求拦截器,封装请求拦截和响应拦截的方法
首先我们先看一下uni官方给开发者提供的uni.request用来网络请求的api 1 2 3 4 5 6 7 8 9 uni.request({ url: , method: GET, data: {}, header: {}, success: res > {}, fail: () > {}, complete: () > {} }); 可以看到我们每次请求数据的时候都需…...

开局一个启动器:从零开始入坑ComfyUI
前几天刷某乎的时候看到了一位大佬写的好文,可图 IP-Adapter 模型已开源,更多玩法,更强生态! - 知乎 (zhihu.com) 久闻ComfyUI大名,决定试一下。这次打算不走寻常路,不下载现成的一键包了,而是…...

34_YOLOv5网络详解
1.1 简介 YOLOV5是YOLO(You Only Look Once)系列目标检测模型的一个重要版本,由 Ultralytics 公司的Glenn Jocher开发并维护。YOLO系列以其快速、准确的目标检测能力而闻名,尤其适合实时应用。YOLOV5在保持高效的同时,…...

深入解析Perl的正则表达式:功能、应用与技巧
在编程世界中,正则表达式是一种强大的文本处理工具,它能够用于搜索、替换、匹配字符串等操作。Perl语言以其强大的文本处理能力著称,而其正则表达式功能更是其核心特性之一。本文将深入探讨Perl中的正则表达式,包括其基本语法、应…...

【JAVA】Hutool CollUtil.sort 方法:多场景下的排序解决方案
在 Java 开发中,集合的排序是常见需求。Hutool 库的 CollUtil.sort 方法提供了一系列用于排序的实用功能,适用于不同的场景。以下是对几种常见场景及其实现方式的总结: <dependency><groupId>org.dromara.hutool</groupId>…...

Mysql-安装(Linux)
1、下载mysql 切换到/opt/app目录下,执行如下命令,下载mysql 5.7.38版本。 [rootywxtdb app]# wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.38-linux-glibc2.12-x86_64.tar.gz 解压安装包 [rootywxtdb app]# tar -zxvf mysql-5.7.38-l…...

如何查看日志
别用 cat cat 把整个日志文件刷屏 慎用 vim 日志不大随便整,因为vim会把整个日志文件读到内存,大日志文件(G级别)会造成内存占用过高,影响其他程序,在业务机器上查看日志这样尤其危险 less is more 还…...

python实现责任链模式
把多个处理方法串成一个list。下一个list的节点是上一个list的属性。 每个节点都有判断是否能处理当前数据的方法。能处理,则直接处理,不能处理则调用下一个节点(也就是当前节点的属性)来进行处理。 Python 实现责任链模式&#…...

Prometheus监控ZooKeeper
1. 简介 ZooKeeper是一个分布式协调服务,在分布式系统中扮演着重要角色。为了确保ZooKeeper集群的健康运行,有效的监控至关重要。本文将详细介绍如何使用Prometheus监控ZooKeeper,包括安装配置、关键指标、告警设置以及最佳实践。 2. 安装和配置 2.1 安装ZooKeeper Exporter…...

vuepress搭建个人文档
vuepress搭建个人文档 文章目录 vuepress搭建个人文档前言一、VuePress了解二、vuepress-reco主题个人博客搭建三、vuepress博客部署四、vuepress后续补充 总结 vuepress搭建个人文档 所属目录:项目研究创建时间:2024/7/23作者:星云<Xing…...

面试题 17.14.最小K个数
题目:如下图 答案:如下图 /*** Note: The returned array must be malloced, assume caller calls free().*/ void AdjustDown(int* a,int n,int root) {int parent root;int child parent * 2 1;//默认左孩子是大的,将其与右孩子比较&am…...

C++实现LRU缓存(新手入门详解)
LRU的概念 LRU(Least Recently Used,最近最少使用)是一种常用的缓存淘汰策略,主要目的是在缓存空间有限的情况下,优先淘汰那些最长时间没有被访问的数据项。LRU 策略的核心思想是: 缓存空间有限࿱…...

汇昌联信数字做拼多多运营实力好吗?
汇昌联信数字在拼多多运营方面的实力如何?汇昌联信数字作为一家专注于电子商务运营服务的公司,其在拼多多平台的运营能力是值得关注的。根据市场反馈和客户评价,汇昌联信数字在拼多多的运营实力表现良好,能够为客户提供专业的店铺管理、产品…...

【云原生】Prometheus 服务自动发现使用详解
目录 一、前言 二、Prometheus常规服务监控使用现状 2.1 Prometheus监控架构图 2.2 Prometheus服务自动发现的解决方案 三、Prometheus服务自动发现介绍 3.1 什么是Prometheus服务自动发现 3.2 Prometheus自动服务发现策略 3.3 Prometheus自动服务发现应用…...

(十九)原生js案例之h5地里位置信息与高德地图的初使用
h5 地里位置信息 1. 获取当前位置信息 window.onload function () {const oBtn document.querySelector("#btn");const oBox document.querySelector("#box");oBtn.onclick function () {window.navigator.geolocation.getCurrentPosition(function (…...

三、基础语法2(30小时精通C++和外挂实战)
三、基础语法2(30小时精通C和外挂实战) B-02内联函数B-04内联函数与宏B-05_constB-06引用B-07引用的本质B-08-汇编1-X86-X64汇编B-09-汇编2-内联汇编B-10-汇编3-MOV指令C-02-汇编5-其他常见指令C-05-汇编8-反汇编分析C-07-const引用、特点 B-02内联函数 …...

gitee设置ssh公钥密码频繁密码验证
gitee中可以创建私有项目,但是在clone或者push都需要输入密码, 比较繁琐。 公钥则可以解决该问题,将私钥放在本地,公钥放在gitee上,当对项目进行操作时带有的私钥会在gitee和公钥进行验证,避免了手动输入密…...

BGP选路之Next Hop
原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时,BGP协议会对这些BGP路由的属性进行比较,以确定出去往该目标网络的最优BGP路由,然后将该最优BGP路由与去往同一目标网络的其他协议路由进行比较,从而决定是否将该最优BGP路由放进P路由表中…...

牛客14666(优先屏障) + 牛客14847(Masha与老鼠)
文章目录 写在前面14666-优先屏障思路编程 14847-Masha与老鼠思路编程 写在前面 昨天刷的这两道题写了很久,特别是Masha与老鼠这道题,写了都快3个小时,主要还是理解代码逻辑有点难,不过写完之后感觉收获挺大的,给我以…...

Git下载与安装
下载网址:https://git-scm.com/downloads 下载之后开始安装 选择安装路径,next 选择需要安装的组件,这里默认即可,next 选择菜单文件夹,这里默认即可,next 选择默认编辑器,默认推荐的即可&…...

创建vue2/vue3项目
目录 创建一个Vue2项目创建一个Vue3项目 创建一个Vue2项目 ## 安装Vue-Cli : npm install -g vue/cli // Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)vue --version // 检测版本是否正确## 创建一个项目: vue create hello-world // hel…...

IOS七层模型对应的网络协议和物理设备
以下是网络模型、对应的协议以及对应的物理设备的表格总结: 网络模型层次主要功能对应协议对应物理设备物理层透明的传输比特流,确定机械及电气规范RS-232、V.35、RJ-45、FDDI等中继器、集线器、网线、调制解调器、网卡数据链路层将比特组装成帧和点到点…...

论文复现:Predictive Control of Networked Multiagent Systems via Cloud Computing
Predictive Control of Networked Multiagent Systems via Cloud Computing论文复现 文章目录 Predictive Control of Networked Multiagent Systems via Cloud Computing论文复现论文摘要系统参数初始化系统模型观测器预测过程控制器设计系统的整体框图仿真结果 论文摘要 翻译…...

JSON 文件存储
JSON 全称为: JavaScript Object Notation 也就是 javaScript 对象标记,通过对象和数组的组合来表示数据, 虽然构造简洁,但是结构化程度非常高, 是一种轻量级的数据交换格式 对象和数组 在 JavaScript 语言中&#…...

python——pynput
pynput 是一个 Python 库,用于控制和监听键盘与鼠标输入。它在 Windows、macOS 和 Linux 上都可以工作,为用户提供了一个跨平台的输入事件处理方式。pynput 包含两个主要模块:keyboard 和 mouse,分别用于处理键盘和鼠标事件。 主…...

[用AI日进斗金系列]用码上飞在企微接单开发一个项目管理系统!
今天是【日进斗金】系列的第二期文章。 先给不了解这个系列的朋友们介绍一下,在这个系列的文章中,我们将会在企微的工作台的“需求发布页面”中寻找有软件开发需求的用户 并通过自研的L4级自动化智能软件开发平台「码上飞CodeFlying」让AI生成应用以解…...

《JavaEE篇》--多线程(2)
《JavaEE篇》--多线程(1) 线程安全 线程不安全 我们先来观察一个线程不安全的案例: public class Demo {private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(() -> {//让count自增5W次…...