QEMU源码全解析 —— PCI设备模拟(10)

接前一篇文章:

上一回讲到,在SeaBIOS的调用链dopost->maininit->platform_hardware_setup->qemu_platform_setup->pci_setup->pci_bios_map_devices过程中,最后这个函数负责完成PCI设备BAR的设置。

其中包括I/O、MEM以及PREFMEM三种BAR的设置,MEM和PREFMEM是一起的,这里以上述命令行为例,讨论SeaBIOS如何给PCI设备设置BAR基址。

pci_bios_map_devices首先调用pci_bios_init_root_regions_io和pci_bios_init_root_regions_mem函数做初始化的工作,以mem为例,调用的是src/fw/pcinit.c中的pci_bios_init_root_regions_mem函数。

该函数在QEMU源码根目录/roms/seabios/src/fw/pciinit.c中,代码如下:

static int pci_bios_init_root_regions_mem(struct pci_bus *bus)
{struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM];struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM];if (pci_region_align(r_start) < pci_region_align(r_end)) {// Swap regions to improve alignment.r_end = r_start;r_start = &bus->r[PCI_REGION_TYPE_PREFMEM];}u64 sum = pci_region_sum(r_end);u64 align = pci_region_align(r_end);r_end->base = ALIGN_DOWN((pcimem_end - sum), align);sum = pci_region_sum(r_start);align = pci_region_align(r_start);r_start->base = ALIGN_DOWN((r_end->base - sum), align);if ((r_start->base < pcimem_start) ||(r_start->base > pcimem_end))// Memory range requested is larger than available.return -1;return 0;
}

pci_region结构表示该虚拟机所有设备的某一类BAR(如PCI_REGION_TYPE_MEM表示mem BAR)。其定义也在roms/seabios/src/fw/pciinit.c中,如下:

struct pci_region {/* pci region assignments */u64 base;struct hlist_head list;
};

struct pci_region的base成员表示这类BAR的起始地址;list成员用来链接所有这类BAR的设备。

    PCI: map device bdf=00:03.0 bar 1, addr 0000c000, size 00000040 [io]PCI: map device bdf=00:01.1 bar 4, addr 0000c040, size 00000010 [io]PCI: map device bdf=00:04.0 bar 0, addr fea00000, size 00100000 [mem]PCI: map device bdf=00:03.0 bar 6, addr feb00000, size 00040000 [mem]PCI: map device bdf=00:03.0 bar 0, addr feb40000, size 00020000 [mem]PCI: map device bdf=00:02.0 bar 6, addr feb60000, size 00100000 [mem]PCI: map device bdf=00:02.0 bar 2, addr feb70000, size 00001000 [mem]PCI: map device bdf=00:02.0 bar 0, addr fd000000, size 01000000 [prefmem]

pci_region_align函数会返回最大的align值,每个设备的BAR地址的alignment就是其大小。这里首先比较align,大的尽量往前面放。在命令行启动的虚拟机中最大的是VGA的16MB ROM区域,所以会把PREFMEM放在更前面,也就是其地址比较低。pci_region_sum函数返回某一类BAR的所有空间和,将pcimem_end设置为0xfec00000。

这里r_end表示的就是mem BAR,此例中所有PCI设备的mem BAR的sum为0x171000,align为mem中最大的那一个值,此例中是0x00100000,所以r_end->base就是0xfec00000-0x171000之后与0x100000进行与运算的结果,该值为0xfea00000。

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

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

相关文章

Docker安装Odoo17

Docker安装Odoo 前言所需环境安装步骤登录Odoo 配置数据库 前言 Odoo是一个开源的ERP框架&#xff0c;它提供了一套完整的、可定制的、模块化的企业管理软件解决方案。以下是Odoo的主要特点&#xff1a; 模块化设计&#xff1a;Odoo的各个功能都以模块的形式提供&#xff0c;包…

linux主机的免密登录

实现linux主机之间的相互免密登录 在进行远程登录的时&#xff0c;服务器和主机间进行认证阶段分为&#xff1a; 基于口令认证&#xff08;不安全&#xff0c;易被抓包拦截获取&#xff09; 客户机连接服务器时&#xff0c;服务器将自己的公钥返回给客户机 客户机会将服务器的…

Vue中避免滥用this去读取data中数据

template模板中如何避免 提前处理v-for循环所用的数据&#xff0c;不要在v-for循环中去读取数组、对象类型的数据。在上述template模板中滥用this的例子中可以这样优化。 假设list、arr、obj皆是服务端返回来的数据&#xff0c;且arr和obj没有用到任何模块渲染中&#xff0c;…

机器视觉系统选型-参数—景深

镜头在垂直方向上&#xff0c;能清晰成像的空间距离(清晰成像范围)&#xff0c;称为景深

【java八股文】之分布式系列篇

1、什么是CAP BASE理论 1.1 CAP 一致性: 在分布式环境下&#xff0c;一致性是指数据在多个副本之间是否能够保持一致性的特性&#xff0c;等同于所有的节点访问同一份最新数据的副本。在一致性的需求下&#xff0c;当一个系统在数据一致的状态下执行更新操作后&#xff0c;应该…

CSAPP - 反编译 initialize_bomb()

CSAPP - 保持好奇&#xff0c;反汇编 initialize_bomb() 相比于直接看 bomblab phase_1 的答案&#xff0c;我更想搞懂答案之外涉及的每个函数的反汇编 - 反正是一个实验&#xff0c;代码能复杂到哪里去&#xff1f; 而搞懂这些函数&#xff0c; 无疑对于实际工程中的各种 deb…

nrm使用

为了更方便的切换下包的镜像源&#xff0c;我们可以安装 nrm 这个小工具&#xff0c;利用 nrm 提供的终端命令&#xff0c;可以快速查看和切换下 包的镜像源。 //通过 npm 包管理器&#xff0c;将 nrm 安装为全局可用的工具 npm i nrm -g//查看所有可用的镜像源 nrm ls//将下载…

【现代密码学】笔记 补充7-- CCA安全与认证加密《introduction to modern cryphtography》

【现代密码学】笔记7-- CCA安全与认证加密《introduction to modern cryphtography》 写在最前面7 CCA安全与认证加密 写在最前面 主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充&#xff1a;骆婷老师的PPT 《introduction to modern cryphtography》…

mysql数据库被黑恢复—应用层面delete删除---惜分飞

客户的mysql被人从应用层面攻击,并且删除了一些数据,导致业务无法正常使用,通过底层分析binlog确认类似恢复操作 确认这类的业务破坏是通过delete操作实现的,客户那边不太幸,客户找了多人进行恢复,现场严重破坏,老库被删除,并且还原了历史的备份文件(非故障第一现场),通过底层…

Error: error:0308010C:digital envelope routines::unsupported的解决方案

因为最近安装了pnpm对node版本有要求&#xff0c;升级了node版本是18以后&#xff0c;在运行之前的项目&#xff0c;就跑不起来了&#xff0c;报错如下&#xff1a; Error: error:0308010C:digital envelope routines::unsupported解决方案一&#xff1a; node版本切换到16版…

KEI5许可证没到期,编译却出现Error: C9555E: Failed to check out a license.问题解决

一、编译出现如下报错 二、检查一下许可证 三、许可证在许可日期内&#xff0c;故应该不是许可证的问题 四、检查一下编译器&#xff0c;我用的是这个&#xff0c;这几个编译器的区别其实我不太明白&#xff0c;但我把问题解决是选的这个 五、找到编译器的路径&#xff0c;去复…

Dockerfile的COPY --link

文章目录 总结环境概述“ --link” 是什么引入“ --link”使用“COPY --link”示例什么情况不适用总结参考 注&#xff1a;我做了很多测试&#xff0c;发现不管是否使用 --link &#xff0c;结果貌似都一样。我在网上搜了半天&#xff0c;最后发现&#xff0c;该功能貌似目前被…

计算机网络的常用的网络通信命令(Windows)

ping&#xff1a;它是用来检查网络是否通畅或者网络连接速度的命令。ping命令利用的原理是&#xff1a;网络上的机器都有唯一确定的IP地址&#xff0c;我们给目标IP地址发送一个数据包&#xff0c;对方就要返回一个同样大小的数据包&#xff0c;根据返回的数据包我们可以确定目…

父(子)组件获取子(父)组件的方法和数据

1.父组件获取子组件的方法和数据 在父组件中的子组件添加 ref"childName"&#xff0c;childName自定义 <childComponent ref"childName"></childComponent> #获取子组件的方法 method:方法名this.$refs.childName.method()#获取子组件的数…

Linux——安装docker

安装 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun启动docker systemctl start docker常用指令 查找镜像 docker search [name]拉取镜像 docker pull [name]运行容器 docker run [name] 配置项&#xff1a;-i 交互式 -t 终端 -d 后台运行 --name [n…

【力扣每日一题】力扣83删除排序链表中的重复元素

题目来源 力扣83删除排序链表中的重复元素 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 思路分析 思路一&#xff1a;使用两个指针&#xff0c;last指针指向上一个元素&#xff0c;…

高中电学实验学习

bilibili上的笔记有价值的链接 1、 自学物理吧 电学实验 https://www.bilibili.com/video/BV1SM411u757/?spm_id_from333.337.search-card.all.click&vd_source91b03ee59c462b7b3cfbd57346cf1001 2、张老师的物理课堂 测电源电动势和内阻

Unity求射线与球体交点(有可能还能优化)

代码如下&#xff1a; bool RayCrossSphere(Ray ray, Sphere sphere, out Vector3[] vs) {Vector3 c2o sphere.center - ray.origin;float sqrtRadius sphere.radius * sphere.radius;Vector3 project Vector3.Project(c2o, ray.direction);Vector3 vPoint ray.origin pr…

【驱动】TI AM437x(内核调试-02):dynamic 动态打印调试

1、配置内核 dynamic 可以根据不同级别的作用域来启用/禁用-每个源文件、函数、模块、格式字符串和行号的打印信息。 内核中,默认没有配置 dynamic ,因为使能 dynamic 会使内核增大2% Symbol: DYNAMIC_DEBUG [=n] Type : boolean …

SpringCloud:Ribbon

文章目录 Ribbon快速入门Ribbon负载均衡算法常见的负载均衡算法更改算法规则修改配置 饥饿加载 Ribbon ribbon是一个客户端负载均衡器&#xff0c;会从注册中心拉取可用服务&#xff0c;当客户端需要获取服务请求时&#xff0c;ribbon能够解析服务地址并实现负载均衡 快速入门 …