实验目的
深入理解进程和进程切换的概念;
综合应用进程、CPU 管理、PCB、LDT、内核栈、内核态等知识解决实际问题;
开始建立系统认识。修改sheddule函数
修改sched.h
实现swtitch_to函数
注释掉switch_to部分
修改fork.c
编译
启动
(一)movl tss,%ecx addl $4096,%ebx movl %ebx,ESP0(%ecx) copy (1)为什么要加 4096;(2)为什么没有设置 tss 中的 ss0。
答:(1)4096 = 4KB。在linux0.11中,一个进程的内核栈和该进程的PCB段是放在一块大小为4KB的内存段中的,其中该内存段的高地址开始是内核栈,低地址开始是PCB段。ebx是指向一个进程的PCB,偏移4096后便指向了另一个进程的PCB。
(2)tss.ss0是内核数据段,现在只用一个tss,因此不需要设置了
(二) 针对代码片段:*(--krnstack) = ebp; *(--krnstack) = ecx; *(--krnstack) = ebx; *(--krnstack) = 0; (1)子进程第一次执行时,eax=?为什么要等于这个数?哪里的工作让 eax 等于这样一个数?(2)这段代码中的 ebx 和 ecx 来自哪里,是什么含义,为什么要通过这些代码将其写到子进程的内核栈中?(3)这段代码中的 ebp 来自哪里,是什么含义,为什么要做这样的设置?可以不设置吗?为什么? 答:(1)eax =0。为了与父进程区分开 copy_process(),成功初始化进程copy_process后赋值eax得到。
(2)ebx和ecx来自copy_process()的形参,形参的来源是各个段寄存器。对于fork函数而言,子进程是父进程的拷贝,就是要让父子进程共用同一个代码、数据和堆栈。
(3)ebp是用户栈地址,一定要设置,不设置子进程就没有用户栈了
(三) 为什么要在切换完 LDT 之后要重新设置 fs=0x17?而且为什么重设操作要出现在切换完 LDT 之后,出现在 LDT 之前又会怎么样? 这两句代码的含义是重新取一下段寄存器fs的值,这两句话必须要加,也必须要出现在切换完LDT之后,这是因为通过fs访问进程的用户态内存,LDT切换完成就意味着切换了分配给进程的用户态内存地址空间,所以前一个fs指向的是上一个进程的用户态内存,而现在需要执行下一个进程的用户态内存,所以就需要用这两条指令来重取fs。 出现在LDT之前访问的就还是上一个进程的用户态内存。
学习时间 116分钟
操作时间 63分钟
按键次数 704次
实验次数 6次
报告字数 2057字
是否完成 完成