首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使ARM1136JFS (ARM v6)内存管理单元在物理地址空间和虚拟地址空间之间具有一对一的映射?

如何使ARM1136JFS (ARM v6)内存管理单元在物理地址空间和虚拟地址空间之间具有一对一的映射?
EN

Stack Overflow用户
提问于 2010-08-09 19:54:22
回答 4查看 2.7K关注 0票数 3

我想启用数据缓存。我没有太多的ARM经验,因为我主要是为IA32编程。我的理解是,我需要启用MMU才能启用数据缓存。因为我不需要虚拟内存,所以我希望为所有应用程序启用物理和虚拟地址空间之间的MMU一对一映射。

欢迎任何帮助/指针/文章或代码。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-04-27 14:23:01

下面给出了在物理和虚拟地址空间之间启用一对一映射的代码:

代码语言:javascript
复制
#define NUM_PAGE_TABLE_ENTRIES 4096 /* 1 entry per 1MB, so this covers 4G address space */
#define CACHE_DISABLED    0x12
#define SDRAM_START       0x80000000
#define SDRAM_END         0x8fffffff
#define CACHE_WRITEBACK   0x1e

static inline void enable_mmu(void)
{
    static U32 __attribute__((aligned(16384))) page_table[NUM_PAGE_TABLE_ENTRIES];
    int i;
    U32 reg;

    /* Set up an identity-mapping for all 4GB, rw for everyone */
    for (i = 0; i < NUM_PAGE_TABLE_ENTRIES; i++)
        page_table[i] = i << 20 | (3 << 10) | CACHE_DISABLED;
    /* Then, enable cacheable and bufferable for RAM only */
    for (i = SDRAM_START >> 20; i < SDRAM_END >> 20; i++)
    {
        page_table[i] = i << 20 | (3 << 10) | CACHE_WRITEBACK;
    }

    /* Copy the page table address to cp15 */
    asm volatile("mcr p15, 0, %0, c2, c0, 0"
            : : "r" (page_table) : "memory");
    /* Set the access control to all-supervisor */
    asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (~0));

    /* Enable the MMU */
    asm("mrc p15, 0, %0, c1, c0, 0" : "=r" (reg) : : "cc");
    reg|=0x1
    asm volatile("mcr p15, 0, %0, c1, c0, 0" : : "r" (reg) : "cc");
}
票数 3
EN

Stack Overflow用户

发布于 2010-08-11 05:23:35

欢迎你尝试这样的东西(见下文)。我想做同样的事情,启用数据缓存,并进行一对一。一些工具、文档和代码可能会使问题变得过于复杂。您需要来自arm的核心中特定mmu的trm和/或核心的数据表,无论mmu记录在何处。

我使用的是一个mpcore,它很可能与你所拥有的很相似,arm11也足够类似于arm9。mpcore有一些新的大块表条目,它比下一个大16倍,但这完全是浪费,因为您必须在mmu表中放置相同条目的16个副本。

您需要一块ram来保存mmu表,您需要在表中为该ram块的物理地址放置一个条目,这是它可能查找的第一个条目,在mmu表中查找mmu表之类的东西。同样,中断向量表区域(地址0)也应该在那里。尽可能使用最粗略的条目。

请记住,控制寄存器空间不应该被缓存,在mmu表工作之前,您可能不应该启用数据缓存,然后开始缓存区域,直到代码崩溃,然后取消缓存最后一件事。

既然您的目标是一对一的映射,而不是像操作系统那样使用mmu,那么您可以像我一样提前构建mmu表。操作系统需要一些例程来实时完成这项工作。下面的代码是在汇编程序中构建表,然后将表链接到程序中。您的解决方案可能有所不同。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MMUTABLEBASE 0x00000000

#define MMUALLOC (0x8000>>2)

unsigned int mmu_table[MMUALLOC];
unsigned int mmu_table_owner[MMUALLOC];

#define TOP_LEVEL_WORDS (1<<((31-20)+1))
#define COARSE_TABLE_WORDS (1<<((19-12)+1))
#define SMALL_TABLE_WORDS (1<<((11-0)+1))

unsigned int base;
unsigned int nextfree;


unsigned int next_coarse_offset ( unsigned int x )
{
    unsigned int mask;

    mask=(~0)<<(10-2);
    mask=~mask;
    while(x&mask) x++; //lazy brute force
    return(x);
}

unsigned int add_one ( unsigned int add, unsigned int flags )
{
    unsigned int ra;
    unsigned int rb;
    unsigned int rc;

    ra=add>>20;
    if(mmu_table[ra])
    {
        printf("Address %08X already allocated\n",add);
        return(1);
    }
    add=ra<<20;

    rb=next_coarse_offset(nextfree);
    rc=rb+COARSE_TABLE_WORDS;

    if(rc>=MMUALLOC)
    {
        printf("Not enough room\n");
        return(1);
    }
    nextfree=rc;

    mmu_table[ra]=(MMUTABLEBASE+(rb<<2))|0x00000001;

    for(ra=0;ra<COARSE_TABLE_WORDS;ra++)
    {
        mmu_table[rb+ra]=(add+(ra<<12))|0x00000032|flags;
        mmu_table_owner[rb+ra]=(add+(ra<<12));
    }
    return(0);
}



int main ( void )
{

    memset(mmu_table,0xF0,sizeof(mmu_table));

    for(nextfree=0;nextfree<TOP_LEVEL_WORDS;nextfree++)
    {
        mmu_table[nextfree]=0x00000000;
        mmu_table_owner[nextfree]=nextfree<<20;
    }

    if(add_one(0xD6000000,0x0000|8|4)) return(1);
    if(add_one(0x00000000,0x0000|8|4)) return(1);
    if(add_one(0xC3F00000,0x0000)) return(1);
    if(add_one(0xCA000000,0x0000)) return(1);


    printf("    .globl _start\n");
    printf("_start:\n");

    for(base=0;base<nextfree;base++)
    {
        printf(".word 0x%08X ;@ [0x%08X] 0x%08X\n",mmu_table[base],MMUTABLEBASE+(base<<2),mmu_table_owner[base]);
    }

    for(;base<MMUALLOC;base++)
    {
        printf(".word 0x00000000 ;@ [0x%08X]\n",MMUTABLEBASE+(base<<2));
    }
    printf("   b   zreset\n");
    for(base=0;base<15;base++) printf("    b zhang\n");
    printf("zhang: b zhang\n");
    printf("zreset:\n");
    printf("  ldr pc,=reset\n");
    printf("\n");


    return(0);
}
票数 3
EN

Stack Overflow用户

发布于 2011-01-12 07:13:43

可以使用以下(未经测试的)代码创建包含一对一虚拟/物理映射的16K页目录:

代码语言:javascript
复制
/* 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项的

  • 清除数据和指令;
  • 刷新其他高速缓存(预取缓冲区、分支目标高速缓存等);包含指向上述生成的PD的指针的
  • Setup TTBR0;以及高速缓存和MMU.

这些指令中的每一个都是特定于CPU的,但示例应该(希望)在其他地方可以用于您的硬件(或者,如果做不到,可以查看其他操作系统的源代码,例如Linux或FreeBSD)。此外,对于测试,您可能只需要考虑最后两点即可开始。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3439708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档