MMU简介与测试

原创
2022/11/27 13:05
阅读数 306

一、MMU简介 

MMU(Memory Management Unit),内存管理单元,负责虚拟地址与物理地址的转换(即虚拟内存管理)、内存保护、中央处理器高速缓存的控制等,是大内核系统对比与嵌入式小系统比较典型的特征。

现代的多进程操作系统通常需要MMU才能保证每个进程都拥有独立的地址空间,它的常见权限包括:虚拟内存的读、写、可执行、无法访问四种。怎样测试其权限是各开发者关心的问题,下面小编将使用内存MAP测试MMU权限管理(内存保护),一起来看看吧~

二、MMU测试 

1.内存MAP 简介

内存MAP通过MMU把虚拟内存“映射”到物理内存,把虚拟内存和物理内存一一对应起来。为了达到这个目的,需要3个要素:虚拟地址的起始地址,物理地址的起始地址,以及需要MAP(映射)的大小。(由于分页机制,一般MAP时都是以页为单位,也就是4096字节。)

在完成MAP时,还需要指定映射内存的属性,也就是这里的权限管理:读、写、可执行、无法访问。

unsigned long attr = map_mk_attr(MAP_PTL_PAGES, MAP_TYPE_RAM, MAP_AP_KRW_URO,

 MAP_FLAG_CACHEABLE | MAP_FLAG_SHAREABLE);

arg.v_start = 0x60050000;

arg.p_start = 0x60000000;

arg.map_size = 0x1000;

arg.attr = attr;

以上的代码就是表示将虚拟地址从0x60050000映射到物理地址0x60000000,连续映射一个页,也就是大小为0x1000(4096字节),属性为KRW,表示内核可读写,URO表示用户态可读可写。

2. 四种权限的测试

2.1读权限测试

unsigned long attr = map_mk_attr(MAP_PTL_PAGES, MAP_TYPE_RAM, MAP_AP_KRW_URO,

 MAP_FLAG_CACHEABLE | MAP_FLAG_SHAREABLE);

arg.v_start = 0x60050000;

arg.p_start = 0x60000000;

arg.map_size = 0x1000;

arg.attr = attr;

如以上代码:建立映射0x60050000到0x60000000,大小为4096字节,MAP属性为URO,也就是用户态只读。

测试方法:用户态读取地址0x60050000的值,预期可以成功。然后向地址0x60050000写入任意值,比如1,预期会失败,抛出异常。

2.2读写测试

unsigned long attr = map_mk_attr(MAP_PTL_PAGES, MAP_TYPE_RAM, MAP_AP_KRW_URW,

 MAP_FLAG_CACHEABLE | MAP_FLAG_SHAREABLE);

arg.v_start = 0x60050000;

arg.p_start = 0x60000000;

arg.map_size = 0x1000;

arg.attr = attr;

如以上代码:建立映射0x60050000到0x60000000,大小为4096字节,MAP属性为URW,也就是用户态读、写。

测试方法:用户态读取地址0x60050000的值,预期可以成功。然后向地址0x60050000写入任意值,比如1,预期会成功,无任意异常。

2.3读写可执行测试

unsigned long attr = map_mk_attr(MAP_PTL_PAGES, MAP_TYPE_RAM, MAP_AP_KRW_URW,

 MAP_FLAG_CACHEABLE | MAP_FLAG_SHAREABLE | MAP_FLAG_EXECUTABLE);

arg.v_start = 0x60050000;

arg.p_start = 0x60000000;

arg.map_size = 0x1000;

arg.attr = attr;

如以上代码:建立映射0x60050000到0x60000000,大小为4096字节,MAP属性为URW,也就是用户态读、写,同时指定EXECUTABLE(可执行)属性。

测试方法:用户态读取地址0x60050000的值,预期可以成功。然后向地址0x60050000写入return指令的机器码,预期会成功,最后跳到地址0x60050000执行,由于写入的是return指令,所以预期执行完该代码,就会返回主调用线程,最后正确结束测试,无异常。

2.4不可访问测试

unsigned long attr = map_mk_attr(MAP_PTL_PAGES, MAP_TYPE_RAM, MAP_AP_KRW_UNA,

 MAP_FLAG_CACHEABLE | MAP_FLAG_SHAREABLE );

arg.v_start = 0x60050000;

arg.p_start = 0x60000000;

arg.map_size = 0x1000;

arg.attr = attr;

如以上代码:建立映射0x60050000到0x60000000,大小为4096字节,MAP属性为UNA,也就是用户态NO ACCESS(无法访问)。

测试方法:用户态读取地址0x60050000的值,预期会直接抛出异常,因为该地址的MAP属性是无法访问。

好啦,以上就是对使用内存MAP测试MMU权限的全部介绍,快动手尝试一下吧!有疑问欢迎在评论区留言讨论哦~

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
1
分享
返回顶部
顶部