进程调度与系统调用ppt课件.ppt
《进程调度与系统调用ppt课件.ppt》由会员分享,可在线阅读,更多相关《进程调度与系统调用ppt课件.ppt(127页珍藏版)》请在三一办公上搜索。
1、Linux操作系统内核分析,湘潭大学信息工程学院,讲课内容,中断管理进程管理信号处理,中断的概念,改变处理器正常执行顺序的事件中断来源:硬件:时钟、键盘、硬盘等,异步发生 异常:CPU检测到的错误软件 系统调用:进程向OS发出的请求,中断向量,保护模式支持256个中断,每个中断用一个0到255的整数来标识,把这个整数称为中断向量0到31对应异常(P76表5-2)32到47对应硬件中断(P9图2-5)48到255预留,linux使用了0 x80作为系统调用,中断,保护模式下中断处理,idtr,0号中断描述符,1号中断描述符,2号中断描述符,3号中断描述符,中断描述符表,中断描述符,段选择子,段内
2、偏移(0-15),段内偏移(16-31),2位,4位,Head中对中断描述符表的处理,在程序232行(P58),定义了有256个中断描述符的中断描述符表,并在程序开始处把该描述符表的基地址输出(可以被C程序使用)在程序78行(P54),把这256个中断描述符中的处理程序设置为ignore_int在程序105行(P55)把中断描述符表的基地址装入到idtr寄存器中,gcc嵌入汇编,_asm_ _volatile_(汇编语句 : 输出寄存器 : 输入寄存器 : 会被修改的寄存器);输出寄存器:“=代表寄存器的字母” (变量名) 寄存器的值会被写入变量中输入寄存器:“代表寄存器的字母” (变量名)
3、用变量的值初始化寄存器,P81,常用寄存器加载代码,P83表5-3,嵌入汇编示例,#define _save_flags(x) _ asm_ _volatile_( “pushfl;” “popl %0” : “=a” (x) );,a代表寄存器eax。把eax和变量x绑定,往eax中写入值等于给变量x赋值,数字代表寄存器的序号。把输出寄存器和输入寄存器按照顺序进行编号,从0开始。%n代表第n个寄存器。,序号0,嵌入汇编示例,#define get_seg_byte(seg,addr)( register char _res; _ _asm_ _(“ push %fs; mov %ax, %f
4、s; movb %fs:%2,%al; pop %fs”:“=a”(_res):“0”(seg), “m”(*(addr);_res;),序号0,序号1,序号2,宏的返回值,eax用seg的值进行了初始化,_set_gate宏,_set_gate宏(定义在system.h,P390的22行),用来设置中断描述符gate_addr:描述符的地址type:描述符的类型dpl: 使用描述符的最低权限addr:中断处理函数的地址,_set_gate宏,#define _set_gate(gate_addr,type,dpl,addr) _asm_ (movw %dx,%axnt movw %0,%dx
5、nt movl %eax,%1nt movl %edx,%2 : : i (short) (0 x8000+(dpl13)+(type8), o (*(char *) (gate_addr), o (*(4+(char *) (gate_addr), d (char *) (addr),a (0 x00080000),0,1,2,3,4,_set_gate宏,0号立即数,1号内存地址指向描述符的基地址(前4个字节),2号内存地址指向描述符的基地址+4(后4个字节),处理程序高16位,处理程序低16位,edx,0 x0008,0 x0000,eax,处理程序低16位,0 x8000+(dpl13
6、)+(type8),0 x8000+(dpl13)+(type8),段选择子,段内偏移(0-15),段内偏移(16-31),Type,0,DPL,1,00000000,设置中断描述符,#define set_trap_gate(n,addr) _set_gate(&idtn,15,0,addr)#define set_system_gate(n,addr) _set_gate(&idtn,15,3,addr),idt是head中定义的描述符表基地址,dpl=0,只有操作系统能够使用该中断,dpl=3,任何进程都可以使用该中断,异常初始化,trap.c中的trap_init()(P80的181行
7、)函数负责再次初始化中断描述符表,该函数在main函数(P65的127行)中被调用异常的中断向量参见P76表5-2,中断初始化,在traps.c中的trap_init函数的最后( P81第207行)设置了并口(0 x27)的中断描述符在sche.c中的sched_init函数的最后(P103第409行)设置了时钟中断(0 x20)的中断描述符参见P9图2-5,系统调用初始化,在sche.c中的sched_init函数的最后(P103第411行)设置了系统调用(0 x80)的中断描述符,中断处理,中断处理完后,进程会按照被打断前的状态继续运行,所以需要保存该状态。,保存执行现场,调用中断处理函数
8、,恢复执行现场,指令1指令2指令n,进程,中断处理,保存执行现场,调用中断处理函数,恢复执行现场,用户指令1用户指令2内核指令1内核指令2,进程,内核,硬中断异常系统调用,硬中断异常,中断处理,CS,EIP,SS,ESP,EFLAGS,通用寄存器,用户态指令,用户态堆栈,CPU,内核态指令,内核态堆栈,用户态,内核态,中断处理,当发生中断时,如果当前进程运行在内核态,CPU会将EFLAGS、CS、和EIP寄存器中的内容压入堆栈当发生中断时,如果当前进程运行在用户态,CPU除了会将EFLAGS、CS、和EIP寄存器中的内容压入堆栈外,还会把进程在用户态时使用的SS和ESP寄存器的内容压入堆栈,中
9、断发生时的堆栈,CS,EFLAGS,EIP,CS,EFLAGS,EIP,用户态ESP,用户态SS,中断发生时进程在内核态,中断发生时进程在用户态,中断处理,异常处理系统调用中断处理,异常处理,异常发生时,可能带有出错码。如果有,则该出错码也会被CPU压入堆栈,CS,EFLAGS,EIP,用户态ESP,用户态SS,CS,EFLAGS,EIP,用户态ESP,用户态SS,出错码,不带出错码的异常处理,pushl $do_divide_errorno_error_code:xchgl %eax,(%esp)pushl %ebxpushl %ecxpushl %edxpushl %edipushl %e
10、sipushl %ebppush %dspush %espush %fspushl $0 lea 44(%esp),%edxpushl %edxmovl $0 x10,%edxmov %dx,%dsmov %dx,%esmov %dx,%fscall *%eax,do_divide_error,eax的值,ebx的值,eax保存do_divide_error的地址,EFLAGS,EIP,用户态ESP,用户态SS,ecx的值,edx的值,edi的值,esi的值,ebp的值,错误码0,初始esp位置,指向内核数据段,不带出错码的异常处理,addl $8,%esppop %fspop %espop
11、%dspopl %ebppopl %esipopl %edipopl %edxpopl %ecxpopl %ebxpopl %eaxiret,eax的值,ebx的值,EFLAGS,EIP,用户态ESP,用户态SS,ecx的值,edx的值,edi的值,esi的值,ebp的值,错误码0,初始esp位置,异常处理流程,保存现场,准备参数,调用C语言函数,弹出参数,恢复现场,中断返回,发生中断,带出错码的异常处理,P75页第99行,CS,EFLAGS,EIP,用户态ESP,用户态SS,出错码,中断处理,异常处理系统调用中断处理,使用系统调用,P383第133行#define _syscall0(typ
12、e,name)type name(void)long _res; _ _asm_ _ volatile(“int $0 x80 : “=a”(_res) : “0”(_NR_#name);if(_res =0) return (type)_res;errno = - _res;return -1;,系统调用的返回放在eax中,系统调用的功能号放在eax中(P381),使用系统调用,P63第23行static inline _syscall0(int,fork)int fork(void)long _res; _ _asm_ _ volatile(“int $0 x80 : “=a”(_res)
13、 : “0”(_NR_fork);if(_res =0) return (type)_res;errno = - _res;return -1;,使用系统调用,系统调用的输入把子功能号放入eax中如果还有其它参数(最多3个),则第1、第2和第3个参数分别放入寄存器ebx,ecx和edx中系统调用的返回值保存在eax中,数据结构及算法,函数指针数组 sys_call_talbe (P409)system_call(P86第80行)处理流程保存现场以子功能号作为索引查找sys_call_table,找到处理该功能的C语言函数,然后调用该函数。恢复现场,系统调用的处理,cmpl $nr_system
14、_calls-1,%eaxja bad_sys_callpush %dspush %espush %fspushl %edxpushl %ecxpushl %ebxmovl %0 x10, %edxmov %dx,%dsmov %dx,%esmovl %0 x17, %edxmov %dx,%fscall _sys_call_table(,%eax,4)pushl %eax,EFLAGS,EIP,用户态ESP,用户态SS,EDX,ECX,EBX,系统调用参数,_sys_call_table+4*eax_sys_call_table在P409定义,EAX,保存系统调用返回值,系统调用的处理,3:
15、popl %eaxpopl %ebxpopl %ecxpopl %edxpop %fspop %espop %dsiret,EFLAGS,EIP,用户态ESP,用户态SS,EDX,ECX,EBX,EAX,讲课内容,中断管理进程管理信号处理,进程的概念,进程是程序的一次执行,是由代码段、数据段和堆栈段组成动态的实体,在Linux中,把进程又称为任务(task)进程是系统资源分配的基本单位,也是使用CPU运行的基本调度单位,进程描述符,为了管理进程,操作系统需要清楚地知道每个进程的属性,Linux用一个称为进程描述符(task_struct)的数据结构来描述task_struct定义在sched.
16、h中,参见P404第78行,进程描述符状态,P12图2-6,没有实现,进程描述符线性地址分布,代码,数据,bss,用户态堆栈,环境参数,nr*64M,(nr+1)*64M,start_code,end_code,end_data,brk,start_stack,进程描述符任务状态段,任务状态段(TSS)是保存任务的所有信息的内存段,共104B寄存器保存区域内层堆栈指针区域地址映射寄存器区域其它字段P116图5-8,进程描述符任务状态段,在任务切换过程中首先,CPU中各寄存器的当前值被自动保存到TR所指定的TSS中(当前任务的TSS中)然后,下一任务的TSS的选择子被装入TR最后,从TR所指定的
17、TSS中取出各寄存器的值送到处理器的各寄存器中由此可见,通过在TSS中保存任务现场各寄存器状态的完整映象,实现任务的切换,进程描述符任务状态段,TSS的段描述符在GDT中,当前进程的TSS的段选择子被保存在TR寄存器中,TSS段描述符,GDT,TSS段,当前进程的TSS段选择子,TR,TSS段描述符,TSS段,进程描述符局部描述符表,局部描述符表(LDT)包含任务私有内存段的描述符(也是一个内存段)LDT的段描述符在GDT中,当前进程的LDT段选择子在ldtr中,进程描述符局部描述符表,Linux中LDT包含3个描述符,其中:第0个没用第1个描述的是代码段,该段的段选择子是0 xf(1111)
18、第2个描述的是数据段,该段的段选择子是0 x17(10111),进程描述符局部描述符表,LDT段描述符,私有段段描述符,私有段段描述符,私有段段描述符,GDT,LDT,当前进程的LDT段选择子,ldtr,LDT段描述符,私有段段描述符,私有段段描述符,私有段段描述符,TSS段描述符,TSS段描述符,进程1,进程2,Linux内核堆栈,Intel平台上进程在不同的特权级别下使用不同的堆栈在Linux中为进程在内核态建立的堆栈与进程描述符公用一块4K的内存块参见shed.c(P95第53行),task_union,union task_union struct task_struct task;c
19、har stackPAGE_SIZE;/宏定义在mm.h(P401第4行);,内核堆栈栈顶,任务描述符基地址,4K,任务数组,Linux把所有任务的进程描述符的指针用一个指针数组管理起来,定义在sched.c中(P95第65行)struct task_struct *taskNR_TASKS;/NR_TASK=64,定义在sched.h中(P402第4行)FIRST_TASKLAST_TASK,taskn,task数组,tss,进程数据段描述符,其它属性,进程描述符,没用,内核代码段描述符,内核数据段描述符,没用,TSS0,LDT0,TSS1,LDT1,TSSn,LDTn,TSS(n+1),L
20、DT(n+1),GDT,.,进程代码段描述符,没用,进程n,n*64,内核态堆栈,求进程n的TSS段的段选择子,#define FIRST_TSS_ENTRY 4#define _TSS(n) (unsigned long) n)4)+(FIRST_TSS_ENTRY3)定义在sched.h(P405第153和155行),4*8,16B,16B,GDT,Index,0,00,RPL,TI,(4+n*2)*8,进程管理,进程0的创建创建子进程调度进程进程睡眠终止进程,进程0,进程0是一个特殊的进程它是所有其他进程的祖先进程;所有其他的进程都是通过fork系统调用,复制进程0或者其后代进程产生的;
21、只有进程0是静态产生的。,进程0,创建进程0的步骤申请一个进程描述符与进程内核堆栈的公用体把进程描述符的地址放在task数组的第0项在GDT中设置进程0的tss段描述符和ldt段描述符(sched_init函数, P102第392,393行)把进程0tss段描述符的选择子和ldt段描述符的选择子装载到tr寄存器和ldtr寄存器(404,405行),申请进程描述符与内核堆栈的公用体,static union task_union init_task = INIT_TASK,;/定义在sched.c中(P95第58行)/INIT_TASK定义在sched.h中(P405第113行)/进程0的代码段
22、和数据段与内核代码段和数据段重合struct task_struct *taskNR_TASKS = /定义在sched.c中(P95第65行),task数组,tss,进程数据段描述符,其它属性,进程描述符,没用,内核代码段描述符,内核数据段描述符,没用,TSS0,LDT0,GDT,进程代码段描述符,没用,进程0,64M,0M,esp0,内核态堆栈,tr,ldt,1,2,2,3,4,加载进程0的tss和ldt的段选择子,ltr(0);lldt(0);#define ltr(n) _asm_(ltr %ax:a (_TSS(n)#define lldt(n) _asm_(lldt %ax:a (
23、_LDT(n)/定义在sched.h中(P405第157行),把进程0移到用户态,sched_init函数运行完之后,进程0还是运行在内核态利用模拟中断返回的方法把进程0从内核态切换到用户态move_to_user_mode定义在system.h中(P389第1行),Iret指令,EIP,CS,FLAG,SS,ESP,esp,内核态堆栈,0 xf,0 x17,move_to_user_mode,#define move_to_user_mode() _asm_ ( “movl %esp,%eaxnt pushl $0 x17nt pushl %eaxnt pushflnt pushl $0 x
24、0fnt pushl $1fnt iretn 1:tmovl $0 x17,%eaxnt movw %ax,%dsnt movw %ax,%esnt movw %ax,%fsnt movw %ax,%gs :ax),进程0用户态数据段选择子(0 x17),进程0用户态堆栈指针( user_stack ),EFLAGS,进程0代码段段选择子(0 x0f),EIP(iret返回后执行的代码),进程管理,进程0的创建创建子进程调度进程进程睡眠终止进程,fork系统调用,系统调用处理函数_sys_fork定义在system_call.s中(P89第208行),在task数组中寻找一个空位,有空位,拷贝
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 调度 系统 调用 ppt 课件
链接地址:https://www.31ppt.com/p-1443946.html