历史上的今天
返回首页

历史上的今天

今天是: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) *~

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


推荐阅读

史海拾趣

扬州国芯(Gcore)公司的发展小趣事

扬州国芯(Gcore)公司发展的五个故事

故事一:成立与初期发展

扬州国芯半导体有限公司成立于2011年,起初便定位于集成电路产品的设计、测试、销售与服务。公司总部位于历史文化名城扬州,并在深圳设立了销售办事处,以便更好地服务国内外市场。成立初期,扬州国芯便专注于研发集成度高、低噪声、低功耗、高可靠性的模拟芯片及数模混合芯片产品。通过不懈的努力,公司逐渐在运算放大器、比较器、电源管理等领域形成了自己的核心产品线,为后续的快速发展奠定了坚实基础。

故事二:技术创新与产品研发

扬州国芯深知技术创新是企业发展的核心动力。因此,公司不断加大研发投入,引进高端人才,并与国内外多所知名高校和科研机构建立了紧密的合作关系。经过多年的努力,扬州国芯成功研发出了一系列具有自主知识产权的芯片产品,如锂电池充电管理芯片、马达驱动芯片等,这些产品性能优越,品质可靠,迅速赢得了市场的认可。此外,公司还积极参与国家标准和行业标准的制定,进一步提升了企业的行业地位和影响力。

故事三:市场拓展与品牌建设

随着产品线的不断丰富和技术的持续创新,扬州国芯开始积极拓展国内外市场。公司通过参加各类行业展会、举办技术研讨会等方式,加强与客户的沟通和交流,不断提升品牌知名度和美誉度。同时,公司还注重售后服务体系的建设,为客户提供全方位、一站式的解决方案和服务。这些措施有效地推动了公司市场份额的快速增长,使扬州国芯在激烈的市场竞争中脱颖而出。

故事四:政府支持与产业合作

扬州国芯的发展离不开当地政府的支持和产业合作。近年来,扬州市政府高度重视电子信息产业的发展,出台了一系列优惠政策和扶持措施,为扬州国芯等高科技企业提供了良好的发展环境。同时,公司还积极与上下游产业链企业开展合作,共同推动产业链的协同发展。这些合作不仅有助于降低生产成本、提高产品质量,还有助于公司更好地把握市场动态和客户需求,实现持续稳健的发展。

故事五:国际化战略与未来展望

面对全球集成电路产业的快速发展和市场竞争的日益激烈,扬州国芯制定了明确的国际化战略。公司积极寻求与国际知名企业的合作机会,引进先进的技术和管理经验,提升企业的国际竞争力。同时,公司还计划在海外设立研发中心和销售网络,以便更好地服务全球客户。展望未来,扬州国芯将继续秉承“以人才为根本、以市场为导向、以技术为核心、以顾客为目标”的经营宗旨,不断开创新的辉煌篇章。

ATOP_Technologies公司的发展小趣事

在追求技术创新的同时,ATOP Technologies也始终注重品质管理和品牌建设。公司通过了ISO-9001认证,从产品的研发设计到生产,所有的流程都严格遵循最佳品质原则。此外,ATOP Technologies还注重品牌形象的塑造和推广,通过参加行业活动、举办技术研讨会等方式,不断提升品牌知名度和影响力。

Fillfactory Nv公司的发展小趣事

2015年,FIDELIX迎来了一个重要的转折点。在这一年,东芯半导体有限公司(以下简称“东芯半导体”)正式收购了FIDELIX 25.3%的股权,成为其第一大股东及实际控制人。这一收购标志着FIDELIX开始进入一个新的发展阶段。

通过与东芯半导体的合作,FIDELIX获得了更多的资金支持和市场资源。东芯半导体是一家专注于中小容量存储芯片研发、设计和销售的中国企业,在半导体领域拥有丰富的经验和资源。双方的合作不仅为FIDELIX带来了更多的发展机会,同时也加速了FIDELIX在国际市场上的扩张步伐。

在上述两个故事的基础上,可以根据FIDELIX公司的具体发展历程、重要事件、技术创新、市场策略等方面进行进一步的拓展和补充,以形成完整、详细的故事内容。

台湾岱恩(DAIN)公司的发展小趣事

FIDELIX公司成立于1990年,是一家专注于存储芯片研发与销售的韩国企业。在公司成立初期,FIDELIX凭借对技术的深入研究和对市场的敏锐洞察,成功推出了多款性能优越的NAND FLASH(闪存)和SDR/DDR(单/双数率同步动态存储器)等存储芯片产品。这些产品不仅在韩国市场上获得了良好的口碑,同时也开始逐步进入国际市场。

随着技术的不断进步和市场的不断扩大,FIDELIX逐渐在韩国存储芯片领域崭露头角。公司不断投入研发资金,加强技术创新,努力提升产品的性能和品质。同时,FIDELIX也积极拓展销售渠道,与多家国内外知名厂商建立了合作关系,为公司的持续发展奠定了坚实的基础。

CANDD公司的发展小趣事

在电子行业的初期,CANDD公司凭借其创始人对半导体技术的深入研究,成功开发出了一款具有划时代意义的芯片。这款芯片不仅性能卓越,而且成本远低于市场上的同类产品。凭借这一技术突破,CANDD公司迅速在行业内崭露头角,吸引了大量投资者的关注。随着产品销量的不断增长,公司逐渐扩大了生产规模,并在全球范围内建立了销售网络。

ARCOTRONICS公司的发展小趣事

在电子行业的早期,ARCOTRONICS公司凭借其卓越的研发团队,成功开发出一种新型的高效能电子元件。这一技术突破不仅大幅提升了电子设备的性能,还降低了生产成本,使公司在市场上迅速获得了竞争优势。这一技术突破为ARCOTRONICS公司奠定了坚实的基石,为其后续发展打下了坚实的基础。

问答坊 | AI 解惑

求示波器原理的资料

找了好久,市场上没有一本关于示波器的书,淘宝也搜了。最多有本用示波器修电视机的。哪能找到些好书啊?有电子版的给我发一份好吗?先谢了。hongyijiabox@163.com…

查看全部问答>

发帖发问一个bootloader问题并邀请学习6410,PXA3XX等高级货的同志了!

这几天看了6410的eboot,并对nk.bin以及nk.nb0文件重新了解了一下,发现了很多疑问。 主要是我以前一直用ADS bootloader,现在觉得两者有不可思议的差别。 一、ADS bootloader没有拷贝全局变量到RAM的行为,但是eboot.nb0有——但是这两个格式的 ...…

查看全部问答>

急!!!IIC0改成IIC1!

如题。用的2450的板子,wince5.0的平台。现在用IIC1接我的IC芯片。现在拿到手的IIC驱动是IIC0的,即用的GPE14\\GPE15,我需要将其换成IIC1,即GPB7\\GPB8。我做了如下修改: 1、 WINCE500\\PLATFORM\\SMDK2450\\Src\\Drivers\\IIC\\i2c.c中 //#de ...…

查看全部问答>

菜鸟提问,请指教。关于中断

void int0_init(void) {         if(rEINTPEND == (1…

查看全部问答>

cramfs根文件系统启动问题

我用的优龙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…

查看全部问答>

sim卡座无电

我用的sim300模块,连不上线,后来发现模块给sim卡座供电的管脚没有电,这是什么原因?以前的时候一切都正常,最近要用了,却出毛病了。…

查看全部问答>

怎么样的汇编代码才算绝对地址代码,生成obj里的也没有浮动地址。

怎么样的汇编代码才算绝对地址代码,生成obj里的也没有浮动地址。 是不是代码里不要段这个伪操作就可以了?…

查看全部问答>

LM3s8962体验之五……精确的位操作

Bit-banding 又称为:极细微的位处理操作, 精确的位操作,位别名区。 为了减少读-修改-写(RMW)操作的时间,ARM在Cortex-M3处理器中引入了bit-banding技术。在bit-banding使能的处理器中,存储器映射的特定区域(SRAM和外设区)能够使用地址别 ...…

查看全部问答>

论坛的论坛,不是在做电源吗?人呢?

怎么回事,没人参加吗?好萧条啊…

查看全部问答>