昨天跟老师建议了OS实验改革的事情,感觉助教老师给的指导书挺坑哈,代码注释也不全。我也算沦落到看别人家的源码了。。。
我参考的源码注释是:https://github.com/benwei/MIT-JOS/
这个源码质量暂且不评价,但这个注释质量真心不错!!!良心注释啊!!!
本不想去找源码注释啥来看的,毕竟可能一不小心就抄袭了源码的思想?不知道HT和WLM是怎么写的,他们做的都好快啊=。=难道只有我一个人做OS实验的周期是1~2周吗...
哎,不吐槽了,这篇文章留着慢慢更,不着急。仅以此系列文章献给那些有耐心阅读OS实验源码并且渴望在其中获得精巧与奥妙的同学。
[目前处于函数上传与修改阶段,各位看客们请移驾,写好后再来咯~]
这次实验的主要内容其实就是这几个:补全系统调用,实现进程通信,实现fork函数。
首先是对系统调用整个流程的一个理解:
填过syscall_all.c的同学都知道,在每个sys_Xxxx函数中每个函数里都有一个参数叫 [int sysno],我一开始也是不理解,不知道这个参数在这么函数里出现究竟是因为啥?后来笔者仔细想了想整个架构,发现了一些端倪,先提供以下材料以供大家联想:
./lib/syscall.S
0: lw t1, TF_EPC(sp)
1: lw v0, TF_REG2(sp)
2: subu v0, v0, __SYSCALL_BASE (__SYSCALL_BASE 和 __NR_SYSCALLS 均位于 ./include/unistd.h )
3: sltiu t0, v0, __NR_SYSCALLS+1 ( sltiu的作用是,当v0<__NR_SYSCALLS+1时,置 t0 为1,说明实际上我们一共有SYSCALLS+1个系统调用)
4: addiu t1, 4 ( t1= t1 + 4 )
5: sw t1, TF_EPC(sp) ( 把t1存到epc里面去,这一点很有意思! Hint:Why?)
6: beqz t0, illegal_syscall//undef ( 如果 t0==0的话,则无效,因为其超过了系统调用数的范围,不在系统调用表内 )
7: nop
8: sll t0, v0,2 ( v0左移2位得到)
9: la t1, sys_call_table ( 把系统调用表的地址存在t1寄存器中 )
观察这段汇编指令,细细观察,发现
01
void
02
page_fault_handler(
struct
Trapframe
*
tf)
03
{
04
u_int
va;
05
u_int
*
tos
,
d;
06
struct
Trapframe
PgTrapFrame;
07
extern
struct
Env
*
curenv;
08
//printf("^^^^cp0_BadVAddress:%x\n",tf->cp0_badvaddr);
09
bcopy(
tf
,
&
PgTrapFrame
,
sizeof(
struct
Trapframe));
10
if(
tf
->
regs
[
29
]
>= (
curenv
->
env_xstacktop
-
BY2PG)
&&
tf
->
regs
[
29
]
<= (
curenv
->
env_xstacktop
-
1))
11
{
12
//panic("fork can't nest!!");^M
13
tf
->
regs
[
29
]
=
tf
->
regs
[
29
]
-
sizeof(
struct
Trapframe);
14
bcopy(
&
PgTrapFrame
,
tf
->
regs
[
29
],
sizeof(
struct
Trapframe));
15
}
16
else
17
{
18
tf
->
regs
[
29
]
=
curenv
->
env_xstacktop
-
sizeof(
struct
Trapframe);
19
// printf("page_fault_handler(): bcopy(): src:%x\tdes:%x\n",(int)&PgTrapFrame,(int)(curenv->env_xstacktop - sizeof(struct Trapframe)));
20
bcopy(
&
PgTrapFrame
,
curenv
->
env_xstacktop
-
sizeof(
struct
Trapframe
),
sizeof(
struct
Trapframe));
21
}
22
// printf("^^^^cp0_epc:%x\tcurenv->env_pgfault_handler:%x\n",tf->cp0_epc,curenv->env_pgfault_handler);
23
tf
->
cp0_epc
=
curenv
->
env_pgfault_handler;
24
return;
25
}