嵌入式Hypervisor组件设计(一)

Linux阅码场 2024-07-16 08:01
 本文节选自孙陈伟著《嵌入式Hypervisor架构、原里与应用》
     PRTOS 通过分离内核架构以及半虚拟化技术实现。半虚拟化具有高性能和低复杂度的优势。如果客户操作系统或应用程序需要运行在虚拟化环境中,首先要做的就是修改源码,以调用半虚拟化服务。半虚拟化模型具备较强的性能优势,能够最大限度地提升系统实时性。
     PRTOS 必须运行在处理器特权模式下,为分区提供虚拟化服务,并虚拟出 CPU、内存、中断和一些特定的外围设备,形成 PRTOS 基本架构,如图 2-2 所示。PRTOS 包含硬件依赖层、虚拟化服务层、内部服务层以及超级调用接口函数库。本章将分别介绍这 4 个组件。
3.1 硬件依赖层
     硬件依赖层是嵌入式系统软件架构的底层,负责与底层硬件进行交互和通信,以控制和管理硬件资源。硬件依赖层包括设备驱动程序、硬件抽象层等组件。
     在嵌入式系统中,硬件依赖层直接与硬件资源进行交互,对系统性能和功能具有很大的影响。通过硬件依赖层,软件可以直接控制和管理硬件资源,如 CPU、内存、外围设备等资源,从而实现软件系统的各项功能。同时,硬件依赖层还可以对硬件资源进行抽象和封装处理,以简化软件开发和维护的工作。
3.1.1 硬件资源虚拟化
虽然虚拟化技术在桌面系统领域取得了极大的进展,但在嵌入式领域的发展受到了诸多限制。
1. 虚拟化受限的因素
虚拟化技术在嵌入式领域主要受到以下 4 个因素的限制。
1)在硬件资源配置方面,嵌入式系统通常面临资源受限的局面,包括处理能力、内存和存储容量的限制。而虚拟化技术通常需要较多的计算和内存资源来管理虚拟机,这可能会导致嵌入式系统性能下降。
2)在处理器选型方面,应用在嵌入式领域的处理器架构对硬件虚拟化的支持是非常保守的。比如应用在嵌入式领域的 MCU(Micro Control Unit,微控制单元)系列一般是 32 位的 ARMv7 架构,不支持硬件虚拟化。即使是多核处理器,为了节省成本,通常也不包含硬件虚拟化扩展组件。
3)在软件设计方面,当应用程序需要满足实时需求时,引入 Hypervisor 后,应用程序、操作系统以及 Hypervisor 的设计均需要满足实时需求。
4)在硬件设计方面,单核 / 多核处理器的底层架构设计会直接影响整个系统的实时性,其中流水线和高速缓存是影响系统实时性的两个主要因素。
同时,考虑到 Hypervisor 是所有分区应用程序的公共软件层,为了使不同安全级别的分区应用共存于系统中,Hypervisor 的安全级别必须是整个安全关键系统中最高的。
2. 分区包含的硬件
分区是 Hypervisor 创建的运行时环境,又称虚拟机或域(Domain),用于执行用户代码,并使得分区中的用户代码像在原生硬件平台上执行一样。在分区环境下,需要进行硬件抽象处理的资源包含以下 6 种。
1)某些特殊的 CPU 寄存器资源,比如 Intel X86 处理器中的 CR3、GDTR(GlobalDescriptor Table Register,全局描述符表寄存器)、IDTR(Interrupt Descriptor Table Register,中断描述符表寄存器)等。
2)硬件中断控制器。
3)硬件时钟和定时器。
4)基于分页的 MMU 硬件资源。
5)X86 平台通过 I/O 端口地址管理 I/O 设备。
6)高速缓存管理。
分区通过 Hypervisor 提供的超级调用服务来使用虚拟化的资源。比如分区需要设置定时器时,不能直接访问硬件定时器资源,可以通过使用 Hypervisor 提供的定时器服务来实现定时功能。
在分区环境下,以下 3 种硬件资源是不需要被虚拟化的。
1)分配给该分区的内存地址空间:分区可以直接访问。
2)非特权指令:可以直接在原生 pCPU 上运行。比如,一个分区代码执行一条加指令(ADD)时可以直接在 pCPU 上运行,不需要 Hypervisor 的参与。
3)硬件高速缓存:高速缓存的使用对 Hypervisor 来说是透明的,这和在原生硬件环境下高速缓存的使用对操作系统透明是类似的。
在多核处理器硬件平台,实现 Hypervisor 的虚拟化技术需要考虑一些特殊情况。比如,Hypervisor 在解决与缓存管理和信息安全相关的问题时,为了避免分区缓存的泄密隐患,分区被调度时通常采取刷新缓存的方式来避免敏感信息泄露。又比如,不同处理器核心对共享内存的访问会引入竞争问题,导致系统响应时间不确定。对此,虚拟化层只能缓解,不能彻底解决,需要系统在分区层通过更复杂的计算方式来估算 WCET,来确定临时的解决方案。
3.1.2 处理器驱动
处理器驱动主要负责初始化工作,包括设置处理器时钟、中断控制器、内存控制器等。本小节主要介绍与处理器时钟、中断控制器初始化相关的两类驱动,以实现 PRTOS 获取CPU 主频和设置 CPU 中断向量。本小节之所以不涉及内存控制器的初始化,是因为在 IntelX86 平台使用 GRUB(GRand Unified Bootloader,大统一启动加载器)来加载 PRTOS 系统映像时,已经对内存控制器做了初始化,PRTOS 无须对内存控制器再次初始化。
1. 获取 CPU 主频
在 Intel X86 硬件平台,可借助 64 位的 TSC(Time Stamp Counter,时间戳定时器)和Intel 8253(也称为 Intel 8254)PIT(可编程中断定时器)的计时通道 2,来计算当前 CPU的主频。
TSC 可以对驱动 CPU 的时钟脉冲进行计数。Intel 8253 芯片的时钟输入频率是 1 193 180Hz。通过设定一定的初始计数值 LATCH(默认值为 65 535),就能控制该芯片的输出频率(默认为 1 193 180/65 535Hz)。例如,假定 LATCH=1 193 180/100,则能保证输出频率为 100Hz,即周期为 10ms。
脉冲的精度是 1 /(CPU 主频)。比如,CPU 的主频是 500MHz,那么时钟脉冲的精度就是 2ns。
可通过设置 Intel 8253 PIT 的计时通道 2 让定时器工作在模式 0 下。之所以选择通道 2,是因为通道 2 的输出电平可以通过 I/O 端口 0x61 的第 5 位读取。在模式 0 下,当计数器的值递减到 0 时,通道 2 的输出持续处于高电平状态,并且计数器只计数一遍,便于读取通道 2 的计数器值递减到 0 时的状态。这样我们就可以在通道 2 的计数值从 LATCH 递减到0 的时间段内,将 TSC 记录的时钟脉冲次数乘以(1 193 180/LATCH),计算得到的结果即CPU 当前工作频率。CPU 当前工作频率的具体计算过程如代码清单 3-1 所示。
代码清单 3-1 计算 CPU 的当前工作频率

//源码路径:core/kernel/x86/processor.c
01 #define CLOCK_TICK_RATE 1193180 //时钟频率Hz
02 #define PIT_CH2 0x42
03 #define PIT_MODE 0x43
04 #define CALIBRATE_MULT 100
05 #define CALIBRATE_CYCLES CLOCK_TICK_RATE / CALIBRATE_MULT
06
07 __VBOOT prtos_u32_t calculate_cpu_freq(void) {
08 prtos_u64_t c_start, c_stop, delta;
09
10 out_byte((in_byte(0x61) & ~0x02) | 0x01, 0x61);
11 out_byte(0xb0, PIT_MODE); //二进制, 模式0, LSB/MSB, 通道2
12 out_byte(CALIBRATE_CYCLES & 0xff, PIT_CH2); //低8位写入
13 out_byte(CALIBRATE_CYCLES >> 8, PIT_CH2); //高8位写入
14 c_start = read_tsc_load_low();
15 delta = read_tsc_load_low();
44 嵌入式 Hypervisor:架构、原理与应用
16 in_byte(0x61);
17 delta = read_tsc_load_low() - delta;
18 while ((in_byte(0x61) & 0x20) == 0)
19 ;
20 c_stop = read_tsc_load_low();
21
22 return (c_stop - (c_start + delta)) * CALIBRATE_MULT;
23 }

提示:这里的源码路径是相对于 PRTOS 源码根目录的位置,即 https://github.com/prtos-project/prtos-hypervisor。后续源码路径均为相对于这个根目录的路径。
2. 设置 CPU 中断向量
在介绍中断向量初始化之前,我们先介绍中断种类和 Intel X86 处理器的中断向量表。
(1)中断种类
中断的来源有两种:一种是由 CPU 外部产生的,另一种是 CPU 在执行程序过程中产生的。外部中断就是通常所讲的“中断”。对执行中的软件来说,外部中断是异步的,CPU(或者软件)对外部中断的响应完全是被动的,当然软件可以通过关中断指令关闭 CPU 的响应(这里不考虑系统重置等不可屏蔽中断)。而 CPU 在执行程序过程中产生的中断往往是由专设的指令有意产生的,这种主动的中断被称为陷阱。除此之外,还可能存在预期之外的中断,一般是同步的,被称为异常。例如程序中的除法指令(DIV),当除数为 0 时,就会发生一次同步异常。
不管是外部产生的中断,还是内部产生的陷阱或异常,CPU 的响应过程基本一致,即在执行完当前指令之后或者在执行当前指令的中途,根据中断源提供的中断向量在内存中找到相应的服务程序入口并调用该服务程序。外部中断的向量是由软件或硬件设置好了的,陷阱向量是在自陷指令中发出的,其他各种异常的向量则是在 CPU 的硬件结构中预先设定的。这些不同的情况因中断向量号的不同而被分开。根据中断类型的不同 Hypervisor,挂载的中断处理程序也不同。PRTOS 的中断处理类型如图 3-1 所示。

(2)Intel X86 处理器的中断向量表
      在 X86 处理器中,中断向量表中的表项称为“门”,意思是当中断发生时必须先通过这些门,才能进入相应的服务程序。这里的门并不仅是为中断而设的,只要想切换 CPU 的运行状态(如从用户 Ring 3 进入系统 Ring 0),就需要通过一道门。而从用户模式进入系统态的途径也并不只限于中断(或者异常,或者陷阱),还可以通过子程序调用指令 CALL 来达到目的(PRTOS 的超级调用就是通过子程序调用指令 CALL 实现的)。而且当中断发生时,不但可以切换 CPU 的运行状态并转入中断服务程序,还可以安排一次分区切换(即分区上下文切换),立即切换到另一个分区。
    根据用途和目的的不同,X86 CPU 的门共分为 4 种:任务门、中断门、陷阱门以及调用门。PRTOS 只初始化中断门和陷阱门。中断门、陷阱门均指向一个子程序,必须结合使用段选择子和段内偏移来确定这个子程序的位置。
    中断门和陷阱门在使用上的区别不在于中断是由外部产生还是由 CPU 本身产生的,而在于通过中断门进入中断服务程序时,CPU 会自动将中断关闭(关中断),即将 CPU 中的标志寄存器(EFLAGS)的 IF 标志位清 0,以防嵌套中断的发生;而通过陷阱门进入服务程序时,则维持 IF 标志位不变。这就是中断门和陷阱门的唯一区别。不管是什么门,都通过段选择子指向一个存储段。段选择子的作用与普通的段寄存器一样。在保护模式下,段寄存器的内容并不直接指向一个段的起始地址,而是指向由 GDTR 或 LDTR 确定的某个段描述表中的一个表项。至于到底是由 GDTR 还是由 LDTR 所指向的段描述表,则取决于段选择子中的 TI 标志位。在 PRTOS 中只使用全局段描述表 GDT。对中断门和陷阱门来说,段描述表中的相应表项是一个代码段描述符表项。
     CPU 通过中断门找到一个代码段描述符表项,并进而转入相应的中断处理程序。之后,CPU 要将当前 EFLAGS 寄存器的内容以及返回地址压入栈,返回地址由段寄存器CS 的内容和取指令指针 EIP 的内容共同组成。如果中断是由异常引起的,则还要将表示异常原因的出错代码也压入栈。进一步地,如果中断服务程序的运行级别不同(即目标代码段的 DPL 与中断发生时的 CPL 不同),还得更换栈。X86 的任务状态段(Task StateSegment,TSS)描述符结构中除包含所有常规的寄存器内容外,还有 3 对额外的栈指针(SS 和 ESP)。这 3 组栈指针分别对应 CPU 在目标代码段中的运行级别 Ring 0、Ring 1和 Ring 2。CPU 根据寄存器 TR 的内容找到当前的 TSS 结构,并根据目标代码段的 DPL从 TSS 结构中取出新的栈指针(SS 加 ESP),装入段寄存器(Segment Register,SS)和栈指针寄存器(Extended Stack Pointer,ESP),从而达到更换栈的目的。在这种情况下,CPU 不但要将 EFLAGS、返回地址以及出错代码压入栈,还要将原来的栈指针也压入栈(新栈)。
(3)Intel X86 处理器中断向量表的定义及初始化
在 Intel X86 硬件平台,PRTOS 中断向量表的定义如代码清单 3-2 所示。
代码清单 3-2 PRTOS 中断向量表的定义

//源码路径:core/kernel/x86/head.S

01 #include

02 #include

03 #include

04 #include

05 #include

06 ...

07 .data

08 PAGE_ALIGN

09 .word 0

10 ENTRY(idt_desc) //PRTOS中断描述符表

11 .word IDT_ENTRIES*8-1

12 .long _VIRT2PHYS(hyp_idt_table)

13 ...

14 ENTRY(hyp_idt_table) //PRTOS中断向量表的定义

15 .zero IDT_ENTRIES*8

16

中断向量表的初始化如代码清单 3-3 所示。

代码清单 3-3 中断向量表的初始化

//源码路径:core/kernel/x86/irqs.c

01 void setup_x86_idt(void) {

02 //setup_x86_idt()函数的具体实现,请参考PRTOS对应的源码文件

34 }

setup_x86_idt() 函数的主要功能如下。

1)完成外部中断向量服务程序的初始化(这里假设有 16 个外部中断)。

2)实现 X86 CPU 预留的 19 个陷阱门和异常门描述选项的初始化。






Linux阅码场 专业的Linux技术社区和Linux操作系统学习平台,内容涉及Linux内核,Linux内存管理,Linux进程管理,Linux文件系统和IO,Linux性能调优,Linux设备驱动以及Linux虚拟化和云计算等各方各面.
评论
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 332浏览
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 216浏览
  • 故障现象 一辆2007款日产天籁车,搭载VQ23发动机(气缸编号如图1所示,点火顺序为1-2-3-4-5-6),累计行驶里程约为21万km。车主反映,该车起步加速时偶尔抖动,且行驶中加速无力。 图1 VQ23发动机的气缸编号 故障诊断接车后试车,发动机怠速运转平稳,但只要换挡起步,稍微踩下一点加速踏板,就能感觉到车身明显抖动。用故障检测仪检测,发动机控制模块(ECM)无故障代码存储,且无失火数据流。用虹科Pico汽车示波器测量气缸1点火信号(COP点火信号)和曲轴位置传感器信
    虹科Pico汽车示波器 2025-01-23 10:46 249浏览
  • 书接上回:【2022年终总结】阳光总在风雨后,启航2023-面包板社区  https://mbb.eet-china.com/blog/468701-438244.html 总结2019,松山湖有个欧洲小镇-面包板社区  https://mbb.eet-china.com/blog/468701-413397.html        2025年该是总结下2024年的喜怒哀乐,有个好的开始,才能更好的面对2025年即将
    liweicheng 2025-01-24 23:18 247浏览
  • 嘿,咱来聊聊RISC-V MCU技术哈。 这RISC-V MCU技术呢,简单来说就是基于一个叫RISC-V的指令集架构做出的微控制器技术。RISC-V这个啊,2010年的时候,是加州大学伯克利分校的研究团队弄出来的,目的就是想搞个新的、开放的指令集架构,能跟上现代计算的需要。到了2015年,专门成立了个RISC-V基金会,让这个架构更标准,也更好地推广开了。这几年啊,这个RISC-V的生态系统发展得可快了,好多公司和机构都加入了RISC-V International,还推出了不少RISC-V
    丙丁先生 2025-01-21 12:10 1135浏览
  •  万万没想到!科幻电影中的人形机器人,正在一步步走进我们人类的日常生活中来了。1月17日,乐聚将第100台全尺寸人形机器人交付北汽越野车,再次吹响了人形机器人疯狂进厂打工的号角。无独有尔,银河通用机器人作为一家成立不到两年时间的创业公司,在短短一年多时间内推出革命性的第一代产品Galbot G1,这是一款轮式、双臂、身体可折叠的人形机器人,得到了美团战投、经纬创投、IDG资本等众多投资方的认可。作为一家成立仅仅只有两年多时间的企业,智元机器人也把机器人从梦想带进了现实。2024年8月1
    刘旷 2025-01-21 11:15 905浏览
  • 前篇文章中『服务器散热效能不佳有解吗?』提到气冷式的服务器其散热效能对于系统稳定度是非常重要的关键因素,同时也说明了百佳泰对于散热效能能提供的协助与服务。本篇将为您延伸说明我们如何进行评估,同时也会举例在测试过程中发现的问题及改善后的数据。AI服务器的散热架构三大重点:GPU导风罩:尝试不同的GPU导风罩架构,用以集中服务器进风量,加强对GPU的降温效果。GPU托盘:改动GPU托盘架构,验证出风面积大小对GPU散热的影想程度。CPU导风罩:尝试封闭CPU导风罩间隙,集中风流,验证CPU降温效果。
    百佳泰测试实验室 2025-01-24 16:58 129浏览
  • 项目展示①正面、反面②左侧、右侧项目源码:https://mbb.eet-china.com/download/316656.html前言为什么想到要做这个小玩意呢,作为一个死宅,懒得看手机,但又想要抬头就能看见时间和天气信息,于是就做个这么个小东西,放在示波器上面正好(示波器外壳有个小槽,刚好可以卡住)功能主要有,获取国家气象局的天气信息,还有实时的温湿度,主控采用ESP32,所以后续还可以开放更多奇奇怪怪的功能,比如油价信息、股票信息之类的,反正能联网可操作性就大多了原理图、PCB、面板设计
    小恶魔owo 2025-01-25 22:09 358浏览
  • 不让汽车专美于前,近年来哈雷(Harley-Davidson)和本田(Honda)等大型重型机车大厂的旗下车款皆已陆续配备车载娱乐系统与语音助理,在路上也有越来越多的普通机车车主开始使用安全帽麦克风,在骑车时透过蓝牙连线执行语音搜寻地点导航、音乐播放控制或免持拨打接听电话等各种「机车语音助理」功能。客户背景与面临的挑战以本次分享的客户个案为例,该客户是一个跨国车用语音软件供货商,过往是与车厂合作开发前装车机为主,且有着多年的「汽车语音助理」产品经验。由于客户这次是首度跨足「机车语音助理」产品,因
    百佳泰测试实验室 2025-01-24 17:00 154浏览
  • 2024年是很平淡的一年,能保住饭碗就是万幸了,公司业绩不好,跳槽又不敢跳,还有一个原因就是老板对我们这些员工还是很好的,碍于人情也不能在公司困难时去雪上加霜。在工作其间遇到的大问题没有,小问题还是有不少,这里就举一两个来说一下。第一个就是,先看下下面的这个封装,你能猜出它的引脚间距是多少吗?这种排线座比较常规的是0.6mm间距(即排线是0.3mm间距)的,而这个规格也是我们用得最多的,所以我们按惯性思维来看的话,就会认为这个座子就是0.6mm间距的,这样往往就不会去细看规格书了,所以这次的运气
    wuliangu 2025-01-21 00:15 629浏览
  • 飞凌嵌入式基于瑞芯微RK3562系列处理器打造的FET3562J-C全国产核心板,是一款专为工业自动化及消费类电子设备设计的产品,凭借其强大的功能和灵活性,自上市以来得到了各行业客户的广泛关注。本文将详细介绍如何启动并测试RK3562J处理器的MCU,通过实际操作步骤,帮助各位工程师朋友更好地了解这款芯片。1、RK3562J处理器概述RK3562J处理器采用了4*Cortex-A53@1.8GHz+Cortex-M0@200MHz架构。其中,4个Cortex-A53核心作为主要核心,负责处理复杂
    飞凌嵌入式 2025-01-24 11:21 225浏览
  • 随着AI大模型训练和推理对计算能力的需求呈指数级增长,AI数据中心的网络带宽需求大幅提升,推动了高速光模块的发展。光模块作为数据中心和高性能计算系统中的关键器件,主要用于提供高速和大容量的数据传输服务。 光模块提升带宽的方法有两种:1)提高每个通道的比特速率,如直接提升波特率,或者保持波特率不变,使用复杂的调制解调方式(如PAM4);2)增加通道数,如提升并行光纤数量,或采用波分复用(CWDM、LWDM)。按照传输模式,光模块可分为并行和波分两种类型,其中并行方案主要应用在中短距传输场景中成本
    hycsystembella 2025-01-25 17:24 270浏览
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 385浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦