我想启用数据缓存。我对ARM没有太多的经验,因为我大多是为IA32编程的。我的理解是,我需要启用mmu来启用数据缓存。因为我不需要虚拟内存,所以我想为所有应用程序启用物理和虚拟地址空间之间的一对一映射的mmu。
欢迎使用任何帮助/指针/文章或代码。
最佳答案
可以使用以下(未测试)代码创建包含一对一虚拟/物理映射的16K页目录:
/* Setup types for virtual addresses, physical address, and the page table. */
typedef unsigned long vaddr_t;
typedef unsigned long paddr_t;
typedef unsigned long pde_t;
/* Reserve space for a page directory. Must be 16k aligned. */
pde_t page_directory[1 << 12] ALIGNED(1 << 12);
/* Create a 1MB mapping in the given page directory from 'virt' to 'phys'. */
void set_large_page_mapping(pde_t *pd, vaddr_t virt, paddr_t phys)
{
pde_t entry = 0;
entry |= phys & 0xfff00000; /* Target of the mapping. */
entry |= 2; /* This is a 1MB section entry. */
entry |= 1 << 4; /* Enable caches (C). */
entry |= 1 << 3; /* Enable writeback (B). */
entry |= 3 << 10; /* Full read/write permission. */
pd[virt >> 20] = entry; /* Install the entry. */
}
/* Setup a page directory with one-to-one physical/virtual mappings. */
void setup_one_to_one_mappings(void)
{
unsigned long i;
/* Setup a mapping for each 1MB region in the virtual address space. */
for (i = 0; i < (1 << 12); i++) {
/* Map the virtual address "i << 20" to phys address "i << 20". */
set_large_page_mapping(page_directory, i << 20, i << 20);
}
/* TODO: Write function to install this page directory and enable the MMU. */
enable_mmu(page_directory);
}
enable_mmu
函数仍然需要编写,它需要:干净的数据和指令缓存;
现有的TLB条目无效;
刷新其他缓存(预取缓冲区、分支目标缓存等);
设置ttbr0以包含指向上面生成的pd的指针;最后
启用缓存和mmu。
这些指令往往都是特定于cpu的,但是示例应该(希望)可用于其他地方的硬件(或者,如果失败,可以通过查看其他操作系统的源代码,例如linux或freebsd)。另外,对于测试,您可能只需要担心最后两点就可以开始了。