arm初探

# PREFACE:之前猜猜查查的,感觉不彳亍了,这下不得不和 arm 爆了!

# 架构介绍

img

img

# 架构层级
  • EL0: 无特权模式 (unprivileged)
  • EL1: 作业系統核心模式 (OS kernel mode)
  • EL2: 虚拟机器监视器模式 (Hypervisor mode)
  • EL3: TrustZone(monitor mode)

要提升到较高层级需要透过 exceptions (如:中断、page faults 等)。

  • EL0 => EL1: SVC (system call)
  • EL1 => EL2: HVC (hypervisor call)
  • EL2 => EL3: SMC (secure monitor call)

在转换时会将返回地址 (return address) 记录在例外连结寄存器 ELR (Exception-Link-Register)。

每个 EL 会有个别的 SP (stack pointer)

根据目前架构,由下层系統的 Execution State 決定上层系统所在模式

若下层系統为 32bits 則上层只能为 32bits,反之若为 64bits 則上层可为 32bits or 64bits

# 安全性状态 (Security state)

ARMv8-A 架构提供两种安全性状态,他们有个别的实体记忆体定址空间 (Secure physical address space)。

安全状态 (Secure state): PE 可以存取安全及不安全的实体定址空间,有 EL0.EL1.EL3

不安全状态 (Non-Secure state): 只能存取不安全的实体定址空间,有 EL0.EL1.EL2

# 虚拟化 (Virtualization)

这边提到的虚拟化为有实现 EL2 架构的系统。以下为其基础模型: (manual D1.5 Virtualization)

一个跑在 EL2 的 Hypervisor 负责切换跑在 EL1、EL0 的 virtual machines 一些跑在 virtual machines 上 (在 EL1 中) 的 Guest OS 每个 Guest OS 上跑在 EL0 的应用程序 每个 VM 会被 Hypervisor 指定一个 VMID。

EL2 只会实现在 Non-secure state,并负责:

提供虚拟值给少数特定的暂存器 (1)。Guest OS 或其上的应用程序读取这些暂存器时会得到虚拟的值。 Trapping: 当在做记忆体管理及存取其他大多数的暂存器 ((1) 之外的) 时会产生 exception 并由 EL2 处理。 Routing interrupt: 将中断分配给 现在的 Guest OS 现在没在执行的 Guest OS hypervisor (以上会在各别的章节特别探讨) 实现 EL2 包含以下实作:

Hypervisor Call (HVC) exception Traps to EL2 虚拟中断:包括: Virtual SError Virtual IRQ Virtual FIQ 所有虚拟中断会由 EL1 处理 每个虚拟中断可由 EL2 各别启用 每个虚拟中断都会有其对应的实体中断 当一个虚拟中断被启用时,其对应的实体中断会由 EL2 处理 (除非 EL3 指定他要处理)

偷了个,基本上简单入门够了

# 【ARM】内核寄存器以及常用汇编指令分析 - 知乎 (zhihu.com)

ARM Data Types and Registers (Part 2) | Azeria Labs (azeria-labs.com)

Wiki - ARMv8 (ncku.edu.tw) : 这个讲的挺底层的

ARM 指令 - HackMD:这个主要偏移动设备

# 常见寄存器

# 基本寄存器结构

img

# R13,堆栈指针 (Stack Pointer)

R13 寄存器中存放的是堆栈的栈顶指针,CM3 中有两个堆栈指针,也就支持两个堆栈。分别是:主堆栈指针 (Main Stack Pointer),进程堆栈指针 (Process Stack Pointer)。

堆栈主要是通过 POP,PUSH 指令来进行操作。在执行 PUSH 和 POP 操作时,那个通常被称为 SP 的地址寄存器,会自动被调整,以避免后续的操作破坏先前的数据。

在一个汇编程序中, LR 用于在调用子程序时存储返回地址。例如,在使用 BL (分支并连接, Branch and Link) 指令时,就自动填充 LR 的值 (执行函数调用的下一指令),进而在函数退出时,正确返回并执行下一指令。

如果函数中又调用了其他函数,那么 LR 将会被覆盖,所以需要先将 LR 寄存器入栈 PUSH,保护起来。

# R15,程序计数器 (Program Count)

因为 CM3 内部使用了指令流水线,读 PC 时返回的值是当前指令的地址 + 4

# 特殊功能寄存器组

Cortex‐M3 中的特殊功能寄存器包括:

程序状态寄存器组( xPSR),存放当前 CPU 的状态

中断屏蔽寄存器组( PRIMASK, FAULTMASK, 以及 BASEPRI),用于控制异常的使能和除能

控制寄存器( CONTROL),用于定义特权级别,以及选择当前使用堆栈指针 (PSP/MSP?)。

# CM3 的操作模式

为了架构的安全性和健壮性,CM3 支持 2 个模式 (线程模式,handler 模式),以及 2 个特权等级 (特权级,用户级)。handler 模式下只能是特权级。

img

# 复位序列

在进入复位状态后, CM3 做的第一件事就是读取下列两个 32 位整数的值:

从地址 0x0000,0000 处取出 MSP 的初始值。(初始化 MSP,为后续的代码执行创造环境)

从地址 0x0000,0004 处取出 PC 的初始值 — 这个值是复位向量。(启动引导代码)

img

img

# ARM 汇编指令集

ARM 指令集可以分为跳转指令、数据处理指令、程序状态寄存器 (PSR) 处理指令、加载 / 存储指令、协处理器指令和异常产生指令六大类

跳转指令:B,BL,BX,BXL (用于函数调用时的跳转,分为带 / 不带 返回地址 / 状态 的跳转)

数据处理指令:MOV,ADD,SUB,DIV,MUL,AND,ORR,CMP…(赋值,加减乘除,与或逻辑,比较)

程序状态寄存器 (PSR) 处理指令:MSR,MRS (用于查询或设置状态寄存器 / 特殊寄存器的数据)

加载 / 存储指令: LDR,STR…(* 用于寄存器与内存之间的数据交换,一般为间接寻址)

异常产生指令:SWI (用于产生软件中断)