Advertisement

UBOOT阶段cache研究

阅读量:

文章目录

  • UBoot启用缓存可行性分析

    • 在UBoot启动过程中为何需要禁用MMU和缓存机制?
      • 关于现代处理器中的寄存器管理机制(MMU)

        • MMU的基本应用方法
      • 探讨现代处理器中的地址转换机制(Address Translation Mechanism)

      • 分析禁用-MMU的理由与影响

        • 1.2 、关于cache
          • 1.2.1、cache的用法
      • 1.2.2、关闭cache的原因

  • 2、是否支持缓存的开启

  • 3、在uboot阶段进行缓存与内存同步的必要性

    • 3.1、缓存机制采用两种不同的策略
      • 3.1.1、Write-Through mechanism
  • Write-Back strategy

    复制代码
    * 3.2、uboot执行的策略以及是否需要cache同步
    • 4、当前存在的问题

uboot enable cache可行性研究

1、为何uboot开始要关闭mmu与cache

要知道为什么关闭这两个硬件,首先要了解这两个硬件的作用。

1.1 关于MMU

1.1.1、MMU简单用法

MMU的作用是实现虚拟地址与物理地址之间的转换过程。它作为一个专用硬件设备,在CP15协处理器中能够完成相关功能设置。MMU通过读取相应的TTB信息来确定页表的位置。其中记录了内存地址与物理内存对应关系的数据存储在页表中。创建页表的具体代码如下:

复制代码
    #define GPMCON (volatile unsigned long *)0xA0008820  //虚拟地址
    #define GPMDAT (volatile unsigned long *)0xA0008824 
    
    #define MMU_FULL_ACCESS     (3 << 10)   /* 访问权限 [11:10]*/
    #define MMU_DOMAIN          (0 << 5)    /* 属于哪个域 [8:5]*/
    #define MMU_SPECIAL         (1 << 4)    /* 必须是1 [4]*/
    #define MMU_CACHEABLE       (1 << 3)    /* cacheable  [3]*/
    #define MMU_BUFFERABLE      (1 << 2)    /* bufferable [2]*/
    #define MMU_SECTION         (2)         /* 表示这是段描述符  [1:0]*/
    #define MMU_SECDESC         (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)
    #define MMU_SECDESC_WB      (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)
    
    void creat_page_table()
    {
    unsigned long *ttb = (unsigned long *)0x50000000; //表在内存的基地址处
    unsigned long vaddr; //虚拟地址
    unsigned long paddr; //物理地址
    
    vaddr = 0xa0000000; //虚拟地址
    paddr = 0x7F000000;
    *(ttb + (vaddr >> 20)) = (paddr&0xfff00000) | MMU_SECDESC;
    //*(ttb + (vaddr >> 20))  为表项的位置 
    //(paddr&0xfff00000) 获取高12位数据
    //MMU_SECDESC  访问led的gpio很简单,就不需要cache和buffer
    
    //映射内存
    vaddr = 0x50000000;
    paddr = 0x50000000;  //其虚拟地址和物理地址是一致的
    while (vaddr < 0x54000000)  //映射64mb
    {
        *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC_WB;
        vaddr += 0x100000;
        paddr += 0x100000;
    }   
    
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/uDv03fNPR7GEw8mOdXJyQzYlSKn2.png)

采用MVA[31:20]作为索引基址定位到一级页表(其中2^{(31-20)}=4096),从而获取相应的描述符信息;每一个这样的描述符占用4个字节的空间;每一个这样的描述符负责对应1\text{ MB}的虚拟内存地址;每一个这样的描述符要么用于记录其对应的1\text{ MB}物理内存起始地址;要么用于记录下一层级页表的相关信息

复制代码
    vaddr = 0xa0000000; //虚拟地址
    paddr = 0x7F000000;
    *(ttb + (vaddr >> 20)) = (paddr&0xfff00000) | MMU_SECDESC;
    
    
    c

这表明上述代码已经完成了1M虚拟地址的映射。假设有一个物理地址为XA7F23456789ABCDEF在进行虚拟化处理后将被转换为对应的内存位址XB3CDEFGHIJKLMTYVFR。所有访问请求指向的内存地址可以通过硬件进行解密映射到相应的物理内存位置。

1.1.2 、MMU的地址转换法

第一步将来自CPU内核的32位虚拟地址空间(Va)值 Va[31:0]划分为三部分 其中前两部分分别为 Va[31:20] 和 Va[19:12] 这两者分别用于两次查找表的操作 最后一部分 Va[11:0] 则用于表示页内偏移量 查找过程的具体步骤如下所述

image-20200525160411425

从协处理器CP15的寄存器2(TTB寄存器, Translation Table Base Register)中读取存储于其中的第一级页表(Translation Table)的基准地址。该基准地址即为PA(Page Address),表示页表直接按此地址存储于物理内存中。
基于TTB的内容作为基准地址,并以VA[31:20]作为索引来一级页表查找一项(共4096项)。该页表项(亦即描述符, Descriptor)记录着二级页表(Coarse Page Table)的基准地址。此基准地址同样为物理内存中的直接存储位置。
基于VA[19:12]作为索引在二级页表中查找一项(共256项)。此记录中所保存的就是物理页面基准地址。虚拟内存管理基于页面单位运作这一事实可于此可见一斑:因为查找操作是以页面单位进行的。
获得了物理页面基准地址后,在其基础上加上VA[11:0]偏移量(相当于4KB)即可获取所需数据。
这一过程被称为Translation Table Walk:从TTB依次走到一级页表、二级页表直至物理页面——每一次寻址实际上都是三次访问物理内存的操作。
值得注意的是这一'走'的过程完全是硬件完成的:每当CPU执行一次寻址指令时MMU都会自动完成上述四步操作的前提条件是操作系统必须维护正确的页表项:每次分配内存时需填入相应的页表项;每次释放内存时需清除相应项;必要时需动态分配或释放整个页表。

以下是二级页表处理流程说明:当仅采用一级页表时,其存储内容即为直接对应的物理基址信息。这些基址能够覆盖1M的空间范围。通过将一级页表中记录的[31:20]字段与输入的有效地址中的[20:0]字段进行组合计算,则可获得对应的物理地址值。

1.1.3 、关闭MMU原因

通过分析可知MMU的主要功能是实现虚拟地址映射。这种机制使得数据读取更加便捷。值得注意的是,在启动过程中的初期阶段,在处理物理内存时直接使用实际物理地址。具体而言,在启动过程中尚未完成初始化流程的情况下,在处理物理内存时直接使用实际物理地址。

在uboot阶段对内存的管理较为宽松,在这种情况下允许对各类物理地址进行较为自由地利用因此无需进行地址映射操作。该阶段所需的物理内存资源相对较少,并且同样无需引入虚拟地址以扩展可用空间

1.2 、关于cache

1.2.1、cache的用法

缓存主要用于提升数据访问速度。它位于CPU与DDR之间,并能够存储频繁使用的指令和数据。从而使得CPU能够更快地执行指令。

Cache可分为两种类型:ICache和DCache。通常情况下,在机器学习框架中仅禁用了DCache,并保留了ICache

icache是存储一些常用的指令,方便CPU直接调用。dcache是存储数据。

dcache是CPU用于存储常用的数据于DCache中,并非必须从DDR访问。除非DCache中已存在相应数据,则无需从DDR访问。这些操作均由硬件自动执行。

1.2.2、关闭cache的原因

有些人认为关闭缓存是为了防止DDR中的数据与缓存不一致而导致数据错误;然而这一说法实际上是不正确的;实际上UBOOT采用的是直写策略,在这种情况下不会出现这个问题

主要问题是MLO阶段中的DDR尚未完成正常初始化若采用dcache则需与MMU协同工作当MMU无法正常运行时 cache也不会被激活当CPU访问dcake时会通过MMU执行地址转换以定位所需数据其访问机制直接影响到数据在缓存中的存储位置

2、是否可以打开cache

基于以上分析,在uboot环境中完成DDR初始化后,我们完全能够充分开启MMU以及DCache,并且这将不会产生负面效果。

3、是否需要在uboot阶段将cache与内存同步

3.1、cache的两种策略

3.1.1、 Write-Through

最简单的写入策略被称为"Write-Through"( Write-Through)。在这一策略下,在每次处理数据时都会将其直接写入到主内存中。在执行此操作前会先检查数据是否已经存在于Cache中:如果存在,则先将数据更新至Cache中再进行主内存写入;如果不存在,则仅进行主内存更新。
Write-Through策略直观易懂但存在明显缺陷:不管数据是否存在Cache中,在每次处理时都需要进行主内存写入操作。这与前面提到使用volatile关键字的做法类似。

该策略直接将数据存储在内存中,并在数据发生变化时则必须立即存入内存以避免延迟。

3.1.2、 Write-Back

写回策略的具体实施步骤如下:

首先识别目标存储位置:如果发现目标存储位置(CPU Cache)已经存在相应数据,则仅做以下操作:替换该存储位置中的现有数据,并将其标记为"脏"状态(Dirty)。所谓"脏"状态即表示此时CPU Cache中的该存储区域与主存存在不一致性。

如果目标存储位置(对应的Cache块)存放的是另一条主存地址中的数据,则需执行以下操作:

a) 首先检查该Cache块是否已标记为"脏"状态(Dirty)。如果是,则无需进一步操作;

b) 如果未被标记为"脏"状态(Dirty),则必须先将该Cache块中的原始数据复制到主存中以保证一致性;

c) 接着将当前准备插入的数据替换为主存中的对应值,并将其放置于相应的Cache块中;

d) 最后重新将该Cache块标记为"脏"状态(Dirty),以反映其与主存已存在差异。

这种缓存机制其实是在数据插入完成后被存储于缓存中,在没有进一步操作的情况下直接被使用。当CPU在准备进行下一次数据插入时会检查该缓存部分是否存在尚未处理的数据。如果有的话就会触发回写操作以确保数据完整性。

3.2、uboot执行的策略以及是否需要cache同步

uboot运行的是内存直写策略。尽管会带来一定的访问速度损失……但能够确保所有数据都正确地被写入到内存中而不是存在于缓存中与实际运行时的内存状态存在不一致的情况……因此无需进行缓存同步操作

同步操作在系统中主要基于这一原则:即需要将位于内存和缓存中的数据转移至硬盘。与uboot中的cache缓存机制存在显著差异,在进行烧录操作时,该系统需要完成针对NAND闪存的 writes.只有完成所有必要的 write operations后才能终止该过程;其独特之处在于无需在内存或闪存中留下剩余的 cache data.

4、当前存在的问题

现在存在的问题是尚未找到具体的相关关于"cache是如何访问的"资料, cache如何查找数据已知的方式.

然而,在cache被查找时进行地址解析的任务是由MMU完成的吗?目前的研究中缺乏可靠的数据支持。

推测是MMU完成的,因为打开dcache时,必须要打开MMU才可以。

此外,在缓存数据获取过程中与页表查找机制具有相似性。该过程通过获取内存地址并计算偏移量来确定起始位置;最终可定位所需数据的具体位置。

全部评论 (0)

还没有任何评论哟~