00. 目录

文章目录

  • 00. 目录
  • 01. 开发环境
  • 02. Tiny4412内存布局
  • 03. 配置MMU
  • 04. 程序示例
  • 05. 附录

01. 开发环境

  • 开发板:Tiny4412SDK标准版 「Tiny4412 SDK 1506」
  • 工具:「arm-linux-gcc-4.5.1」 「minicom」 「dnw」
  • 平台:Ubuntu 20.04

02. Tiny4412内存布局

咱们的内存是1G,范围是0x40000000~0x8000000

在0x40000000~0x80000000, 程序示例

#include <string.h>
#include <adc.h>
#include <gpio.h>void (*udelay)(unsigned int) = (void*)0x43e26480;
int (*print)(const char *format, ...) = (void*)0x43e11a2c;extern unsigned int __bss_start;
extern unsigned int __bss_end;int main(void)
{//0x40000000 ~ 0x80000000  1Gmemset((void*)&__bss_start, 0, (int)&__bss_end -(int)&__bss_start);print("main start\n");U32 *p = (void*)0x72345678;*p = 0x11223344;print("*p = %#x\n", *p);p = (void*)0x82345678;*p = 0x11112222;print("*p = %#x\n", *p);print("main end\n");return 0;
}

执行结果

## Starting application at 0x50000000 ...
main start
*p = 0x11223344

03. 配置MMU

3.1 使能MMU

B3.2.4 Enabling MMUs

    .section .text.align 2.global mmu_enable
mmu_enable:mrc p15, 0, r0, c1, c0, 0orr r0, r0, #1 @将M为设置为1mcr p15, 0, r0, c1, c0, 0mov pc, lr

3.2 禁用MMU

    .section .text.align 2.global disable_mmu
disable_mmu:mrc p15, 0, r0, c1, c0, 0bic r0, r0, #1 @将M为设置为0mcr p15, 0, r0, c1, c0, 0mov pc, lr

3.3 设置页表基地址

B4.1.154 TTBR0, Translation Table Base Register 0, VMSA

访问TTBR0的方法

MRC p15, 0, <Rt>, c2, c0, 0 ; Read 32-bit TTBR0 into Rt
MCR p15, 0, <Rt>, c2, c0, 0 ; Write Rt to 32-bit TTBR0

设置TTB的基地址

    .section .text.align 2.global set_ttb
set_ttb:mcr p15, 0, r0, c2, c0, 0mov pc, lr

3.4 设置Domain访问权限

B4.1.43 DACR, Domain Access Control Register, VMSA

To access the DACR, software reads or writes the CP15 registers with  <opc1> set to 0,
<CRn> set to c3,  <CRm> set to
c0, and  <opc2> set to 0. For example:
MRC p15, 0, <Rt>, c3, c0, 0 ; Read DACR into Rt
MCR p15, 0, <Rt>, c3, c0, 0 ; Write Rt to DACR

设置域访问权限

    .section .text.align 2.global set_domain
set_domain:mcr p15, 0, r0, c3, c0, 0mov pc, lr

04. 程序示例

一级页表描述符格式

二级页表描述符格式

sp15.S文件内容如下

    .section .text.align 2.global get_midr
get_midr:MRC p15, 0, r0, c0, c0, 0 mov pc, lr.section .text.align 2.global get_ccsidr
get_ccsidr:MRC p15, 1, r0, c0, c0, 0mov pc, lr.section .text.align 2.global get_sctlr
get_sctlr:MRC p15, 0, r0, c1, c0, 0mov pc, lr.section .text.align 2.global get_id_mmfr3
get_id_mmfr3:MRC p15, 0, r0, c0, c1, 7mov pc, lr.section .text.align 2.global enable_mmu
enable_mmu:mrc p15, 0, r0, c1, c0, 0orr r0, r0, #1mcr p15, 0, r0, c1, c0, 0mov pc, lr.section .text.align 2.global disable_mmu
disable_mmu:mrc p15, 0, r0, c1, c0, 0bic r0, r0, #1mcr p15, 0, r0, c1, c0, 0mov pc, lr.section .text.align 2.global set_ttb
set_ttb:mcr p15, 0, r0, c2, c0, 0mov pc, lr.section .text.align 2.global set_domain
set_domain:mcr p15, 0, r0, c3, c0, 0mov pc, lr

ttb.c文件内容如下

#include <string.h>
#include <gpio.h>//一级页表初始化
void ttb_l1_init(U32 *ttb)
{U32 va;U32 pa;//test.binfor (va = 0x50000000; va < 0x50100000; va += 0x100000){pa = va; ttb[va >> 20] = pa | 0x2;}//uboot.bin   Uboot需要多一点空间for (va = 0x43000000; va < 0x44000000; va += 0x100000){pa = va; ttb[va >> 20] = pa | 0x2;}//GPIOfor (va = 0x10000000; va < 0x14000000; va += 0x100000){pa = va; ttb[va >> 20] = pa | 0x2;}
}//一级页表映射
void ttb_l1_mmap(U32 *ttb, U32 va, U32 pa)
{ttb[va >> 20] = (pa & 0xfff00000) | 0x2;
}//二级页表初始化
void ttb_l2_init(U32 *ttb, U32 **ttb_c)
{U32 va;U32 pa;U32 tmp;//test.binfor (va = 0x50000000; va < 0x58000000; (*ttb_c) += 0x100) {ttb[va >> 20] = (int)(*ttb_c) | 0x1; memset((void*)*ttb_c, 0, 256 * 4);//4Kfor (tmp = va + 0x100000; va < tmp; va += 0x1000){pa = va; (*ttb_c)[(va >> 12) & 0xff] = (pa & 0xfffff000) | 0x2;}}//uboot.binfor (va = 0x43000000; va < 0x44000000; (*ttb_c) += 0x100) {ttb[va >> 20] = (int)(*ttb_c) | 0x1; memset((void*)*ttb_c, 0, 256 * 4);//4Kfor (tmp = va + 0x100000; va < tmp; va += 0x1000){pa = va; (*ttb_c)[(va >> 12) & 0xff] = (pa & 0xfffff000) | 0x2;}}//gpiofor (va = 0x10000000; va < 0x14000000; (*ttb_c) += 0x100) {ttb[va >> 20] = (int)(*ttb_c) | 0x1; memset((void*)*ttb_c, 0, 256 * 4);//4Kfor (tmp = va + 0x100000; va < tmp; va += 0x1000){pa = va; (*ttb_c)[(va >> 12) & 0xff] = (pa & 0xfffff000) | 0x2;}}
}//二级页表映射
void ttb_l2_mmap(U32 *ttb, U32 **ttb_c, U32 va, U32 pa)
{ttb[va >> 20] = (int)(*ttb_c) | 0x1;memset((void*)*ttb_c, 0, 256 * 4);(*ttb_c)[(va >> 12) & 0xff] = (pa & 0xfffff000) | 0x2;(*ttb_c) += 0x100;
}

test.c文件内容如下

#include <string.h>
#include <stdlib.h>
#include <adc.h>
#include <gpio.h>void (*udelay)(unsigned int) = (void*)0x43e26480;
int (*print)(const char *format, ...) = (void*)0x43e11a2c;extern unsigned int __bss_start;
extern unsigned int __bss_end;//TTB的基地址
U32 *ttb = (void*)0x60000000;
U32 *ttb_c = (void*)0x61000000;int main(void)
{int i = 0;//0x40000000 ~ 0x80000000  1Gmemset((void*)&__bss_start, 0, (int)&__bss_end -(int)&__bss_start);print("main start\n");U32 *p = (void*)0x72345648;for (i = 0; i < 100; i++){p[i] = i; }print("*p = %#x\n", *p);//清零 4K * 4Bytememset((void*)ttb, 0, 4096 * 4);memset((void*)ttb_c, 0, 256* 4);#if 0ttb_l1_init(ttb);ttb_l1_mmap(ttb, 0xC2345648, 0x72345648);#elsettb_l2_init(ttb, &ttb_c);ttb_l2_mmap(ttb, &ttb_c, 0xC2345648, 0x72345648);
#endif//设置TTB基地址set_ttb(ttb);//设置域访问权限set_domain(0xffffffff);//使能MMUenable_mmu();p = (void*)0xC2345648;for (i = 0; i < 100; i++){print("p[%d] = %d\n", i, p[i]); }print("main end\n");//禁用MMUdisable_mmu();return 0;
}

执行结果

## Starting application at 0x50000000 ...
main start
*p = 0x0
p[0] = 0
p[1] = 1
p[2] = 2
p[3] = 3
p[4] = 4
p[5] = 5
p[6] = 6
p[7] = 7
p[8] = 8
p[9] = 9
p[10] = 10
p[11] = 11
p[12] = 12
p[13] = 13
p[14] = 14
p[15] = 15
p[16] = 16
p[17] = 17
p[18] = 18
p[19] = 19
p[20] = 20
p[21] = 21
p[22] = 22
p[23] = 23
p[24] = 24
p[25] = 25
p[26] = 26
p[27] = 27
p[28] = 28
p[29] = 29
p[30] = 30
p[31] = 31
p[32] = 32
p[33] = 33
p[34] = 34
p[35] = 35
p[36] = 36
p[37] = 37
p[38] = 38
p[39] = 39
p[40] = 40
p[41] = 41
p[42] = 42
p[43] = 43
p[44] = 44
p[45] = 45
p[46] = 46
p[47] = 47
p[48] = 48
p[49] = 49
p[50] = 50
p[51] = 51
p[52] = 52
p[53] = 53
p[54] = 54
p[55] = 55
p[56] = 56
p[57] = 57
p[58] = 58
p[59] = 59
p[60] = 60
p[61] = 61
p[62] = 62
p[63] = 63
p[64] = 64
p[65] = 65
p[66] = 66
p[67] = 67
p[68] = 68
p[69] = 69
p[70] = 70
p[71] = 71
p[72] = 72
p[73] = 73
p[74] = 74
p[75] = 75
p[76] = 76
p[77] = 77
p[78] = 78
p[79] = 79
p[80] = 80
p[81] = 81
p[82] = 82
p[83] = 83
p[84] = 84
p[85] = 85
p[86] = 86
p[87] = 87
p[88] = 88
p[89] = 89
p[90] = 90
p[91] = 91
p[92] = 92
p[93] = 93
p[94] = 94
p[95] = 95
p[96] = 96
p[97] = 97
p[98] = 98
p[99] = 99
main end
## Application terminated, rc = 0x0

05. 附录

ARM ® Architecture Reference Manual ARMv7-A and ARMv7-R edition

【ARM】Tiny4412裸板编程之MMU封装相关推荐

  1. 【ARM】Tiny4412裸板编程之MMU(页 4K)

    00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...

  2. 【ARM】Tiny4412裸板编程之MMU(段 16M)

    00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...

  3. 【ARM】Tiny4412裸板编程之MMU(段1M)

    00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...

  4. 【ARM】Tiny4412裸板编程之MMU简介

    00. 目录 文章目录 00. 目录 01. MMU简介 02. MMU发展 03. 地址分类 04. MMU工作过程 05. 段地址转换过程 06. 二级页表描述符 07. TLB的作用 08. C ...

  5. 【ARM】Tiny4412裸板编程之ADC

    00. 目录 文章目录 00. 目录 01. 开发环境 02. ADC概述 03. ADC特性 04. ADC模块图 05. ADC寄存器 06. ADC电路连接 07. 程序示例 08. 附录 01 ...

  6. 【ARM】Tiny4412裸板编程之 printf函数

    00. 目录 文章目录 00. 目录 01. 开发环境 02. printf概述 03. Uboot中printf函数 04. 程序示例一 05. 附录 01. 开发环境 开发板:Tiny4412SD ...

  7. 【ARM】Tiny4412裸板编程之LED(C语言)

    00. 目录 文章目录 00. 目录 01. 控制原理 02. 配置寄存器 03. 程序示例一 04. 程序示例二 05. 程序示例三 06. 程序实例四 07. 附录 01. 控制原理 咱们的LED ...

  8. 【ARM】Tiny4412裸板编程之LED(二)

    00. 目录 文章目录 00. 目录 01. 控制原理 02. 配置寄存器 03. 程序示例一 04. 程序示例二 05. 程序示例三 06. 附录 01. 控制原理 咱们的LED在核心板上,所以需要 ...

  9. 【ARM】Tiny4412裸板编程之Chip ID

    00. 目录 文章目录 00. 目录 01. Chip ID概述 02. 寄存器介绍 03. 程序示例 04. 编译执行 05. 附录 01. Chip ID概述 The Exynos 4412 SC ...

最新文章

  1. 吞吐量达到瓶颈后下降_如何找到 Kafka 集群的吞吐量极限?
  2. Mysql 中获取刚插入的自增长id的值
  3. spring boot 整合redis实现方法缓存
  4. C#常用集合的使用(转载)
  5. 如何找到Fiori Launchpad tile所属的catalog id
  6. [TJOI2018]智力竞赛 (匈牙利)
  7. python实现常见排序算法
  8. 从json数组中获取某一属性的集合
  9. 架构设计工作笔记001---智慧城市项目架构设计中应该注意的问题
  10. Android SurfaceFlinger vsync信号产生与分发
  11. 转载 《Python爬虫学习系列教程》学习笔记
  12. 在Tiny6410烧写linux内核文件和文件系统
  13. 使用开票组件快速开具清单发票
  14. 彻底掌握Quartus——基础篇
  15. 著名的劝学诗,少年辛苦终事成,莫向光阴惰寸功!
  16. 实战无成本搭建php社工库,简单、高效、几T数据随便查,高效社工库搭建与数据库整理–深夜福利...
  17. 高中计算机基础知识课件,5.1.2 信息资源管理的方式方法
  18. Apache HBase JavaAPI 查询数据
  19. k-means像素聚类
  20. 后台执行linux命令

热门文章

  1. COM本质论学习笔记(一)IDL
  2. 10-19 查询学生成绩及汇总其总学分 (10 分)
  3. linux mint 蓝牙,Linuxmint19蓝牙连接的问题
  4. Java Decimal范围_Java BigDecimal初探
  5. 《架构之美》阅读笔记二
  6. Linux 下mysql5.7安装搬运 该安装说明坑最少
  7. .net core 中使用httpclient,HttpClientFactory的问题
  8. SpringBoot+SpringSecurity之多模块用户认证授权同步
  9. Java类之File记录
  10. DAL,IDAL,BLL,Factory作用