也谈MMU管理机制

1,结构:

MMU存储器系统的结构允许对存储器系统的精细控制。大部分的控制细节由存在存储器中的转换表提供。这些表的入口定义了从1KB 到1MB 的各种存储器区域的属性。这些属性包括:
Ø        虚拟地址到物理地址映射
ARM 处理器产生的地址叫虚拟地址,MMU 允许把这个虚拟地址映射到一个不
同的物理地址去。
这个物理地址表示了被访问的主存储器的位置。如果使用了快速上下文切换扩展(Fast Context Switch Extension),则在本文中的虚拟地址的意思应该是修改过的虚拟地址(Modified virtualaddress)
这种方式允许我们用很多方式管理物理存储器的位置,例如:
用具有潜在冲突的地址映射为不同的进程分配存储器;
允许具有不连续地址的应用把它映射到连续的地址空间。
Ø        存储器访问权限(permissions)
控制对存储器区域的不可访问权限、只读权限、读写权限。当访问不可
访问权限的存储器时,会有一个存储器异常通知ARM 处理器。
允许权限受程序运行在用户状态还是特权状态影响,还和是否使用了域有关。
Ø        高速缓存和缓冲位(Cachability and bufferability bits [C and B])
这些在高速缓存和缓冲一节讲
系统控制协处理器的寄存器允许对系统的高级控制,如转换表的位置。他们也用来为ARM 提供内存异常的状态信息。
查找整个转换表的过程叫转换表遍历。它由硬件制动进行,并需要大量的执行时间(至少一个存储器访问,通常是两个)。为了减少存储器访问的平均消耗,转换表遍历结果被高速缓存在一个或多个叫作Translation Lookaside Buffers(TLBs)的结构中。通常在ARM 的实现中每个内存接口有一个TLB。
·  有一个存储器接口的系统通常有一个唯一的TLB
·  指令和数据的内存接口分开的系统通常有分开的指令TLB 和数据TLB
如果系统有高速缓存, 高速缓存的数量也通常是由同样的方法确定的。所以在高速缓存的系统中,每个高速缓存一个TLB。当存储器中的转换表被改变或选中了不同的转换表(通过写CP15 的寄存器2),先前高速缓存的转换表遍历结果将不再有效。MMU 结构提供了刷新TLB 的操作。MMU 结构也允许特定的转换表遍历结果被锁定在一个TLB 中,这就保证了对相关的存储器区域的访问绝不会导致转换表遍历,这也对那些把指令和数据锁定在高速缓存中的实时代码有相同的好处。

2,存储器访问的顺序

当ARM 要访问存储器时,MMU 先查找TLB 中的虚拟地址表,如果ARM 的结构支持分开的地址TLB 和指令TLB,那么它用:
·  取指令使用指令TLB
·  其它的所有访问类别用数据TLB
如果TLB 中没有虚拟地址的入口,则转换表遍历硬件从存在主存储器中的转换表中获取转换和访问权限,一旦取到,这些信息将被放在TLB 中,它会放在一个没有使用的入口处或覆盖一个已有的入口。关于转换表的信息和转换表遍历的实现参见转换过程一节。
一旦为存储器访问的TLB 的入口被拿到,这些信息将被用于:
1. C(高速缓存)和B(缓冲)位被用来控制高速缓存和写缓冲,并决定是否高速缓存。(如果系统中没有高速缓存和写缓冲,则对应的位将被忽略)
2. 访问权限和域位用来控制访问是否被允许。如果不允许,则MMU 将向ARM 处理器发送一个存储器异常;否则访问将被允许进行。
访问权限、域和异常几节有详细描述。
3. 对没有高速缓存的系统(包括在没有高速缓存系统中的所有存储器访问),物理地址将被用作主存储器访问的地址。对有高速缓存的系统,在高速缓存没有选中的情况下,物理地址将被用行取(line fetch)的地址。如果选中了高速缓存,则物理地址将被忽略。图3-1 说明了这种高速缓存系统
mmu_1.JPG

2.1允许和禁止MMU

通过写系统控制协处理器的寄存器1 的第0 位可以允许和禁止MMU。在复位后这位是0,MMU 被禁止。当MMU 被禁止时,存储器访问将被按如下处理:
1. 由具体的实现确定当MMU 被禁止时是否能够允许高速缓存和写缓冲。
·  当MMU 被禁止时不能允许高速缓存和写缓冲时,C 和B 位不起作用。
·  当MMU 被禁止时能允许高速缓存和写缓冲时:
i. 访问数据时被认为没有高速缓存和写缓冲(C==0,B==0)
ii. 取指令时:
a) 当系统只有一个唯一的TLB 时,认为是没有高速缓存。(C==0)
b) 当系统只有独立的指令TLB 时,认为是有高速缓存。(C==1)
2. 没有存储器访问权限的检查,MMU 也不产生异常信号。
3. 物理地址与虚拟地址相同(即所谓的平坦地址映射模式)。
在允许MMU 之前,必须在内存中建立适当的转换表,并且所有相关的CP15 寄存器要被初始化正确。
允许和禁止MMU 直接改变了虚拟地址到物理地址的映射(除非转换表被设定为平坦地址映射模式)。所以很可能在允许MMU 时所有的高速缓存需要被刷新。另外,如果允许MMU 的指令的物理地址和虚拟地址不同,取指令将变得复杂化。所以,强烈建议允许MMU 的指令具有相同的物理地址和虚拟地址。

3转换过程

MMU 支持基于节或页的存储器访问:
(Section) 构成1MB 的存储器块
支持3 中不同的页尺寸:
微页(Tiny page) 构成1KB 的存储器块
小页(Small page) 构成4KB 的存储器块
大页(Large page) 构成64KB 的存储器块
节和大页是支持允许只用一个TLB 入口去映射大的存储器区间。小页和大页有附加的访问控制:小页分成1KB 的子页,和大页分成16KB 的子页。微页没有子页,对微页的访问控制是对整个页。
存在主存储器内的转换表有两个级别:
第一级表 存储节转换表和指向第二级表的指针。
第二级表 存储大页和小页的转换表。一种类型的第二级表存储微页转换表。
MMU 把CPU 产生的虚拟地址转换成物理地址去访问外部存储器,同时继承并检查访问权限。地址转换有四条路径。路径的选取由这个地址是被标记成节映射访问还是页映射访问确定。页映射访问可以是大、小和微页的访问。
然而,转换过程总是由下面所描述的那样由第一级表的获取开始。节映射的访问只需要读取第一级表,页映射的访问还需要读取第二级表。

3.1 转换表基址

当片上(on-chip)的TLB 中不包含被要求的虚拟地址的入口时,转换过程被启
动。转换表基址寄存器(CP15 的寄存器2)保存着第一级转换表基址的物理地址。
只有bits[31:14]有效,bits[13:0]应该是零(SBZ)。所以第一级表必须在16KB
的边界。

3.2 取第一级表

转换表基址寄存器的bits[31:14]与虚拟地址的bits[31:20]和两个0 位连接形成32 为物理地址,如图3-2。这个地址选择了一个四字节的转换表入口,它是第一级描述符或是指向第二级页表的指针。
mmu_2.JPG

3.3 第一级描述符

第一级表的每个入口是一个描述它所关联的1MB 虚拟地址是如何映射的描述符。见表3-1,根据bits[1:0]的组合,有四种可能:
·  如果bits[1:0]==0b00,所关联的地址没有被映射,试图访问他们将产生一
个转换错(fault)。因为他们被硬件忽略,所以软件可以利用这样的描述
符的bits[31:2]做自己的用途。推荐为描述符继续保持正确的访问权限。
·  如果bits[1:0]==0b10,这个入口是它所关联地址的节描述符。见节描述符
和转换节参考中的细节。
·  如果bits[0]==1,这个入口给出粗糙第二级表(bit[1]==0),或精细第二
级表(bit[1]==1)。
每一种类型的表描述了它所关联的1MB 存储区域的映射。粗糙第二级表较小,每个表1KB,每个精细第二级表4KB。然而粗糙第二级表只能映射大页和小页,精细第二级表可以映射大页、小页和微页。
mmu_3.JPG
 
3.4 节描述符和转换节参考
如果第一级描述符是节描述符,那么各个字段有如下的意义:
Bits[1:0] 描述符类型标识(0b10 表示节描述符)
Bits[3:2] 高速缓存和缓冲位
Bits[4] 由具体实现定义
Bits[8:5] 这个描述符控制的节的16 种域之一
Bits[9] 现在没有使用,应该为零
Bits[11:10] 访问控制,见表3-3
Bits[19:12] 现在没有使用,应该为零
Bits[31:20] 节基址,形成物理地址的高12 位
mmu_4.JPG
图3-3 表示了节转换的完整过程。
注:---------------
访问权限必须在物理地址产生之前去检查,检查访问权限的顺序见访问权限一节。
---------------------
3.5 粗糙页表描述符
如果第一级描述符是粗糙页表描述符,那么各个字段有如下的意义:
Bits[1:0] 描述符类型标识(0b01 表示粗糙页表描述符)
Bits[4:2] 由具体实现定义
Bits[8:5] 这个描述符控制的页的16 种域之一
Bits[9] 现在没有使用,应该为零
Bits[31:10] 页表基地址是一个指向第二极粗糙页表的指针,
它给出第二级表访问的基地址。而第二级粗糙页表必须在1KB 边
界对齐。如果从第一级读取到的是二级粗糙页表描述符,那么会
象图3-4 所示执行第二级描述符读取。
mmu_5.JPG
3.6 精细页表描述符
如果第一级描述符是精细页表描述符,那么各个字段有如下的意义:
Bits[1:0] 描述符类型标识(0b11 表示精细页表描述符)
Bits[4:2] 由具体实现定义
Bits[8:5] 这个描述符控制的页的16 种域之一
Bits[11:9] 现在没有使用,应该为零
Bits[31:10] 页表基地址是一个指向第二级精细页表的指针,它给出第二级表
访问的基地址。而第二级精细页表必须在4KB 边界对齐。如果从第
一级读取到的是二级精细页表描述符,那么会象图3-5 所示执行第
二级描述符读取。
mmu_6.JPG
3.7 第二级描述符
每个粗糙第二级表对映着以4KB 为单位的虚拟地址范围市怎么映射的,每个精细第二级表对映着以1KB 为单位的虚拟地址范围市怎么映射的。那些入口是页描述符,他们能够分别描述大于4KB 或1KB 的页。在这种情况下,这个描述符必须被重复足够次,以保证这个页始终使用相同的描述符,不论访问这个页中的哪个虚拟地址。对于一个第二级描述符,有四种可能,由描述符的bits[1:0]选择。见表3-2:
·  如果bits[1:0]==0b00,说关联的虚拟地址没有被映射,任何对这些虚拟地
址的访问将会导致转换错(fault)。软件可以利用这样的描述符的bits[31:2]做自己的用途,因为他们被硬件忽略。推荐为描述符继续保持正确的访问权限。
·  如果bits[1:0]==0b01,这个入口是大页描述符,描述64KB 的虚拟地址。
见转换大页参考。一个大页描述符在精细第二级表中必须被重复64 次,在粗
糙第二级表中必须被重复16 次以保证所有的虚拟地址都被描述。
·  如果bits[1:0]== 0b10,这个入口是小页描述符,描述4KB 的虚拟地址。
见转换小页参考。一个小页描述符在精细第二级表中必须被重复4 次,以保
证所有的虚拟地址都被描述。在粗糙第二级表中只有一个实例。
·  如果bits[1:0]== 0b11,这个入口是微页描述符,描述1KB 的虚拟地址。
见转换微页参考。在精细第二级表中只需要一个微页描述符的实例。微页描
述符不能在粗糙第二级表中出现,如果出现了,结果不可预测。
mmu_7.JPG
大页描述符字段
大页描述符的字段有如下意义:
bits[1:0] 表示描述符的类型
bits[3:2] 高速缓促和缓冲位
bits[11:4] 访问权限位。这些为控制对页的访问。关于这些位的解释见表3-3。
大页被分成4 各子页。
AP0 编码对第一个子页的访问权限。
AP1 编码对第二个子页的访问权限。
AP2 编码对第三个子页的访问权限。
AP3 编码对第四个子页的访问权限。
bits[15:12] 现在没有使用,应该为零。
bits[31:16] 用来形成物理地址的对应位。
小页描述符字段
小页描述符的字段有如下意义:
bits[1:0] 表示描述符的类型
bits[3:2] 高速缓促和缓冲位
bits[11:4] 访问权限位。这些为控制对页的访问。关于这些位的解释见表3-3。
小页被分成4 各子页。
AP0 编码对第一个子页的访问权限。
AP1 编码对第二个子页的访问权限。
AP2 编码对第三个子页的访问权限。
AP3 编码对第四个子页的访问权限。
bits[31:12] 用来形成物理地址的对应位。
微页描述符字段
微页描述符的字段有如下意义:
bits[1:0] 表示描述符的类型
bits[3:2] 高速缓促和缓冲位
bits[5:4] 访问权限位。这些为控制对页的访问。关于这些位的解释见表3-3 关于微页的解释。
bits[9:6] 现在没有使用,应该为零。
bits[31:10] 用来形成物理地址的对应位。
3.8 转换大页参考
图3-6 显示了在粗糙第二级表中转换一个64KB 的大页的完整顺序。在精细第二级表中的转换顺序页相似,只是第二级描述符的地址如精细页表描述符一节所决定。
注:-----------------------------
页索引的高4 位和第二级表的低阶4 位重叠,在粗糙页表中大页的每个页表入口必须被重复16 次。在精细页表中大页的每个页表入口必须被重复64 次。
mmu_8.JPG
-----------------------------------
3.9 转换小页参考
图3-7 显示了在粗糙第二级表中转换一个4KB 的小页的完整顺序。在精细第二级表中的转换顺序页相似,只是第二级描述符的地址如精细页表描述符一节所决定。
注:-----------------------------
当小页出现在精细第二级表中时,页索引的高2 位和第二级表的低阶2 位重叠,在精细页表中小页的每个页表入口必须被重复4 次。
-----------------------------------
mmu_9.JPG
3.10 转换微页索引
图3-8 显示了在精细第二级表中转换1KB 微页的完整过程。
注:---------------------------
微页不能出现在粗糙第二级表中。
---------------------------------
mmu_a.JPG



4域

域是节、大页和小页的集合。ARM 结构支持16 个域。对域的访问由域访问控制寄存器的两个位字段控制。因为每个字段对访问对应的域的使能非常迅速,所以整个存储器区间能很快地交换进出虚拟存储器。这里支持2 种域访问方式:
客户域的用户(执行程序,访问数据),被形成这个域的节或页来监督访问权限。
管理者控制域的行为(域中的当前节和页,对域的访问),不被形成这个域的节或页来监督访问权限。
一个程序可以是一些域的客户,也是另外一些域的管理者,同时没有对其它域的访问权限。这允许对程序访问不同存储器资源的非常灵活的存储器保护。表3-4 说明了域访问控制寄存器的位编码方式。
mmu_b.JPG
5 CP15 寄存器
MMU 由系统控制寄存器的2、3、4、5、6、8、10 号寄存器和1 号寄存器的一些位控制。
5.1 对协处理器寄存器的操作
ARM寄存器到协处理器的数据传诵指令和反向传送指令分别为MCR和MRC
u       MCR
MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。若协处理器不能成功执行该操作,将产生未定义指令异常中断。指令格式如下:
MCR{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}
其中 coproc 指令操作的协处理器的名称,标准名为pn,n为0~15,这里为p15
opcode1 协处理器的特定操作码
Rd      做源的ARM处理器寄存器
CRn     存放第一个操作数的协处理器寄存器
CRm     存放第二个操作数的协处理器寄存器
opcode2 可选的协处理器操作码
指令举例如下:
MCR p6,2,R7,c1,c2
MCR p7,0,R1,c3,c2,1
u       MRC
MRC指令将协处理器的寄存器中的数据传送到ARM理器的寄存器中。若协处理器不能成功执行该操作,将产生未定义指令异常中断。指令格式如下:
MRC{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}
其中 coproc 指令操作的协处理器的名称,标准名为pn,n为0~15,这里为p15
opcode1 协处理器的特定操作码
Rd      做目标的ARM处理器寄存器
CRn     存放第一个操作数的协处理器寄存器
CRm     存放第二个操作数的协处理器寄存器
opcode2 可选的协处理器操作码
指令举例如下:
MRC p6,2,R7,c1,c2
MCR p7,0,R1,c3,c2,1
5.2 寄存器1 的MMU 控制位
寄存器1 的如下这些位用来控制MMU:
M(bit[0]) 使能MMU
0 = 禁止MMU
1 = 允许MMU
在没有MMU 和保护单元的系统上,这个位应该读出为0,并忽略写。
A(bit[1]) 使能对齐错检查
0 = 禁止
1 = 允许
S(bit[8]) 这是系统保护位,见3-4 节。
R(bit[9]) 这是ROM 保护位,见3-4 节。
5.3 寄存器2:转换表基地址
mmu_c.JPG
读CP15 寄存器2 时,在bits[31:14]返回当前活动的第一级转换表的物理地址,bits[13:0]不确定。读CP15 寄存器2 时,CRm 和操作数2 被忽略,并应该是0。写CP15 寄存器2 时,在bits[31:14]更新当前活动的第一级转换表的物理地址,bits[13:0]应该写0 或先前读回的值。写CP15 寄存器2 时,CRm 和操作数2 被忽
略,并应该是0。
5.4 寄存器3:域访问控制
mmu_d.JPG
读CP15 寄存器3 时,返回域访问控制寄存器的值。CRm 和操作数2 被忽略,并应该是0。写CP15 寄存器3 时,更新域访问控制寄存器的值。CRm 和操作数2 被忽略,并应该是0。
域访问控制寄存器包含16 个2 位的字段,它定义了对应域的访问权限。见3-5
节。
5.5 寄存器4:保留
读写CP15 寄存器4 不可预料结果。
5.6 寄存器5:错误状态 FSR
mmu_e.JPG
读CP15 寄存器5 时,返回FSR 寄存器的值。FSR 包含最近一次数据错的信息。只有低9 位有效,高23 位不确定。FSR 指出异常发生时的域和试图访问的类型。
bit[8] 返回0
bit[7:4] 指出错位发生时访问的域
bit[3:0] 试图访问的类型,这些位的编码见表3-5
FSR 在数据错时更新。由具体实现确定取指令异常是否更新FSR。见3.6.2 节的
“错误地址寄存器(FAR)和错误状态寄存器(FSR)”。CRm 和操作数2 被忽略,并应
该是0。写FSR 将把FSR 设定成写的值。这对于程序调试器非常有用,可以用来恢复FSR 的值。高24 位应该写0 或上次读到的值。CRm 和操作数2 被忽略,并应该是0。
5.7 寄存器6:错误地址 FAR
mmu_f.JPG
读CP15 寄存器6 返回FAR 的值。FAR 保存着错误产生时访问的虚拟地址。在数据错时更新FAR。由具体实现确定取指令异常是否更新FSR。见3.6.2 节的“错误地
址寄存器(FAR)和错误状态寄存器(FSR)”。CRm 和操作数2 被忽略,并应该是0。写FSR 将把FAR 设定成写的值。这对于程序调试器非常有用,可以用来恢复FAR 的
值。高24 位应该写0 或上次读到的值。CRm 和操作数2 被忽略,并应该是0。
---注------
如果使用了第六章描述的快速上下文切换扩展(FCSE),那么:
·  当存储器错更新FAR 时,写入FAR 的是修改的虚拟地址。
·  当用MRC 指令读或用MCR 指令写FAR 时,它的值被当作数据对待,所以没有由FCSE 产生的地址修改。
------------
5.8 寄存器8:TLB 功能
当CP15 的寄存器8 用来控制TLB 时是只读寄存器。表3-6 显示了定义的TLB 功能和在MCR 指令中用的CRm 和第二个朝操作数<opcode2>的值。使用没有在表中的
CRm 和opcode2 的组合将导致不可预料的结果。
如果下面的任何操作被用在单一TLB 的实现中,则在单一TLB 中实现相同的功能:
·  无效的指令TLB (Invalidate instruction TLB)
·  无效的指令单一入口 (Invalidate instruction single entry)
·  无效的整个数据TLB (Invalidate entire data TLB)
·  无效的数据单一入口 (Invalidate data single entry)
否则,如果执行一个与特定实现不相关的功能,会导致不确定的结果。试图用MRC 指令读CP15 寄存器8 的结果不确定。当只有很少量的存储器被重新映射时,无效的单一入口操作能被用来在一些实现中改善性能。对每个被重新映射的存储器区域(节、小页或大页),无效的单一入口需要在存储器区域的虚拟地址上执行。性能的改善来源于不用重新装载与没有被重新映射的存储器区域相关的TLB 入口。
---注------
无效的单一入口操作的性能改善并不被保证。具体实现可以是单一请求入口无效,直到使整个TLB 无效。
-----------
---小心------
当存储器被重新映射时必须使与旧的映射相关的TLB 入口无效。如果不这样,可能会进入两个TLB 入口覆盖虚拟地址范围的状态。在最好的情况下访问这样的覆盖虚拟地址范围会有不可预料的结果;在某些实现中甚至会物理损坏MMU。强烈建议在重新映射存储器时要加倍小心使TLB 适当地失效。
------------
mmu_g.JPG
---注------
如果使用了第六章描述的快速上下文切换扩展(FCSE),那么表3-6 中的一些功
能传递给CP15 的虚拟地址被当作数据。这意味着对它们来说没有由FCSE 产生
的地址修改。
------------
5.9 寄存器10:TLB 锁定
转换表遍历的执行需要一定的时间,特别当访问慢速的主存储器时。在实时中断处理程序中,当TLB 不包含中断处理程序的转换和/或要访问的数据时,中断延迟回大量加长。
TLB 锁定是一些ARM 存储器系统的特性,它允许把特定的转换表遍历的结果装载到TLB 中。这种方式不会被后来的转换表遍历的结果覆盖。由CP15 寄存器10 设定。设 W=LOG2(TLB 入口数),如果需要的话取整(round-up),则CP15 寄存器10 的格式为:mmu_h.JPG

如果具体的实现有分开的指令和数据TLB,那么有2 个不同的寄存器,由访问寄存器10 的MCR 或MRC 指令中的opcode2 字段选择:
opcode2 == 0 选择数据TLB 锁定寄存器
opcode2 == 1 选择指令TLB 锁定寄存器
如果具体的实现只有唯一的TLB,那么只有1 个寄存器,opcode2 字段应该为0。访问寄存器10 的MCR 或MRC 指令中的CRm 总应该为0。
写寄存器10 有如下结果:
victim 字段表示下次TLB 失败(miss)时,转换表遍历的结果替代哪个TLB 入口。Base 字段包含TLB 替换的策略,只使用从(base)到(TLB 入口-1)的TLB 入口,
victim 应该在这个区间。
转换表遍历的结果在写到TLB 入口时,若P==1 则它被保护起来,不能被寄存器8的使整个TLB 失效操作影响;若P==0 则会被那些操作给失效掉。
---注------
如果TLB 的入口不是2 的N 次方,那么写到大于或等于TLB 入口数的TLB 入口的base 或victim 的值将不确定。
-----------
读寄存器10 将返回它的值。
TLB 锁定过程
通常锁定N 个TLB 入口的过程如下:
1. 禁止中断等,来保证当这个过程执行时不会产生异常
2. 如果一个指令TLB 或唯一TLB 被锁定,用base==N、index==N 和P==0 写到适当版本的寄存器10。如果可能,把另指令预取很难理解的分枝预测功能关掉。
3. 使要被锁定的整个TLB 失效。
4. 如果是指令TLB 锁定,要确保剩下的锁定过程所要预取的指令相关的TLB 入口都被装载。(要注意锁定是从哪里开始的,通常可能一个TLB 入口包含所有这些。这时TLB 被失效后的第一条指令能完成这个功能)如果是数据TLB 锁定,要确保剩下的锁定过程所要访问数据的相关的TLB 入口都被装载。这包含被代码用到的嵌入文字(inline literals)(通常最好避免在锁定过程中使用嵌入文字,并把所有的数据放在由一个TLB 入口所包含的区域,然后从那里加载一个数据)如果一个唯一TLB 被锁定,执行以上所有的过程。
5. i 从0 到N-1 循环
a. 用base==i、index==i 和P==1 写到寄存器10。
b. 强迫被锁定到TLB 入口i 处的转换表遍历结果的存储器区域发生转换表遍历:
* 如果是数据TLB 或唯一TLB 被锁定,从那个区域加载一个数据
* 如果是指令TLB 被锁定,用B5-15 页所描述的指令预取高速缓冲寄存器7 来在那个区域产生指令预取。
6. 用base==N、index==N 和P==0 写到寄存器10。
---注------
如果你使用FCSE,要注意第5b 步,因为:
·  如果是数据TLB 锁定或唯一TLB 锁定,加载数据指令的地址是会被FCSE 修改的。
·  如果是指令TLB 锁定,用在寄存器7 的地址被当作数据,所以不会被FCSE 修改。
为了减少混淆,建议锁定过程应该是:
·  从禁止FCSE 开始(设置PID 为0)
·  把适当的PID 值OR 到使用的虚拟地址的高7 位来自己产生修改的虚拟地址。
-----------
TLB 解锁过程
用上面的过程解锁被锁定的TLB 部分:
1. 用寄存器8 的操作使每个被锁定的单一入口失效
2. 用base==0、index==0 和P==0 写到寄存器10。
---注------
第一步是为了保证P==1 的入口在TLB 中不在被剩下。如故它们被剩在TLB 中,后续的TLB 锁定过程中使整个TLB 失效(第三步)将不会有预期的结果。
-----------
参考文献:
宛城布衣《ARM常见指令集合》
无名氏    〈ARM Architecture Reference Manual〉部分中译

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

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

相关文章

__ATTRIBUTE__ 你知多少?

_ATTRIBUTE__ 你知多少&#xff1f; 1 #include "stdio.h"2 3 /* 地址参考基准 */4 5 char r1;6 short r2;int refer;7 8 struct p9 { 10 int a; 11 12 char b; 13 14 short c; 15 16 }__attribute__((aligned(4))) pp; 17 /* 4字节对齐&#xff0c;a…

oracle 根据分隔符提取,oracle自定义函数按照某个分隔符拆分字符串

1.首先需要定义一个集合类型&#xff0c;我这里定义的是变长数组类型(VARRAY)create type type_splitstr is varray(1024) of varchar2(128);--注意&#xff0c;我这里之所以不用嵌套表类型(NESTED TABLE)&#xff0c;是因为oracle官方文档有如下说明。--Nested Tables: The in…

跟几位大佬共进晚餐

这是一篇几个程序员大佬聚会的聚后感文章这次聚会比较唐突&#xff0c;连总从广州专门开车来深圳看望我们&#xff0c;我们约在了某个地铁站的八合里牛肉火锅店&#xff0c;这是一个周五的下午&#xff0c;理论上是非常简单的一个周五&#xff0c;但是因为这些男人女人的存在&a…

vue.js框架搭建

安装脚手架 前提条件&#xff1a;已安装node&#xff08;4.0版本以上&#xff09;&#xff0c;npm a、全局安装 vue-cli npm install -g vue-cli 安装成功后可以通过命令行查看版本号&#xff0c;如图 b、初始化项目 新建一个文件夹命名为01vue&#xff0c;准备在此文件夹下存放…

oracle数据库imp导入,imp 导入 没有数据库

IMP-00009: 导出文件异常结束今天准备从生产库向测试库进行数据导入&#xff0c;结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误&#xff0c;google一下&#xff0c;发现可能有如下原因导致imp的数据太大&#xff0c;没有写buffer和commit两个数据库字符集不同从…

MIK C语言面试两题

这是一个读者朋友在知识星球上提到的两个笔试题&#xff0c;第一个题目比较简单&#xff0c;关键在第二个题目「编程题」&#xff0c;我文章中写的解题思路应该不是最好的&#xff0c;希望大神读者们给出更好的答案&#xff0c;让这个充满乐趣的程序世界再增添一些乐趣吧&#…

[听尉迟方侃侃]平台

很长一段时期我都不能理解什么叫做平台。这个平台那个平台&#xff0c;随随便便的东西都要带上“平台”两个字以期蓬荜生辉。搞得人很是反感。 查了一下金山词霸&#xff0c;对平台一词有两个解释和软件行业相关&#xff1a; 解释1、[platform] ∶ 通常高于附近区域的平…

Swift基础学习(二)数据类型

在编程语言中&#xff0c;不同的数据信息需要不同的数据类型来存储&#xff0c;计算机内存中针对不同的数据类型它们所分配的内存大小是不同的&#xff0c;特定的值需要特定的类型来声明。 Swift 数据类型 内置数据类型 整数 - Int & UInt 根据一个整数变量占据的内存空间&…

看看大疆的C语言面试题

惯例&#xff0c;这笔试题也是一个读者朋友发给我的&#xff0c;简单看了下&#xff0c;并不觉得这是一个非常困难的题目&#xff0c;最近是校招准备的时候&#xff0c;很多人给我说发面试题对大家有帮助。这个题目面试官强调了这个跑在64位系统下。代码如下:#define mal(x,y) …

php三级栏目调用,织梦当前栏目调用二级、三级栏目且栏目高亮解决方法

在处理企业站的时候&#xff0c;经常发现要调用二三级栏目栏目&#xff0c;且需要高亮显示&#xff0c;具体实现方法如下。1、打开 \include\taglib\channelartlist.lib.php 找到$tpsql " reid$typeid AND ispart<>2 AND ishidden<>1 ";改成if($typeson…

RocketMQ实战(一)

阿里巴巴有2大核心的分布式技术&#xff0c;一个是OceanBase&#xff0c;另一个就是RocketMQ。在实际项目中已经领教过RocketMQ的强大&#xff0c;本人计划写一个RocketMQ实战系列&#xff0c;将涵盖RocketMQ的简介&#xff0c;环境搭建&#xff0c;初步使用、API详解、架构分析…

C面试总结文档

最近很多人有参加面试&#xff0c;面试就避免不了笔试&#xff0c;嵌入式面试的话&#xff0c;避免不了C语言&#xff0c;所以给大家准备了两份pdf C语言面试总结的文档。在本公众号回复 「C面试」获取pdf下载链接推荐阅读&#xff1a;专辑|Linux文章汇总专辑|程序人生专辑|C语…

linux下根据端口查进程,linux根据进程查端口,根据端口查进程

[roottest_environment src]# netstat -tnllup 能显示对应端口和进程Active Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemdtcp 0 0 0.0.0.0:6000 0.0.0.0:*…

程序员到底怎么了

我们是这样的一群人&#xff1a;每天都在“努力”的工作着&#xff0c;每天都和计算机打交道&#xff0c;泡在网上&#xff0c;打游戏&#xff0c;查资料&#xff0c;发微博。可是有一天&#xff0c;突然意识到&#xff0c;我们的未来在哪里&#xff0c;每个月那点可怜的工资&a…

SQLServer查询表结构

SELECT 表名case when a.colorder1 then d.name else end, 表说明case when a.colorder1 then isnull(f.value,) else end, 字段序号a.colorder, 字段名a.name, 标识case when COLUMNPROPERTY( a.id,a.name,IsIdentity)1 then √else end, 主键case when exists(SELECT 1 F…

来看看比尔盖茨当年写的BASIC解释器源代码吧,你就知道泰勒级数有什么用了...

几年前当我刚上大学那会&#xff0c;我曾经问过我一位学计算机同学的一个问题&#xff1a;计算机是如何计算诸如 或者 这种运算的&#xff1f;当初这个问题曾经困扰了我好长时间&#xff0c;这个问题并非是我当年在微积分课堂上解决的&#xff0c;而是直到我后来接触编程后才彻…

linux查看进程ppid,pidof命令从运行的进程中以名称查找出进程号PID/PPID横向大到小展示...

1.释义从运行的进程中以名称查找出进程号PID/PPID横向大到小展示2.系统帮助PIDOF(8) Linux System Administrators Manual PIDOF(8)NAMEpidof -- find the process ID of a running program.SYNOPSISSYNOPSISpidof [-s] [-c] [-n] [-x] [-m] [-o omitpid[,omitpid..]] [-o omit…

语言的本地化支持

Support channels on IRC and mailing lists exist for Ubuntu users whose first language is not English. You are welcome to join one of these or start your own. 对于母语不是英语的Ubuntu用户来说&#xff0c;已经有相应的邮件列表和IRC频道提供支持。欢迎你加入它们…

手机可以连接多少个蓝牙设备?

这是一个课题研究&#xff0c;蓝牙的东西我们可以先不说&#xff0c;我们讨论一个产品需求。我经常遇到一个场景&#xff0c;就是我用我的手机连上TWS蓝牙耳机听音乐&#xff0c;然后呢&#xff0c;我没有开车&#xff0c;我下地铁的时候&#xff0c;我需要打开我的手机&#x…

Spring简洁总结

Spring简洁总结 要的对象不是自己建的&#xff0c;而是IOC容器&#xff08;XML文件&#xff09;给的&#xff0c;我们通过getbean来调用。 依赖注入的话就是对象&#xff08;bean&#xff09;的成员的赋值不是我们手动完成&#xff0c;而是容器&#xff08;XML文件&#xff09;…