没有合适的资源?快使用搜索试试~ 我知道了~
JOS LAB2实验记录
4星 · 超过85%的资源 需积分: 9 41 下载量 98 浏览量
2010-11-20
17:05:14
上传
评论 1
收藏 1.79MB DOC 举报
温馨提示
试读
16页
这是mit jos lab2 的实验记录 单位:华中科技大学集群网络与服务计算实验室 作者:卓达城
资源推荐
资源详情
资源评论
实验 2 实验记录
作者:卓达城
单位:华中科技大学集群网络与服务计算实验室
zhuodc@qq.com 欢迎来信
如果linux下不能正确浏览文档请到
http://wenku.baidu.com/view/2333d0563c1ec5da50e2703f.html
阅读
第一步:理解下面这个函数
stab_binsearch(stabs,& region_le,& region_right, type, addr)函数
This func!on is a bi*ch!!!
背景:
JOS 的作者通过 kerne.ld 把调试信息和内核一起加载到内存中去。并提供了四个相应的宏以
记录相关信息。
下图是 kernel.ld 中的代码片段:
当我们运行完虚拟机之后,调试信息和内核一起加载到 0xf0000000(virtual address)中
从以下代码片段中,我们可以找到,调试信息是如何被赋值到 stab 的:
调试信息的结构是怎么样的呢?
我们可以轻松地在代码中发现下面的结构:
但是它到底放的是什么,这令人满头雾水。
我们可以从 init.s 中找到我们想要的答案。init.s 通过命令:
gcc -pipe -nostdinc -O2 -fno-builtin -I. -MD -Wall -Wno-format -
DJOS_KERNEL -gstabs -c -S kern/init.c
生成。
观察以上代码片段:
我们把它放入 stab 结构中,我们可以知道:
n_strx 是函数名,n_type 是 36 ,n_other 是 0,n_desc 也是 0,n_value 是函数的段偏移
(eip)
观察以上代码片段:
我们可以猜测:
n_str 为 空 , n_type 为 68 , n_other 为 0, n_desc 为 行 号 ( 对 一 下 源 代 码 就 知 道 了 ),
n_value 为函数内偏移量。(I just want to say f*ck!Waste my !me for 3 hours!!!)
这就是 type 的类型,0x24 是 36,跟上面的代码片段对应。
有了以上背景知识,我们开始研究 stab_binsearch 函数
先说说这个函数的返回值和参数:
返回值:
函数成功找到代码区域就返回 0 否则返回 -1
region_le 和 region_right:根据 type 返回代码区域的起始地址。如果是函数,返回函数的起
始地址和终点地址,如果是代码,返回代码的起始地址的终点地址(翻译成汇编之后)。
如果是文件或者其它类型,同上。
参数:
stabs 调试信息的起始地址
region_le:要搜索的区域的起始地址
region_right: 要搜索的区域的终点
type:要搜索的代码类型
addr :eip
这个函数用了二分搜索法进行搜索,具体实现请看代码,比较难讲清楚,我看也看了很久
才明白其中奥妙。但是如果了解了上面的背景再看,就会事半功倍。这里的所有的 stab 已
经跟我们的代码运行顺序是一致的。
看完代码之后我们就开始实现我们的 Exercise 1,完成 debuginfo_eip 函数
首先:
在 debuginfo_eip 函数中,我看到这句代码
这句代码是判断函数名字有没有超界的。如果没有,就赋值。
这两句代码求出我们所要找的代码在具体函数中的偏移量。记着,我们前面说过,当 type
是代码的时候,n_value 表示的是偏移量。第一行代码中的 n_value 表示 addr 所在的函数的
代 码 区 域 的 首 地 址 , addr - info->eip_fn_addr 就 可 以 求 出 偏 移 量 , 下 面 就 可 以 用
stab_binsearch 函数找到具体的行号。
以下是我们要添加的代码:
按照要求,我们还要找出函数的参数个数:
所再添加如下代码,我们已经知道了 stab 的结构方式(stab 的顺序和我们的代码顺序一
样),所以以下代码及可以找出参数的个数。
然后,在 monitor.c 中加入如下代码就完成了第一个 Exercise
^^^^^^^^^^^^^^^^^^^^^^zhuodc@qq.com^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^
写到这里,我确实不想再写了,但是作为一个软件工程的学生,我深深体会到文档的
重要性,所以再写。
在开始做下面的实验之前,我们想要了解一下 JOS 的内存结构。
先从最基本的 boot.S 开始
在 boot.S 中,gdt 如下
0x00
0x08
0x10
然后系统跳转到 main.c,由于段选择符为 0x08,所以基地址为 0x0000000
JOS 把第一个扇区加载到 0x10000 处(elf),然后根据 elf 的参数把内核部分加载到
0x1000000 处,现在观察 kernel.ld,里面定义了开始地址为 0xF01000000,所以
entry.S 里面的代码的 eip 都是 0xF0100000++,然后 bootmain 的最后一句跳转到
0x10000c 处,开始执行 entry.S 的代码.
entry.S 中
一开始就 lgdt,把 gdt 变了,在 lgdt 的时候有一个宏 RELOC,这个宏的作用是把虚拟地
址转换成实地址
0xF0100000
- 0xF0000000(KERNBASE)
0x00100000
NULL
0x00000000
0x00000000
剩余15页未读,继续阅读
dachengzhuo
- 粉丝: 0
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页