1. 概述
1.1 基本概念
MMU全称“Memory Management Unit”,顾名思义就是“内存管理单元”。
1.2 运作机制
建立页表描述符号表,将物理地址映射成虚拟地址,以虚拟地址为媒介来操作和管理实际的物理内存。
页表描述符号表,是由用户根据所使用的主芯片的页表描述格式,去创建、修改和管理的,而内存则依据页表描述符号表进行映射、权限控制等。页表描述符号表在创建或修改后,需要将它写入协处理器CP15才能生效,而协处理CP15正是内存管理的实际执行者。
综合来说,对MMU操作就是通过修改页表描述符和控制CP15协处理器来实现的,具体运作流程如下图1所示。
Huawei LiteOS的MMU有两个方面的作用:
- 提供硬件机制的内存cache/nocache属性的控制接口。
- 提供硬件机制的内存访问权限控制接口。
2. 开发指导
2.1 使用场景
系统内部有些内存不希望被修改,否则会造成不可预测的后果,此时可以用MMU修改该段内存的访问权限。访问该段内存时会检查访问权限,若权限不正确则会触发异常,起到保护该段内存数据的作用。
2.2 功能
Huawei LiteOS中MMU模块为用户提供以下接口:
功能分类 | 接口名 | 描述 |
---|---|---|
内存访问权限控制 | LOS_MMUParamSet | 修改指定地址段的内存cache状态、buffer状态、读写权限状态 |
参数:
BUFFER_ENABLE/BUFFER_DISABLE ---- 使能/关闭buffer
CACHE_ENABLE/CACHE_DISABLE ---- 使能/关闭cache
ACCESS_PERM_RW_RW/ACCESS_PERM_RO_RO ---- 可读写/只读
举例:
LOS_MMUParamSet(&__text_start, &__text_end, BUFFER_ENABLE|CACHE_ENABLE|ACCESS_PERM_RO_RO);
描述:
将__text_start, __text_end这两个地址之间的内存设置为(写回)启用cache、 buffer、只读。
说明
LOS_MMUParamSet的入参1和入参2需要4KB对齐,入参3最好是显示的选择以上列举的3种类型的宏。
3 注意事项
- 目前MMU二级页表可操作最小内存单位是4KB,所以要设置访问权限的内存区域的起始地址和结束地址都要4KB对齐。一级页表修改未做对外接口,无需关注。
- 通过该接口可控制的内存大小,取决于分配用于存放二级页表的内存大小,例如Hi3516a:预留了0x80000000~0x80008000的内存用于存放页表,其中0x8000000~0x80004000用于存放一级页表,0x80004000~0x80008000(16K)用于存放二级页表(每条表项占用4byte,每条表项对应4K内存),所以最多可以控制16M的可配置内存。
4 编程实例
4.1 实例描述
调用接口LOS_MMUParamSet,修改内存区域的读写权限,再通过在该内存区域进行写操作,查看是否读写权限正确修改。
步骤1 修改一段区间的内存读写权限为只读。
步骤2 在该段区间的内存中进行简单的写操作。
系统进入异常,说明将该内存设置为“只读”成功。
步骤3 注释掉2中的写操作,而是直接调用接口将读写权限重新修改为可读可写。
系统不进入异常,说明将该内存设置为“可读可写”成功。
4.2 编程实例
UINT32 MMU_Sample()
{
UINT32 *pAlignaddr;
PRINTK("---- TEST START ----\n");
pAlignaddr = (UINT32 *)(&__text_start);
PRINTK(">>1\n");
LOS_MMUParamSet(&__text_start, &__text_end, BUFFER_ENABLE|CACHE_ENABLE|ACCESS_PERM_RO_RO);
*pAlignaddr = 0xa; //if done, be exc
PRINTK(">>2\n");
LOS_MMUParamSet(&__text_start, &__text_end, BUFFER_ENABLE|CACHE_ENABLE|ACCESS_PERM_RW_RW);
*pAlignaddr = 0xb;
PRINTK(">>3\n");
PRINTK("---- TEST END ----\n");
return LOS_OK;
}