历史上的今天
今天是:2024年10月14日(星期一)
2018年10月14日 | Tiny4412的MMU映射代码示例
2018-10-14 来源:eefocus
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 \n"
"mcr p15, 0, r0, c3, c0, 0\n"
"mcr p15, 0, %1, c2, c0, 0\n" //configure ttb
"mrc p15, 0, r0, c1, c0, 0\n"
"orr %0, r0, %0\n"
"mcr p15, 0, %0, c1, c0, 0\n" //enable mmu
:
: "r" (c1_flags), "r" (ttb)
: "r0"
);
p = 0x12345678;
printf("*p = 0xx\n", *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) $@ $<
%.o:%.c
$(Q)$(CC) $(C_FLAGS) $@ $<
.PHONY:clean
clean:
$(Q)$(RM) $(PREFIX)/$(TARGET:=.bin) $(PREFIX)/$(VECTOR:=.bin) $(TARGET:=.o) $(VECTOR:=.o) $(TARGET) $(VECTOR) *~
=====================================================================
小页映射源码示例:
// 李柏章 Li Baizhang, makelinux@gmail.com, 2013-08,
#include "regs.h"
void (*printf)(char *, ...) = 0x43e11434;
void init_ttb(unsigned long *ttb_base, unsigned long *ttb_l2);
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 = 0x53000000, //第一级页表
ttb_l2 = 0x54000000; //第二级页表
volatile int *p = 0x52345678;
*p = 0x52300000;
init_ttb(ttb, ttb_l2);
//在ttb表中把0x12345678映射到0x52345678中去
//因为二级页面可以映射的很细腻,也可以把0x12345678映射到0x52355678中去
mmap(ttb, 0x12345678, 0x52345678);
c1_flags = 1 | (1 << 3) | ( 1 << 11) | (1 << 28);
__asm__ __volatile__ (
"mvn r0, #0 \n"
"mcr p15, 0, r0, c3, c0, 0\n"
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c7, 0\n" //invalidate I & D cache ,使 I & D cache无效
"mcr p15, 0, r0, c8, c7, 0\n" //invalidate I & D TLB,使I & D TLB无效
"mcr p15, 0, %1, c2, c0, 0\n" //configure ttb
"mcr p15, 0, %0, c1, c0, 0\n" //enable mmu
:
: "r" (c1_flags), "r" (ttb)
: "r0"
);
p = 0x12345678;
printf("*p = 0xx\n", *p);
}
void init_ttb(unsigned long *ttb_base, unsigned long *ttb_l2)
{
unsigned long va, pa;
memset(ttb_base, 0x00, 16 * 1024 );
for (va = 0x00000000; va < 0x14000000; ttb_l2+= 0x400) {
unsigned long to;
ttb_base[ va >> 20] = ((unsigned long)ttb_l2 & 0xfffffc00) | 1;
to = va + 0x100000;
for ( ; va < to; va += 0x1000) {
pa = va;
ttb_l2[(va >> 12) & 0xff] = (pa & 0xfffff000) | 2;
}
}
for (va = 0x40000000; va < 0x80000000; ttb_l2+= 0x400) {
unsigned long to;
ttb_base[ va >> 20] = ((unsigned long)ttb_l2 & 0xfffffc00) | 1;
to = va + 0x100000;
for ( ; va < to; va += 0x1000) {
pa = va;
ttb_l2[(va >> 12) & 0xff] = (pa & 0xfffff000) | 2;
}
}
}
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) $@ $<
%.o:%.c
$(Q)$(CC) $(C_FLAGS) $@ $<
.PHONY:clean
clean:
$(Q)$(RM) $(PREFIX)/$(TARGET:=.bin) $(PREFIX)/$(VECTOR:=.bin) $(TARGET:=.o) $(VECTOR:=.o) $(TARGET) $(VECTOR) *~
==============================================================
史海拾趣
|
发帖发问一个bootloader问题并邀请学习6410,PXA3XX等高级货的同志了! 这几天看了6410的eboot,并对nk.bin以及nk.nb0文件重新了解了一下,发现了很多疑问。 主要是我以前一直用ADS bootloader,现在觉得两者有不可思议的差别。 一、ADS bootloader没有拷贝全局变量到RAM的行为,但是eboot.nb0有——但是这两个格式的 ...… 查看全部问答> |
|
如题。用的2450的板子,wince5.0的平台。现在用IIC1接我的IC芯片。现在拿到手的IIC驱动是IIC0的,即用的GPE14\\GPE15,我需要将其换成IIC1,即GPB7\\GPB8。我做了如下修改: 1、 WINCE500\\PLATFORM\\SMDK2450\\Src\\Drivers\\IIC\\i2c.c中 //#de ...… 查看全部问答> |
|
我用的优龙YL2410开发板,最近想自己制作一个cramfs跟文件系统,参考网上比较著名的一个文档《Linux系统移植》的根文件系统制作部分自己制作了一个cramfs的文件系统my_rootfs.cramfs,其中busybox使用的是1.1.3。把my_rootfs.cramfs烧写到板子后发 ...… 查看全部问答> |
|
wince5.0 S3c2440官方bsp,带camera驱动 wince5.0 S3c2440官方bsp,带camera驱动: http://www.itxxh.cn/book/2440/zaxsw1565.shtml WINCE5.0系统下,OV9650 CAMERA驱动程序: http://www.itxxh.cn/book/2440/zaxsw1568.shtml… 查看全部问答> |
|
Bit-banding 又称为:极细微的位处理操作, 精确的位操作,位别名区。 为了减少读-修改-写(RMW)操作的时间,ARM在Cortex-M3处理器中引入了bit-banding技术。在bit-banding使能的处理器中,存储器映射的特定区域(SRAM和外设区)能够使用地址别 ...… 查看全部问答> |




