KTRR 介绍

时间:2022-11-06 22:55:06

简介

KTRR是Kernel Text Readonly Region 的简写,内核代码只读区域。用于保护IOS设备在运行时kernel的完整性。本文主要是学习翻译别人的文档,原文请看KTRR

注意

为了避免寄存器一词的滥用,做了如下一些约定。

  • 寄存器:指实际的寄存器,能被ARM64 通过msr 指令访问的寄存器。 每个cpu core都有一份独立的寄存器,当cpu core进入睡眠状态时,这些值会丢失。例如SCTL_EL3 等。
  • MMIO:memory-mapped I/O,内存映射的IO, 是cpu能访问的物理地址空间一部分,cpu core 通过访问这些地址空间可以实现与外设的交互。是SOC上一片特殊的存储器,属于SOC,但是不属于CPU core,当cpu core 睡眠时,MMIO的值不会丢失。

要区分这两者是因为KTRR是基于SOC上的MMIO和CPU core内部的寄存器实现的。

原语

apple 的芯片在舍弃了EL3后,A系列芯片新引入了两个新的特性作为KTRR的墙角石。

  • RoRgn 我们可以理解是 read only region, 只读区域。只读区域是通过SOC上的MMIO实现的,3个MMIO实现,分别表示起始地址start、结束地址end和lock,当lock MMIO被置位时,上述3个MMIO都不能被修改,除非芯片复位。在start 和 end 之间是DRAM上的物理页,这些物理页只能被读取,内存控制器拒绝任何形式的写。对所有CPU core都生效。其实也就是从DRAM中划分出一些CPU只读的区域,需要注意的是,不仅阻止了CPU写,也阻止了其它处理器以及DMA设备发起的写操作。

  • KTRR 寄存器。每个cpu core 都新增了3个寄存器,分别表示low、high、lock,同样的,lock寄存器会同时锁住low、high和lock寄存器。low和high寄存器表示可执行区域的物理地址范围。当cpu core 处于EL1且mmu使能时,cpu core只能从low和high之间的区域取代码执行,从其它的地方取代码执行会失败,即使这些地方被页表标记为可执行也会失败。如果 cpu core 处于El0或mmu未使能时,则不受low和high影响。主要的目的就是限制了cpu core只能执行kernel的代码段,不能执行其它区域的代码,且是硬件级别的限制,即使修改页表也无法改变。这比ARMV8 页表的XNbit管控能力更强。

  • IORVBAR。 IORVBAR 属于MMIO,其为每个CPU core都保存了一个地址,在CPU reset时从该位置执行(大部分是从休眠时醒来执行)。同样也是需要锁机制来保护IORVBAR被非法修改,IORVBAR的锁机制是通过对其最低bit写1实现的。在早期的A9 CPU 系列,CPU core 在reset 后执行的地址是放在trustzone内的,Apple的watertower 也是位于此位置,这就是EL3. 从A10开始, cpu core 在reset时执行的物理地址被设置为 LowResetVectorBase,iboot 会根据 LowResetVectorBase计算出kernel的入口地址。

上述