linux0.11系统调用的执行过程是怎样的?
(1) 答:当执行系统调用函数时,系统调用函数会执行int 0x80中断命令,同时将系统调用号放入eax寄存器中,并将要传递给系统的参数放入ebx,ecx,edx中。中断处理程序会执行system_call()函数。
(2) system_call()函数首先保存原段寄存器,在将调用参数压入栈中。然后将ds(在保护模式下,ds装的是段选择符)、es指向内核数据段,cs段会在中断产生时由中断门的段选择符赋值为内核代码段,并将原段选择符保存到栈中。然后调用对应的功能函数。当从功能函数返回时,内核会查看当前任务运行状态,如果不在就绪态就去执行调度程序。如果在就绪态,但其时间片用完,则也去执行调度程序。当任务继续执行时则继续对信号进行处理,然后退回到系统调用函数。
代码大概如下
#### int 0x80 --linux 系统调用入口点(调用中断int 0x80,eax 中是调用号)。 .align 2 _system_call: cmpl $nr_system_calls-1,%eax # 调用号如果超出范围的话就在eax 中置-1 并退出。 ja bad_sys_call 5.5 system_call.s 程序 push %ds # 保存原段寄存器值。 push %es push %fs pushl %edx # ebx,ecx,edx 中放着系统调用相应的C 语言函数的调用参数。 pushl %ecx # push %ebx,%ecx,%edx as parameters pushl %ebx # to the system call movl $0x10,%edx # set up ds,es to kernel space mov %dx,%ds # ds,es 指向内核数据段(全局描述符表中数据段描述符)。 mov %dx,%es movl $0x17,%edx # fs points to local data space mov %dx,%fs # fs 指向局部数据段(局部描述符表中数据段描述符)。 # 下面这句操作数的含义是:调用地址 = _sys_call_table + %eax * 4。参见列表后的说明。 # 对应的C 程序中的sys_call_table 在include/linux/sys.h 中,其中定义了一个包括72 个 # 系统调用C 处理函数的地址数组表。 call _sys_call_table(,%eax,4) pushl %eax # 把系统调用号入栈。 movl _current,%eax # 取当前任务(进程)数据结构地址??eax。 # 下面97-100 行查看当前任务的运行状态。如果不在就绪状态(state 不等于0)就去执行调度程序。 # 如果该任务在就绪状态但counter[??]值等于0,则也去执行调度程序。 cmpl $0,state(%eax) # state jne reschedule cmpl $0,counter(%eax) # counter je reschedule # 以下这段代码执行从系统调用C 函数返回后,对信号量进行识别处理。 ret_from_sys_call:
linux0.11 中系统调用中断0x80在哪儿初始化的?
// 设置系统调用中断门。 set_system_gate (0x80, &system_call);
#define _set_gate(gate_addr,type,dpl,addr) / __asm__ ( "movw %%dx,%%ax/n/t" /// 将偏移地址低字与选择符组合成描述符低4 字节(eax)。 "movw %0,%%dx/n/t" /// 将类型标志字与偏移高字组合成描述符高4 字节(edx)。 "movl %%eax,%1/n/t" /// 分别设置门描述符的低4 字节和高4 字节。 "movl %%edx,%2": :"i" ((short) (0x8000 + (dpl << 13) + (type << 8))), "o" (*((char *) (gate_addr))), "o" (*(4 + (char *) (gate_addr))), "d" ((char *) (addr)), "a" (0x00080000))
#define set_system_gate(n,addr) / _set_gate(&idt[n],15,3,addr) //// 设置段描述符函数。 // 参数:gate_addr -描述符地址;type -描述符中类型域值;dpl -描述符特权层值; // base - 段的基地址;limit - 段限长。(参见段描述符的格式)
|
相关推荐
详细介绍linux0.11系统调用执行过程,包括源码注释。
linux 0.11 源码下载 本代码是目前能够找到的最早的Linux的内核版本,Linux 0.11内核是Linux内核的早期版本,于1991年由Linus Torvalds编写并发布。作为一个基于UNIX的操作系统内核,它的源代码包含了核心代码和一些...
linux0.11的源代码,有对linux内核感兴趣的朋友可以下载看看
linux 0.11 源码下载
linux 0.11内核下载,linux 内核
Linux内核设计的艺术(资料)\搭建Linux0.11系统环境.rar
非常好的对linux0.11的文件系统进行动漫展示。
linux 0.11 源码下载
linux 0.11源码 Linus曾经说过:RTFSC - Read The Fucking Source Code. 本代码是目前能够找到的最早的Linux的内核版本。(如果你能找到更早版本的Linux源码,请一定要告诉我。;-) ) 本代码中的注释99%都来源于赵炯...
linux0.11 bochs 调试.txt linux0.11 bochs 调试.txt
linux-0.11.rar linux0.11版内核源代码 下载
Linux 0.11源码,内核编程入门必备的珍贵资料。供相关的内核编程初学者及资深爱好者用以学习、分析及收藏。
Linux0.11内核代码,对于学习内核的人来说,Linux0.11内核代码确实是个不错的选择。。
linux0.11内核源代码 linux0.11内核源代码 linux0.11内核源代码
在Linux0.11的环境下完成基于内核栈切换的进程切换、地址映射与共享、终端设备的控制、proc文件系统的实现中的三个及以上实验项目。 在Linux四项任务中成功完成了四项:基于内核栈切换的进程切换,终端设备的控制,...
可在BOCHS中运行的LINUX0.11系统,需要先安装BOCHS虚拟机(很小,2M左右)。修改方法可参照赵炯博士写的LINUX0.11内核注释的书,未修改的原始版本可在赵博士的网站上下载到。安装BOCHS后双击bochsrc-hd.bxrc进入...
早期版本的linux 0.11源代码!是第一个linux kernel source code!
编写MBR从硬盘启动linux0.11完全过程