对系统调用号做一些调整和限制。
得到系统调用的函数入口。
得到该系统调用的参数个数。
将参数从用户态拷贝到内核态的args中。
如果该系统调用不是MP安全的,则获取全局锁。
调用具体的系统调用。 这里,之所以要间接地使用一个系统调用函数表,是因为模拟其他操作系统的 需要。同一个系统调用在不同的操作系统里"系统调用号"是不同的,当运行其他 操作系统的应用程序时,因为其编译结果是用其他操作系统的"系统调用号", 此时需要转换到相应的FreeBSD的"系统调用号"上来,使用系统调用函数表就可以 方便地作到这一点。
Great,调用成功,设置返回值,并清除carry bit,用户态的libc要根据carry bit 判断系统调用是否成功。
系统调用返回ERESTART,内核要尝试重新执行系统调用,因此需要将返回用户空间后的 %eip后退,具体后退几个字节,跟系统调用的进入方式有关,如果是通过int 0x80进入的, 由于int 0x80指令的长度为两个字节,因此回退2字节,如果是通过lcall $X,y方式进入 内核的,由于lcall $X,y指令的长度为7个字节,因此回退7字节。具体几个字节,在刚进入 时已经压到堆栈上了(前述pushl $2即是)。
如果系统调用返回其他错误的话,则在进程的一个错误对应表中转换错误号。 并设置carry bit,以便libc知道。
释放全局锁。
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|