嵌入式linux------MMU和Cache

2019-07-12 19:17发布

内存管理单元(MMU)负责虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。现代多用户多进程操作系统通过MMU使得各个用户进程都拥有自己独立的地址空间:地址映射使得各进程拥有看起来一样的地址空间,内存访问权限的检查可以保护每个进程所用的内存不会被其他进程破坏。 虚拟存储器在逻辑上对内存容量进行扩充,给人们一种内存很大的假象。虚拟地址范围是0~0xFFFFFFFF,这个地址范围称为虚拟地址空间,对应着真实的物理地址空间,物理内存,这是真正的内存。 ARM CPU上地址转换涉及3个概念:虚拟地址VA、转换后的虚拟地址MVA、物理地址PA。 1. 没有启动MMU前,CPU核、cache、MMU、外设等所有部件使用的都是物理地址。 2. 启动MMU后,CPU核对外发出虚拟地址VA;VA被转换为MVA供cache、MMU使用,然后他们将MVA转换为PA,最后使用PA读写实际设备(寄存器或外设)。 TLB(转义查找缓存)是一个存储器,用来帮助快速的进行地址转换。在程序执行过程中,所用到的指令、数据的地址往往集中在一个很小的范围内,其中的地址、数据经常多次使用,这称为程序访问的局部性。因此采用一个高速、容量较小的存储器来存储近期用的页表条目,避免每次地址转换都到主存上去查,大幅提高性能。 TLB使用过程:
  • CPU发出一个虚拟地址,MMU首先访问TLB。
  • TLB中如果有能转换这个虚拟地址的描述符,则直接使用描述符进行地址转换和权限检查。
  • 否则TLB没有能转换这个虚拟地址的描述符,MMU只能去访问页表找到描述符后再进行地址转换和权限检查,并将这个描述符填入TLB,如果TLB满了则使用round-robin算法踢出一个条目覆盖之。
补充:页表的首地址存放在页表基址寄存器,简称PTBR,是存放在内存中的一种特殊数据结构,放在系统空间的页表区,存放虚拟地址和物理地址的一一对应关系,每个进程都有自己的页表,PCB(一种数据结构,为了描述控制进程的运行而用来存放进程的管理控制信息,它是进程实体的一部分,是操作系统中最重要的记录性数据结构,每个进程均有一个PCB,在创建进程时,建立PCB,伴随进程运行全过程,直到进程撤销)中有指针指向页表。 注意:注意保持TLB中内容与页表一致。在启动MMU之前,使无效整个TLB,改变页表时,使无效所涉及的虚拟地址对应的TLB中的条目。 Cache... SDRAM:同步动态随机存储器,同步是指内存工作需要同步时钟,内部命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断的刷新来保证数据不丢失;随机是指数据不是线性依次存储,而是自由指定地址进行数据读写。                                          CPU读取SDRAM中存储的程序或指令的内部过程(局部性原理):
  1. 假设读取SDRAM地址A的数据,ldr r0, [A]
  2. CPU首先会以地址A查找Cache,一开始Cache中没有任何数据导致查询失败,这种情况叫Cache miss
  3. CPU转而把地址A发到SDRAM,然后找到A,此时不会返回地址A的数据但是会返回一个Cache line,一般是8 word,32byte,结果就是一下从内存中读入Cache line到Cache中,这个过程叫Cache fill。
  4. 程序再次读取地址A的数据时,CPU依然去Cache中查找并找到,这叫Cache hit,直接从Cache返回数据给CPU。
  5. 程序读地址B,A和B是几乎相邻的地址,在刚才Cache fill过程中,B也被加入到了cache中,因此也是Cache命中,返回给CPU。
  6. Cache满了,CPU访问一个新的地址会导致新数据的Cache line(新地址周边的数据)
Cache的写数据Write buffer配置,设置某块内存的cache和buffer,存在于S3C2410,参考下表:                                          
  1. 设置某块内存NCNB,即No Cache和No Buffer,cpu的指令会直接到达硬件,直接读取硬件上的数据,因此GPIO寄存器就要使用这个状态,CPU在读GPDAT寄存器时,想得到外部引脚状态,不该从cache中读取老的状态数据,因此读写的时候都是直接操作硬件,不要缓存的数据。
  2. No Cache Buffer,不使用cache但是使用buffer,读和写的时候都不使用cache,直接操作到硬件;而在写的时候可写入buffer,然后cpu直接去执行下一条指令,buffer再执行写入主存的缓慢的操作。
  3. Cache,write through写通,使用cache但是不使用write buffer,读的时候会优先使用cache中的数据,如果cache中有数据会优先从cache中返回数据,如果cache中没有数据会导致cache line fill写入一行。所有的写操作都是先写入write buffer,这些数据同时会马上写到硬件上去,而cpu把数据写给write buffer之后就会马上执行下一条指令,并不等待写操作完成。
  4. Cache write back写回,读的时候优先使用cache读取数据,如果cache miss会导致line fill。而写的时候分两种情况:1. 写的时候cache miss,cpu的数据会直接写入write buffer,write buffer直接写入硬件,cpu并不等待写硬件操作完成,而是直接执行下一条指令。2.如果写操作时cache 命中的话,cpu在cache中将数据标记一下dirty,在以后的合适时机(比如cache 替换时或者人为通过指令强制Flash cache)会写入write buffer,然后写入硬件。
协处理器: 对于ARM芯片,里面除了有主芯片CPU以外,还有很多协处理器,协处理器协助主处理器完成某些功能,ARM9有CP0到CP15总共16个协处理器,CP15用来管理Cache和MMU,如果要把主CPU中寄存器的数据发送到CP15协处理器的某个寄存器内,或者从协处理器的某个寄存器中读出数据,就需要使用mrc和mcr指令。mov r1, r0的意思是r0的值传给R1;mrc中的c代表coprocessor,mrc是从协处理器中读数据给CPU的寄存器,mcr就是把主CPU中寄存器的值写给协处理器,下边格式示例: {cond} p#,,Rd,cn,cm{,expression2} mcr P15,0,r1,c1,c0,0              这句话的作用是将主CPU的r1寄存器内容写入协处理器15的c1寄存器中,其中P15是协处理器,expression1经常写为0,r1是主CPU的寄存器,c1是协处理器P15的寄存器,最后两个参数不常用到写为c0,0用来区分是哪一个c1 mrc P15,0,r1,c1,c0,0              作用把协处理器CP15寄存器c1的内容写入到主CPU的r1寄存器中