00. 目录

文章目录

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

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

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);//0xC2345648 --> 0x72345648ttb[0xC23] = (int)ttb_c | 0x1;ttb_c[0x45] = (0x72345 << 12) | 0x2;//test.bin//ttb[0x500] = (0x50 << 24) | (1 << 18) | 2;ttb[0x500] = (int)ttb_c | 0x1;ttb_c[0x0] = (0x50000 << 12) | 0x2;//U-Boot.bin stackU32 pa;for (i = 0x42000000; i < 0x44000000; i += 1000000)    {pa = i >> 24;ttb[i >> 20] = (pa << 24) | (1 << 18) | 2;}//所有寄存器的地址for (i = 0x10000000; i < 0x14000000; i += 1000000)    {pa = i >> 24;ttb[i >> 20] = (pa << 24) | (1 << 18) | 2;}//设置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. 程序示例二

将0x00005648地址映射到0x70005648

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);//0x5648 --> 0x72345648ttb[0x0] = (int)ttb_c | 0x1;ttb_c[0x5] = (0x72345 << 12) | 0x2;//test.bin//ttb[0x500] = (0x50 << 24) | (1 << 18) | 2;ttb[0x500] = (int)ttb_c | 0x1;ttb_c[0x0] = (0x50000 << 12) | 0x2;//U-Boot.bin stackU32 pa;for (i = 0x42000000; i < 0x44000000; i += 1000000)    {pa = i >> 24;ttb[i >> 20] = (pa << 24) | (1 << 18) | 2;}//所有寄存器的地址for (i = 0x10000000; i < 0x14000000; i += 1000000)    {pa = i >> 24;ttb[i >> 20] = (pa << 24) | (1 << 18) | 2;}//设置TTB基地址set_ttb(ttb);//设置域访问权限set_domain(0xffffffff);//使能MMUenable_mmu();p = (void*)0x5648;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

06. 附录

Exynos 4412 SCP_Users Manual_Ver.0.10.00_Preliminary0.pdf

【ARM】Tiny4412裸板编程之MMU(页 4K)相关推荐

  1. 【ARM】Tiny4412裸板编程之MMU封装

    00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例 05. 附录 01. 开发环境 开发板:Tiny4412SDK标准版 「 ...

  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. 联想计算机农村,农村的联想
  2. 和平精英清明节服务器维修时间,和平精英体验服关服维护要多久 和平精英体验服什么时候开放...
  3. equals java的用法_Java ConcurrentLinkedDeque equals()用法及代码示例
  4. 《编程珠玑》笔记3 数据结构选择
  5. postfix文档修正
  6. 前端笔记-jquery
  7. WeMos-D1R2的使用
  8. c语言c98标准,1.3.2 C语言标准
  9. 【线段树】HDU 3397 Sequence operation 区间合并
  10. mysql之查询排序
  11. 服务器设计笔记(1)-----消息的封装
  12. Picnic Planning
  13. Vc2013实战(1) 别无选择的Mfc
  14. 8种免费商用中文字体
  15. 对称密钥、非对称密钥、数字签名、数字证书
  16. 人脸关键点检测PFLD
  17. Python str函数
  18. 全球与中国冲压空气涡轮行业调查与未来发展趋势研究报告
  19. html 链接到 appstore,如何在微信浏览器内打开App Store链接
  20. 低碳生活进行时!国产“芯”RK3568创造智慧出行新体验

热门文章

  1. 动态规划之一最长上升子序列LIS
  2. 安装oracle 12c 还用装11g_oracle12c-RAC安装部署之GRID安装
  3. powergrep linux版本,PowerShell实现简单的grep功能
  4. php mongodb 别名,PHP mongo与mongodb扩展 | 码路春哥
  5. C语言学习之求∑k(k=100)+∑K*k(k=50)+∑1/k(k=10)
  6. STL源码剖析---空间配置器
  7. 关于Linux的修复(重新引导)
  8. Ant Design Pro+Electron+electron-builder实现React应用脱离浏览器,桌面安装运行
  9. eclipse中的maven build、maven clean、maven install和maven test的区别
  10. chattr和lsattr命令的使用(对于root用户也无法修改删除的操作问题)