博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Uboot的bad_save_user_regs
阅读量:6829 次
发布时间:2019-06-26

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

下面是一个宏定义,从名字“bad_save_user_regs”就可以猜测它是用来保存程序“出错”时用户态的寄存器的值。从下面的“use bad_save_user_regs for abort/prefetch/undef/swi ...”可以知道,这些“错误”是就是发生abort、prefetch、undef、swi异常时。为什么我把“出错”、“错误”加上引号?因为这些“错误”,有时候是故意加入的,就是为了触发异常处理程序,从而完成某些事情,比如:系统调用就是通过swi异常实现的。CODE:                                                       .macro bad_save_user_regs                           //bad_save_user_regs为宏名字sub sp, sp, #S_FRAME_SIZE                           // 这个宏既然是用来“保存寄存器”的,那保存在哪呢?自然是保存在“栈”中:先令sp指针自减S_FRAME_SIZE                                                    // 这些被保存的寄存器称为“帧”,它们的总长度是S_FRAME_SIZEstmia sp, {r0 - r12}                                @ Calling r0-r12                                                     // 这句话就是保存,把r0至r12保存到SP中,stmia sp中的ia表示,sp的值increase after save,                                                     //就是保存一个,就增加4个字节。所以,r0 - r12这13个寄存器就被从下到上保存在刚刚划出的大小为                                                    //S_FRAME_SIZE的这段空间里了                                                    // 要注意的是,这句指令执行完后,sp的值又恢复成原值,就是“sub sp, sp, #S_FRAME_SIZE”后的值                                                    // 这小段代码,都是计算发生“abort stack”的值                                        ldr r2, _armboot_start                              // r2等于_armboot_start所指向的值,就是u-boot在内存中存放的开始地址, 就是0x33f80000sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)                                                       //0x33f80000 - (CONFIG_STACKSIZE+CFG_MALLOC_LEN):                                                     //CONFIG_STACKSIZE是正常程序运行时的栈大小,CFG_MALLOC_LEN是堆的大小sub r2, r2, #(CFG_GBL_DATA_SIZE+8)                  @ set base 2 words into abort stack                                                     // CFG_GBL_DATA_SIZE是一个全局变量的大小,8:两个字,用来存放发生这些异常时的pc、cpsr寄存器                                             ldmia r2, {r2 - r3}                                 @ get pc, cpsr                                                    // 把发生异常时,使用get_bad_stack保存的pc、cpsr寄存器加载到r2,r3add r0, sp, #S_FRAME_SIZE  @ restore sp_SVC         // r0=原来的SP值add r5, sp, #S_SP                                   // 从这句指令看,原来SP之上,也是用来保存寄存器的                                                    // S_SP等于52,表示“原来SP + 52”的地方,是保存sp寄存器mov r1, lr                                          // r1=lrstmia r5, {r0 - r3}                                 @ save sp_SVC, lr_SVC, pc, cpsr                                                    // “原来SP + 52”的地方 存入 r0,即“原来的SP值”,就是sp_SVC,即被中断时的SP值                                                    // “原来SP + 56”的地方 存入 r1,即lr,就是lr_SVC,即被中断时的lr值                                                    // “原来SP + 60”的地方 存入 r2,即pc,就是“使用get_bad_stack保存的pc”,即被中断时的pc值                                                    // “原来SP + 64”的地方 存入 r3,即cpsr,就是“使用get_bad_stack保存的cpsr”,即被中断时的cpsr值                                                    // 52、56、60、64对应S_SP、S_LR、S_PC、S_PSRmov r0, sp                                          // r0=sp.endm http://blog.csdn.net/ltt305210390/article/details/9270181

 

你可能感兴趣的文章
WCF 第二章 契约 同步请求回复操作
查看>>
Python3 Socket网络编程
查看>>
山泉戒
查看>>
Message Decoding
查看>>
EL表达式产生了DOM对象
查看>>
iOS开发数据库篇—FMDB简单介绍
查看>>
app测试更多机型系统解决方法
查看>>
winxp sp2下安装.net framework失败解决方法
查看>>
python-pcap模块解析mac地址
查看>>
LeeCode-Rotate Array
查看>>
JS封装动画框架,网易轮播图,旋转轮播图
查看>>
前端项目微金所1 - bootstrap模板,Compatible(兼容),Viewport(视口),条件注释,第三方依赖,MediaQuery媒体查询...
查看>>
【java】java学习之路-06-MySQL(四)
查看>>
解决myeclipse部署web项目时报错
查看>>
使用REGINI修改注册表权限
查看>>
关于二进制的利用
查看>>
进程关系
查看>>
非阻塞套接字实现并发处理
查看>>
[leetcode] 一些会的
查看>>
程序员的能力模型与沟通技巧
查看>>