当前位置: 首页 > news >正文

wdcp 网站建设北京大兴网站建设公司哪家好

wdcp 网站建设,北京大兴网站建设公司哪家好,销售管理crm,专业积分商城网站建设文章目录 一、RISC-V assembly简介问题 二、Backtrace简介注意实验代码实验结果 三、Alarm简介注意实验代码实验结果 一、RISC-V assembly 简介 git checkout traps#xff0c;切换到traps分支user/call.c 文件在我们输入 make fs.img 之后会被汇编为 call.asm 文件#xf… 文章目录 一、RISC-V assembly简介问题 二、Backtrace简介注意实验代码实验结果 三、Alarm简介注意实验代码实验结果 一、RISC-V assembly 简介 git checkout traps切换到traps分支user/call.c 文件在我们输入 make fs.img 之后会被汇编为 call.asm 文件阅读该汇编文件中的函数f、h、maincall.c 中的代码比较简单 #include kernel/param.h #include kernel/types.h #include kernel/stat.h #include user/user.hint g(int x) {return x3; }int f(int x) {return g(x); }void main(void) {printf(%d %d\n, f(8)1, 13);exit(0); }问题 我们需要回答以下问题 哪些寄存器用于传参 例如main 函数调用 printf 时持有13 这个参数 RISC-V 寄存器作用如下图 通过main函数的汇编代码可以知道参数 13 使用 a2 寄存器传递 main函数对应的汇编代码在哪里调用了函数f 函数 g 的调用在哪里编译器可能会优化某些函数为内联函数 由问题一查看的汇编可知main函数并未调用函数 f而是直接由编译器优化得到了结果printf 函数的地址是什么 printf 的地址为 0x64a虚拟地址main 函数中的调用也能说明这一点 main 函数中使用 jalr 到 printf 之后ra寄存器的值是什么 jalr 指令执行时会将 pc 4 的值存放到 ra 寄存器中作为返回地址因此ra的值为 0x38运行下面的代码输出是什么输出取决于大小端RISC-V为小端模式如果是大端相同输出需要将 57616 改为多少 unsigned int i 0x00646c72;printf(“H%x Wo%s”, 57616, i);输出为He110 World因为57616对应16进制的 0xe1100x00646c72 以小端存储实际为 0x6c720064,0x6c对应r0x72对应 l0x64对应d00代表NULL不显示。如果是大端则高地址在高处因此应该存储为 0x6c720064 或者 0x6c7264 下面的代码y后面的输出是什么为什么 printf(“x%d y%d”, 3);输出为乱码因为参数传递时使用的寄存器是确定的因此如果第二个参数不传递依然还是会用a2寄存器传递此时a2中的值是caller中的残留值 二、Backtrace 简介 当发生错误时打印当前的调用栈。每个函数栈帧包含一个返回地址以及一个指向caller栈帧的 frame pointer我理解就是caller的rsp 在kernel/printf.c 中实现一个 backtrace()在 sys_sleep 中插入对该函数的调用然后运行 bttest该用户程序会调用 sleep 系统调用此时应该打印堆栈 bttest 在qemu中执行完毕之后新开一个窗口执行 addr2line -e kernel/kernel (or riscv64-unknown-elf-addr2line -e kernel/kernel)将有如下输出 阅读kernel/sysproc.c:74、kernel/syscall.c:224、kernel/trap.c:85 注意 kernel/defs.h 中添加 backtrace() 函数的声明gcc产生汇编时会将栈指针存放在 s0 寄存器在kernel/riscv.h 中添加如下代码 static inline uint64 r_fp() {uint64 x;asm volatile(mv %0, s0 : r (x) ); //含义为读取 s0 寄存器中的值赋值给 x 并返回 xreturn x; }返回地址位于栈指针 - 8的位置保存的栈指(caller的栈指针地址)针位于当前函数的栈指针的-16处栈指针即 rbp你需要识别最后一个栈帧并结束由于函数栈最大为4KB因此可以使用 PGROUNDDOWN(fp) (see kernel/riscv.h) 来判断是否到达最后一个函数栈 实验代码 思路 1、首先 kernel/riscv.h 添加要求的代码kernel/defs.h 声明 backtrace() 2、 backtrace() 的逻辑为使用 r_fq() 获取当前栈指针打印栈指针 - 8 的地址(即调用栈)并 -16得到上一个栈帧的地址依次类推直到地址等于 PGROUNDDOWN(fp) (see kernel/riscv.h) kernel/riscv.h static inline uint64 r_fp() {uint64 x;asm volatile(mv %0, s0 : r (x) ); //含义为读取 s0 寄存器中的值赋值给 x 并返回 xreturn x; }kernel/defs.h void backtrace(void);kernel/printf.c void backtrace(void){// 获取当前栈帧uint64 addr r_fp();// 向上遍历while(addr ! PGROUNDDOWN(addr)){printf(%p\n, *(uint64 *)(addr - 8));addr *(uint64 *)(addr - 16);} }kernel/sysproc.c uint64 sys_sleep(void) {int n;uint ticks0;argint(0, n);//...其他代码backtrace();return 0; }实验结果 三、Alarm 简介 添加一项新的功能定时报警即简单的用户级中断/故障处理程序。为以后缺页中断打下基础。 添加一个新的系统调用 sigalarm(interval, handler)如果用户态应用调用 sigalarm(n, fn)那么每当该程序消耗 n 个cpu ticks内核会调用一次 fn 。当调用 sigalarm(0, 0) 时停止。 注意 makefile 中添加 user/alarmtest.c正确的结果输出如下 实验代码 思路proc中添加三个字段分别记录用户设置的tickscur_ticks以及callback系统调用则是设置进程的 ticks 以及callback在处理时钟中断时给当前的进程cur_ticks 加1判断和ticks是否相等相等则调用callback。 时钟中断的处理函数为 clockintr(),当用户态进程运行时来了时钟中断调用路径为usertrap---判断类型---devintr 详细流程参考 xv6-book 第四章 trap发生时 cpu 硬件会做一些准备 (book:44页)该步骤设置了SIE位 保存 pc设置trap原因进入内核态但是不切换内核页表以及内核栈执行 trap 处理函数(stvec寄存器保存的地址) 如果是在用户态发生 trap此时处理函数为 uservec该函数保存了用户寄存器以及其他状态切换内核页表所以trap发生时硬件只保证切换到内核态即cpu设置为管理模式但是并不会切换页表切换页表是在trap处理函数中做的最后跳转到 usertrap()执行。 因此我们需要在 usertrap 函数中添加对于时钟中断的判断逻辑以及用户callback的调用逻辑需要保证不可重入即我们如果在执行 callback 的时候再次被时钟中断trap此时不应该再次执行callback所以还需要在proc.h中添加一个字段用于防止重入。usertrap中本身有对于时钟中断的判断逻辑即进程调度的部分具体代码如图所以照猫画虎即可 最后还有一点需要注意我们的callback函数是应该在用户态运行的(因为内核态无法解析用户态的虚拟地址所以无法调用callback)此时我们处于内核态因此我们需要保存上下文切换到用户态执行完callback之后切换回内核态恢复上下文继续usertrap的执行。 如何切换到内核态呢此时我们借助 usertrapret() 来返回用户态所以我们需要更改trap的返回地址当前 trap 的返回地址为 p-trapframe-epc 4;(kernel/trap.c:61)。所以我们首先保存一下当前 trapframe然后更改 trapframe-epc callback这样在 usertrapret() 返回用户态后执行的就是 callback 函数此时需要注意callback函数是不能有参数的因为这不是正常的函数调用 callback执行成功了但是我们该如何返回到用户态代码原先的地方执行呢 因此实验测试代码中提供了另外一个系统调用 sigreturn()来让我们重新回到内核态恢复进入 trap 时的用户上下文在这一次的 usertrapret() 返回到用户进程原先执行的地方。xv6 设计的中断、系统调用走相同的调用路径因此这里可以执行这样的骚操作。 总体流程 用户态程序用户态程序 — 时钟中断 -- usertrap() (p-trapframe-epc 保存用户态程序的下一条执行语句) — 保存trapframe 到另外一个地方(假设为A) — 更改 p-trapframe callback — usertrapret() 返回用户态执行callback — 通过sigreturn() 重新进入trap流程 — 此时走系统调用路径 ---- sys_sigreturn() 恢复 p-trapframe 为最开始保存的(从A处读取) —usertrapret() 返回用户态trap中断处继续执行一次 alarm trap 需要往返内核态两次 代码 kernel/proc.h // Per-process state struct proc {struct spinlock lock;//新增字段int ticks; //回调执行所需要ticksint cur_ticks; //当前进程的ticksvoid* callback; //回调函数struct trapframe backup; //保存trapframeint execing; //是否已经在执行了makefile UPROGS\$U/_alarmtest\user/user.h int sigalarm(int ticks, void (*callback)()); int sigreturn(void);user/usys.pl entry(sigalarm); entry(sigreturn);kernel/syscall.h #define SYS_sigalarm 22 #define SYS_sigreturn 23kernel/syscall.c extern uint64 sys_mkdir(void); extern uint64 sys_close(void); //新增 extern uint64 sys_sigalarm(void); extern uint64 sys_sigreturn(void);static uint64 (*syscalls[])(void) { //其他 [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, // 新增 [SYS_sigalarm] sys_sigalarm, [SYS_sigreturn] sys_sigreturn, };kernel/sysproc.c uint64 sys_sigalarm(void){int ticks 0;uint64 callback 0;argint(0,ticks);argaddr(1, callback);struct proc* proc myproc();proc-ticks ticks;proc-callback (void *)callback;proc-execing 0;return 0; }uint64 sys_sigreturn(void){struct proc* proc myproc();*(proc-trapframe) proc-backup;proc-execing 0;// 由于该函数返回后返回值保存在a0中会覆盖trapframe中原来的a0// 该函数返回之后就会走 usertrapret() 返回到用户态return proc-trapframe-a0; }kernel/trap.c if(killed(p))exit(-1);// 新增代码 if(which_dev 2){struct proc* proc myproc();// 设置了ticks 且没有执行if(proc-ticks 0 proc-execing 0){proc-cur_ticks;if(proc-cur_ticks proc-ticks){proc-execing 1;proc-backup *(proc-trapframe); //保存trapframeproc-trapframe-epc (uint64)proc-callback;proc-cur_ticks 0;}}}// 新增结束// give up the CPU if this is a timer interrupt.if(which_dev 2)yield();实验结果 make qemu ./grade-lab-traps running alarmtest
http://www.zqtcl.cn/news/165562/

相关文章:

  • 网站建设费用标准做网站怎么盈利
  • 仕德伟做的网站图片怎么修initial wordpress
  • 网站制作公司多少费用正规的机械外包加工订单网
  • 网站的维护和推广2345网址大全设主页访问
  • 天津商城网站建设公司如何申请注册企业邮箱
  • 做家旅游的视频网站好给我一个可以在线观看的免费
  • 香奈儿网站建设做网站应该问客户什么需求
  • 永久免费ppt下载网站互联网上市公司一览表
  • 甘肃省建设工程168网站东营智能网站设计
  • 网站跨机房建设方案山西运城市建设局网站
  • 网站被k文章修改设计师图片素材
  • 建设银行益阳市分行桃江支行网站9377烈焰传奇手游官网
  • 网站收费怎么做沈阳建设工程信息网 等级中项网
  • 做网站后台教程视频杭州网站开发建设
  • 维度 网站建设优秀vi设计网站
  • 快速搭建网站工具海洋网络做网站不负责
  • 做电影资源网站服务器怎么选wordpress唱片公司模板
  • 医院网站建设投标要求wordpress文章的表是什么
  • 怎么做网站后门海外营销推广
  • 网站建设中英版网站要做手机版怎么做的
  • 安徽网站开发与维护专业阜阳建设部网站
  • 山东省住房和建设厅网站网站优化大计
  • 大良建网站织梦建设两个网站 视频
  • 用html5制作个人网站航空港建设局网站
  • 祥云平台建站网站备案通过什么可以备案
  • 免费建造网站系统php和wordpress
  • 九脉堂是做网站的网站权重不稳定
  • 网站怎么做来流量门户网站的发布特点
  • 网站设计相似侵权吗免费游戏网站建设
  • 湖北长安建设网站制作一个网站的步骤是什么