没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
实验 4 基于内核栈切换的进程切换
实验目的
� 深入理解进程和进程切换的概念;
� 综合应用进程、CPU 管理、PCB、LDT、内核栈、内核态等知识解决实际
问题;
� 开始建立系统认识。
实验内容
� 编写汇编程序 switch_to:
� 完成主体框架;
� 在主体框架下依次完成 PCB 切换、内核栈切换、LDT 切换等;
� 修改 fork(),由于是基于内核栈的切换,所以进程需要创建出能完成内
核栈切换的样子。
� 修改 PCB,即 task_struct 结构,增加相应的内容域,同时处理由于修
改了 task_struct 所造成的影响。
� 用修改后的 Linux 0.11 仍然可以启动、可以正常使用。
� (选做)分析实验 3 的日志体会修改前后系统运行的差别。
实验报告
问题 1
针对下面的代码片段:
movl tss,%ecx
addl $4096,%ebx
movl %ebx,ESP0(%ecx)
回答问题:
� (1)为什么要加 4096;
� (2)为什么没有设置 tss 中的 ss0。
问题 2
针对代码片段:
*(--krnstack) = ebp;
*(--krnstack) = ecx;
*(--krnstack) = ebx;
*(--krnstack) = 0;
� (1)子进程第一次执行时,eax=?为什么要等于这个数?哪里的工作
让 eax 等于这样一个数?
� (2)这段代码中的 ebx 和 ecx 来自哪里,是什么含义,为什么要通
过这些代码将其写到子进程的内核栈中?
� (3)这段代码中的 ebp 来自哪里,是什么含义,为什么要做这样的
设置?可以不设置吗?为什么?
问题 3
为什么要在切换完 LDT 之后要重新设置 fs=0x17?而且为什么重设操作要出
现在切换完 LDT 之后,出现在 LDT 之前又会怎么样?
1.%ebx 指向 PCB 的起始地址,分配给 PCB 的大小是 4KB,加上 4096 就指向高
位置也就是空栈时内核栈栈顶的位置。
2.内核栈段的 ss0 永远都是 0x10,所以不用修改。
1.等于 0,用来区分父进程和子进程,p->tss.eax = 0(修改前)或者*(--
krnstack) = 0(修改后)。
2.来自 sys_fork 压入栈的函数值,就是进入内核态前这两个寄存器的值,为
了在返回时恢复现场。
3.来自 sys_fork 的 pushl %ebp 操作,不能,因为后面 copy_process 还要
用到%ebp。
因为如果不重新设置,则 fs 的隐藏部分存放的就是上一个进程的用户态的基
地址和段限长,会产生错误的段属性值。若先设置在切换 LDT,就会在切换
前的进程中进行操作,导致以后访问空间的之前进程的用户空间。
实验步骤
1. 重写 sched.c 中的 schedual 函数,注意实验手册中 LDT 应为_LDT,注意
pnext 的初始值,网上的大部分实验报告写的是 current,这样不对,应该
为&(init_task.task)
Pnext 的值
效果
不设初值
无限重启
NULL
报错如下图
Current
看起来正常,但无法输入指令
直 接 用
switch_to(task[next],_LDT(next));
无限重启
&(init_task.task)
正常
剩余17页未读,继续阅读
资源评论
我慢慢地也过来了
- 粉丝: 5856
- 资源: 3759
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功