⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3 ϵͳ

📁 一个用于学习的操作系统
💻
字号:
系统调用的入口是_system_call_entry  kernel/system_call_entry.asm
整个过程很简单,把必要的寄存器压栈后,根据系统调用号eax(现在还没有做系统调用号的校验,超过现在系统调用数,铁定挂掉)调用系统调用函数(call    [eax + _system_calls])。_system_calls是一个数组,里边存的是系统调用函数的地址。完成系统调用后便从_ret_from_sys_call返回,其中还对信号做了处理。

fork系统的调用的特别说明,由于fork的调用比较特别,完成这个调用,系统中就会多了一个进程,作为父进程从正常的路线返回,返回值就是子进程的pid。而作为子进程的第一次返回到用户态下却有所差别,子进程的第一次返回到用户态是从_child_ret_from_sys_call开始。这是在创建子进程时初始化了的,tmp_task->tss.eip = (u32)CHILD_RET_FROM_SYS_CALL,而子进程的返回值必须是0,因此_child_ret_from_sys_call这里做的第一件事情就是push 0,等到了_ret_from_sys_call之后在push到eax中。

内核空间和用户空间数据传递的方式,主要有以下函数
从用户空间读取数据
get_fs_byte
get_fs_word
get_fs_long

这里主要用了fs段寄存器,这里的fs寄存器则是指向了用户数据段描述符
extern inline unsigned char get_fs_byte(const char * addr)
{
	unsigned register char _v;

    __asm__ __volatile__("movb %%fs:%1,%0":"=q" (_v):"m" (*addr));
    return _v;
}

向用户空间写数据
put_fs_byte
put_fs_word
put_fs_long
向用户空间写数据的原理同上
extern inline void put_fs_byte(char val,char *addr)
{
    __asm__ __volatile__("movb %0, %%fs:%1"::"q" (val),"m" (*addr));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -