×
单片机 > 单片机程序设计 > 详情

Tiny4412的MMU映射代码示例

发布时间:2020-05-22 发布时间:
|

1、关于页表:ARMv6的MMU进行地址映射时涉及到两种页表,

                       一级页表(first level page table)和二级页表(coarse page table)。

2、关于映射方式:映射方式有两种,段映射和页映射。

                               段映射只用到一级页表,页映射用到一级页表和二级页表。

3、关于映射粒度:段映射的映射粒度有两种,1M section和16M supersection;

                             页映射的映射粒度也有两种,4K small page和64K large page。

===================================================================

段模式映射代码,支持1M的映射:

#include "regs.h"

void (*printf)(char *, ...) = 0x43e11434;

void init_ttb(unsigned long *ttb_base);

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa);

void memset(char *buf, char ch, int size);

void main(void)

{    

    unsigned long c1_flags, ttb = 0x73000000;

    volatile int *p = 0x52345678;

    *p = 0x52300000;    

    init_ttb(ttb);

    mmap(ttb, 0x12345678, 0x52345678); //在ttb表中把0x12345678映射到0x52345678中去

    c1_flags = 1 | (1 << 3) | ( 1 << 11) | (1 << 28);

    __asm__ __volatile__ (

        "mvn r0, #0 "            

        "mcr p15, 0, r0, c3, c0, 0 "

        "mcr p15, 0, %1, c2, c0, 0 " //configure ttb

        "mrc p15, 0, r0, c1, c0, 0 "

        "orr %0, r0, %0 "

        "mcr p15, 0, %0, c1, c0, 0 " //enable mmu

        :

        : "r" (c1_flags), "r" (ttb)

        : "r0"

    );

    p = 0x12345678;

    printf("*p = 0xx ",  *p);

}

//对以下三个区域固定映射,不映射这个uboot没办法运行

void init_ttb(unsigned long *ttb_base)

{

    unsigned long va, pa;

    memset(ttb_base, 0x00, 16 * 1024 );        

    //内部的ROM地址在这,0-96K

    for (va = 0x00000000; va < 0x10000000; va += 0x100000) { //Others

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

    //特殊功能寄存器,即所有外设寄存器区域

    for (va = 0x10000000; va < 0x14000000; va += 0x100000) { //SFR

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

    }

    

    //片外内存DRAM

    for (va = 0x40000000; va < 0x80000000; va += 0x100000) { //DRAM

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

}

//创建单条映射,在ttb_base表当中把va虚拟地址映射到pa物理地址上去

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa)

{

    ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

}

void memset(char *buf, char ch, int size)

{

    int i;

    for (i = 0; i < size; i ++)

        buf[i] = ch;

}

====================================================================

Makefile文件:

PREFIX     =  .

#EXEC_PREFIX = /usr/local/arm/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-

EXEC_PREFIX = arm-linux-

TARGET = test

VECTOR = vector

Q    = 

AS    = $(EXEC_PREFIX)as

LD    = $(EXEC_PREFIX)ld

CC    = $(EXEC_PREFIX)gcc

OBJCOPY = $(EXEC_PREFIX)objcopy

RM    = rm -f

AS_FLAGS    = -o

C_FLAGS     = -c -o

all: $(TARGET) 

    $(Q)$(OBJCOPY) -I elf32-littlearm -O binary $(TARGET) $(PREFIX)/$(TARGET:=.bin)    

$(TARGET):$(TARGET:=.o)

    $(Q)$(LD) -Ttext=0x70003000 $< -o $@

%.o:%.S

    $(Q)$(AS) $(AS_FLAGS) $@ $<


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析