博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OK6410A 开发板 (八) 54 linux-5.11 OK6410A 缺页异常实例分析
阅读量:4285 次
发布时间:2019-05-27

本文共 4070 字,大约阅读时间需要 13 分钟。

abort 异常解读(Prefetch Abort & Data Abort)

instruction fetch memory abortdata access memory abort
  • 中止
在 内存访问流程中 ,ARM处理器可能会发生异常异常的原因是中止(异常的访问),中止分为三种:	MMU faults(4种)			MMU检测到限制并向处理器发送信号。	Debug abort			监视器调试模式已启用,并且检测到断点或监视点。	External abort(三种)			外部内存系统发出非法或错误的内存访问信号。
  • 中止产生了什么异常
MMU faults		如果中止的内存请求是指令获取,则当处理器尝试执行与中止的访问对应的指令时,将引发预取中止异常。		如果中止的访问是数据访问或缓存维护操作,则会引发数据中止异常。	Debug event		当启用监视调试模式时 , 可以由于 指令访问上的breakpoint  而执行中止, 产生 预取中止异常		当启用监视调试模式时 , 可以由于 数据访问上的watchpoint  而执行中止, 产生 数据中止异常	External abort		指令获取时的外部中止 , 可能会产生 预取中止异常(依据是否执行)		数据读/写时外部中止 , 会产生 数据中止异常		硬件页表遍历上的外部中止 , 会产生 数据中止异常

案例

本次案例是匿名缺页,会产生	 MMU faults 中的 下面哪一种? (alignment fault/translation fault/domain fault/permission fault)	 因为 没有做映射,所以应该是 translation fault ,// TODO此时是访问数据,从而导致 数据中止异常
  • 应用程序
// mmap (因为mmap比malloc简单)// A1. 私有匿名映射	: 用于 分配大块内存(128KB及以上)// fd = -1 flags=MAP_ANONYMOUS|MAP_PRIVATE#include 
#include
#include
int main(int argc, char *argv[]) {
char *m; size_t s = 256 * 1024; // 此时会进入 系统调用 mmap // 做 虚拟内存的申请 m = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS , -1, 0); if (m == MAP_FAILED) {
perror("map mem"); m = NULL; return 1; } printf("mmap alloc memory ok, press ENTER to acess memory!\n"); getchar(); // 此时会 进入异常 data abort // 每访问一页,就会进入一次异常 // 进入的时候 , 会调用 do_anonymous_page 为 4KB 虚拟地址 // 1. 做 物理页的申请 alloc_zeroed_user_highpage_movable // 2. 做 虚拟内存与物理内存的映射 set_pte_at memset(m, 0, s); printf("mmap acess memory ok, press ENTER to quit!\n"); getchar(); munmap(m, s); return 0;}

A mmap 系统调用及返回

file->f_op->mmap 没有申请物理内存,没有做映射,而是在 file->f_op->mmap 中设置了 vma->ops = &my_file_mmap

B 访存

访存的动作 是 在用户空间做的例如 *p 就是访存动作这个动作做完之后,就会产生一个 data abort 异常

C data abort 异常硬件流程

访存(访问存储器) 时发生异常,armv6 会	1.设置 FSR // Fault Status Register	存储失效的相关信息(包括存储访问所属区域和访问类型)	2.设置 FAR // Fault Address Register 存储访问失效的虚拟地址	R14_abt = address of the aborted instruction + 8	SPSR_abt = CPSR	CPSR[4:0] = 0b10111 		/* Enter Abort mode */	CPSR[5] = 0 				/* Execute in ARM state */								/* CPSR[6] is unchanged */	CPSR[7] = 1 				/* Disable normal interrupts */	CPSR[8] = 1 				/* Disable Imprecise Data Aborts (v6 only) */	CPSR[9] = CP15_reg1_EEbit 	/* Endianness on exception entry */	if high vectors configured then	PC = 0xFFFF0010	else	PC = 0x00000010

D linux-5.11 对 data abort 异常的处理

  • level 1
__vectors_start	vector_dabt		__dabt_usr/__dabt_svc			dabt_helper				CPU_DABORT_HANDLER/v7_early_abort
  • level 2
v7_early_abort	mrc c5 // 读 c5	mrc c6 // 读 c6	do_DataAbort		fsr_info[0...4] // exceptions_init 注册了 do_translation_fault // hook_fault_code(4, do_translation_fault, SIGSEGV, SEGV_MAPERR, "I-cache maintenance fault");			do_translation_fault
  • level 2
do_translation_fault	do_page_fault // 缺页异常 的 核心函数		__do_page_fault			handle_mm_fault				__handle_mm_fault					handle_pte_fault						do_anonymous_page		__do_user_fault		// 用户空间访问 0地址时会出现这种情况		__do_kernel_fault  	// 内核空间访问 0地址是会出现这种情况	A 针对 匿名页面缺页异常 do_anonymous_page		有虚拟地址,没有映射,没有物理地址		应用场景 : malloc // 匿名页面(没有关联到文件映射的页面)在访问地址时会导致内存访问异常, 流程中会调用 do_anonymous_page
  • level 3
// 每一次进入do_anonymous_page  做 一页的映射// 多次 进入之后,发现// 同一个进程,同一个vma,虚拟地址地址越来越高,page地址越来越低(物理地址越来越低) // 此时无法用 page_to_phys(page) 打印物理地址,但是 struct page 的地址 都是间隔 0x20,说明 物理地址是连续的// pmd 是一样的,pmd 中是 页表基址寄存器 的值// page_table 是 一级页表的地址do_anonymous_page (mm=0xee11e540, vma=0xeeb02738, address=3069333504, page_table=0xee13c494, pmd=0xedc0edb8, flags=85)	page = alloc_zeroed_user_highpage_movable(vma, address);	(struct page *) 0xef019cc0	// 物理地址 : TODOdo_anonymous_page (mm=0xee11e540, vma=0xeeb02738, address=3069337600, page_table=0xee13c498, pmd=0xedc0edb8, flags=85)	page = alloc_zeroed_user_highpage_movable(vma, address);	(struct page *) 0xef019ca0	do_anonymous_page (mm=0xee11e540, vma=0xeeb02738, address=3069341696, page_table=0xee13c49c, pmd=0xedc0edb8, flags=85)	page = alloc_zeroed_user_highpage_movable(vma, address);	(struct page *) 0xef019c80

转载地址:http://ajigi.baihongyu.com/

你可能感兴趣的文章
限制 EditText 最多输入两位小数
查看>>
Android中attrs.xml文件的使用详解
查看>>
TabLayout 解析
查看>>
android获取屏幕尺寸、密度(判断手机屏幕类型)
查看>>
dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算
查看>>
Android drawable 目录下不同精度 浅析
查看>>
Drawable 文件夹——xml文件
查看>>
OkHttp 新手上路
查看>>
Android 蓝牙如何使用
查看>>
自定义View三个方法的意义
查看>>
Java访问控制的作用
查看>>
横竖屏切换的生命周期
查看>>
广播的使用
查看>>
Python Requests库
查看>>
下载离线 Visual Studio 离线安装包
查看>>
Makefile Project 中 MSBuild MSB3073 error 不能正确检测字符串 “error:"
查看>>
Error Code 0x800F081F when Installing .NET Framework 3.5
查看>>
Xamarin.Forms.Xaml.XamlParseException: No embeddedresource found for
查看>>
如何 禁掉 Hyper-V && 如何解决禁不掉 Hyper-V 的问题
查看>>
杂记 7/30
查看>>