课后作业4.2:页式内存管理

第1关:页目录和页表的变化

本关任务:

1.在 1 号进程第 1 次开始执行 output_char 函数调用时,线性地址空间到物理地址空间的映射关系是怎样的?

2.在 1 号进程第 2 次开始执行 output_char 函数调用时,线性地址空间到物理地址空间的映射关系是怎样的?

3.在 1 号进程的第 1、2 次 output_char 函数调用之间,页目录和页表发生了怎样的变化?

前面已经做过许多次在gdb模式下获取线性地址,这里不再描述,直接从bochsdbg模式开始。依旧是在0x69d9处打断点,并查看页目录地址

如果要查看分析线性地址空间到物理地址空间的映射关系,有两种方法,我采用的是比较简单的使用info tab命令,显示虚拟地址的映射情况(两次调用基本一致,仅以第一次为例)

还有一种较为复杂的方法可以采用,首先分析页目录中的每个有效的页目录项,找到所有二级页表的首地址;然后分析每一个二级页表,查看其中有效的页表项,计算出页面与页帧之间的对应关系。最后的映射关系类似描述如下:

至于页目录和页表发生了怎样的变化,就是存放mynext物理地址的页表项的值发生了数值变化。

最终答案:

在 1 号进程第 1 次开始执行 output_char 函数调用时,线性地址空间到物理地址空间的映射关系是怎样的?

1.(0x00000000-0x00ffffff->0x00000000-0x00ffffff)

2.(0x04000000-0x04024fff->0x00000000-0x00024fff)

3.(0x04025000-0x04025fff->0x00ffd000-0x00ffdfff)

4.(0x04026000-0x0409ffff->0x00026000-0x0009ffff)

在 1 号进程第 2 次开始执行 output_char 函数调用时,线性地址空间到物理地址空间的映射关系是怎样的?

5.(0x00000000-0x00ffffff->0x00000000-0x00ffffff)

6.(0x04000000-0x04021fff->0x00000000-0x00021fff)

7.(0x04022000-0x04022fff->0x00ffc000-0x00ffcfff)

8.(0x04023000-0x04024fff->0x00023000-0x00024fff)

9.(0x04025000-0x04025fff->0x00ffd000-0x00ffdfff)

10.(0x04026000-0x0409ffff->0x00026000-0x0009ffff)

在 1 号进程的第 1、2 次 output_char 函数调用之间,页目录和页表发生了怎样的变化?

11.页表项(0x00ffe088)的值由原来的(0x00022065)变为了(0x00ffc067)

第2关:用户栈和核心栈的物理位置

本关任务:

使用版本 1 内核时,在第 2 次进程调度后:

1. 0 号进程和 1 号进程的进程控制块的地址分别是多少?

2.执行到函数 task0 时,0 号进程的用户栈栈顶位于物理内存何处?

3.0 号进程执行到函数 sys_pause 时,核心栈栈顶位于物理内存何处?

4.执行到函数 task1 时,1 号进程的用户栈栈顶位于物理内存何处?

5.1 号进程执行到函数 sys_pause 时,核心栈栈顶位于物理内存何处?

在 bochsdbg 中,如何跟踪到第 2 次进程调度

首先查看函数 schedule 的地址,然后在该处设断点,并跟踪到此断点第 2 次出现。

在gdb模式下

得出0号进程和1号进程控制块的地址分别是0x1ea20、0xfff000我们在bochsdbg模式下就是根据这个判断进程号

在 bochsdbg 调试模式下,如何判断当前进程是几号进程

可以先在 gdb 调试模式下确定全局变量 current 的地址和 0 号进程的进程控制块的地址:

在上图中,0 号进程的进程控制块的地址是 0x1ea20 。

然后,在 bochsdbg 调试时,可以查看变量 current 的值,进而判断是不是在 0 号进程里

如何得到一个函数的地址

可以直接查看符号文件,如下所示:

可见函数 task0 的地址为 0x7963 。

我们先查看各个函数的地址信息

然后进入bochsdbg模式,在shedule(0x6d93)处打断点并连续c两次

然后把上面的断点关闭,在task0函数设断点(0x7963),并判断是否为进程0

如何知道当前栈顶的物理位置

当前栈顶的逻辑地址是 $ss:$esp ,只需要将这个地址转换为线性地址,并进而转换为物理地址即可。

那我们先用sreg命令和reg命令查看寄存器的值,求出逻辑地址

可以看到它的逻辑地址是0x2573c

之后求出其对应的物理地址

计算得出物理地址为0x2573c

剩下的几个问题和第一个问题类似,继续照着往下做即可,就不在此详解。

最终答案:

使用版本 1 内核时,在第 2 次进程调度后:

1.0 号进程和 1 号进程的进程控制块的地址分别是多少?(0x1ea20)(0xfff000)

2.执行到函数 task0 时,0 号进程的用户栈栈顶位于物理内存何处?(0x2573c)

3.0 号进程执行到函数 sys_pause 时,核心栈栈顶位于物理内存何处?(0x1f9f0)

4.执行到函数 task1 时,1 号进程的用户栈栈顶位于物理内存何处?(0xffd73c)

5.1 号进程执行到函数 sys_pause 时,核心栈栈顶位于物理内存何处?(0xffffd0)

猜你喜欢

转载自blog.csdn.net/z671514087/article/details/128387486