【ARM】Tiny4412裸板编程之MMU封装
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封装相关推荐
- 【ARM】Tiny4412裸板编程之MMU(页 4K)
00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...
- 【ARM】Tiny4412裸板编程之MMU(段 16M)
00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...
- 【ARM】Tiny4412裸板编程之MMU(段1M)
00. 目录 文章目录 00. 目录 01. 开发环境 02. Tiny4412内存布局 03. 配置MMU 04. 程序示例一 05. 程序示例二 06. 附录 01. 开发环境 开发板:Tiny4 ...
- 【ARM】Tiny4412裸板编程之MMU简介
00. 目录 文章目录 00. 目录 01. MMU简介 02. MMU发展 03. 地址分类 04. MMU工作过程 05. 段地址转换过程 06. 二级页表描述符 07. TLB的作用 08. C ...
- 【ARM】Tiny4412裸板编程之ADC
00. 目录 文章目录 00. 目录 01. 开发环境 02. ADC概述 03. ADC特性 04. ADC模块图 05. ADC寄存器 06. ADC电路连接 07. 程序示例 08. 附录 01 ...
- 【ARM】Tiny4412裸板编程之 printf函数
00. 目录 文章目录 00. 目录 01. 开发环境 02. printf概述 03. Uboot中printf函数 04. 程序示例一 05. 附录 01. 开发环境 开发板:Tiny4412SD ...
- 【ARM】Tiny4412裸板编程之LED(C语言)
00. 目录 文章目录 00. 目录 01. 控制原理 02. 配置寄存器 03. 程序示例一 04. 程序示例二 05. 程序示例三 06. 程序实例四 07. 附录 01. 控制原理 咱们的LED ...
- 【ARM】Tiny4412裸板编程之LED(二)
00. 目录 文章目录 00. 目录 01. 控制原理 02. 配置寄存器 03. 程序示例一 04. 程序示例二 05. 程序示例三 06. 附录 01. 控制原理 咱们的LED在核心板上,所以需要 ...
- 【ARM】Tiny4412裸板编程之Chip ID
00. 目录 文章目录 00. 目录 01. Chip ID概述 02. 寄存器介绍 03. 程序示例 04. 编译执行 05. 附录 01. Chip ID概述 The Exynos 4412 SC ...
最新文章
- 吞吐量达到瓶颈后下降_如何找到 Kafka 集群的吞吐量极限?
- Mysql 中获取刚插入的自增长id的值
- spring boot 整合redis实现方法缓存
- C#常用集合的使用(转载)
- 如何找到Fiori Launchpad tile所属的catalog id
- [TJOI2018]智力竞赛 (匈牙利)
- python实现常见排序算法
- 从json数组中获取某一属性的集合
- 架构设计工作笔记001---智慧城市项目架构设计中应该注意的问题
- Android SurfaceFlinger vsync信号产生与分发
- 转载 《Python爬虫学习系列教程》学习笔记
- 在Tiny6410烧写linux内核文件和文件系统
- 使用开票组件快速开具清单发票
- 彻底掌握Quartus——基础篇
- 著名的劝学诗,少年辛苦终事成,莫向光阴惰寸功!
- 实战无成本搭建php社工库,简单、高效、几T数据随便查,高效社工库搭建与数据库整理–深夜福利...
- 高中计算机基础知识课件,5.1.2 信息资源管理的方式方法
- Apache HBase JavaAPI 查询数据
- k-means像素聚类
- 后台执行linux命令
热门文章
- COM本质论学习笔记(一)IDL
- 10-19 查询学生成绩及汇总其总学分 (10 分)
- linux mint 蓝牙,Linuxmint19蓝牙连接的问题
- Java Decimal范围_Java BigDecimal初探
- 《架构之美》阅读笔记二
- Linux 下mysql5.7安装搬运 该安装说明坑最少
- .net core 中使用httpclient,HttpClientFactory的问题
- SpringBoot+SpringSecurity之多模块用户认证授权同步
- Java类之File记录
- DAL,IDAL,BLL,Factory作用