中断定时和系统调用.ppt

上传人:小飞机 文档编号:5170585 上传时间:2023-06-10 格式:PPT 页数:55 大小:548.50KB
返回 下载 相关 举报
中断定时和系统调用.ppt_第1页
第1页 / 共55页
中断定时和系统调用.ppt_第2页
第2页 / 共55页
中断定时和系统调用.ppt_第3页
第3页 / 共55页
中断定时和系统调用.ppt_第4页
第4页 / 共55页
中断定时和系统调用.ppt_第5页
第5页 / 共55页
点击查看更多>>
资源描述

《中断定时和系统调用.ppt》由会员分享,可在线阅读,更多相关《中断定时和系统调用.ppt(55页珍藏版)》请在三一办公上搜索。

1、中断、定时和系统调用,中断和异常,中断是一种触发信号,一个CPU接收到这样一种信号后会改变它执行代码的流程,一般是从一个固定的地址执行一段预先设定好的程序。中断的种类同步中断:异常,软中断程序运行过程中产生页错误,被0除,中断指令(int),.异步中断:中断,硬中断由设备产生键盘中断,时钟中断,.中断信号常被用来泛指上述各种中断。中断信号是系统的重要和稀缺的资源。每个中断和异常都有一个编号,0-255,称为中断向量。,中断信号处理,中断信号可以由进程或外部事件产生中断信号的处理只能由内核完成中断当前的程序,切换到中断处理代码中断处理代码不属于进程同步中断与当前进程相关异步中断与当前进程无关中断

2、的结果与进程相关中断处理条件:中断响应时间越快越好中断处理分成top half和bottom half。中断嵌套中断处理过程中对临界区的处理,中断,中断可屏蔽中断不可屏蔽中断中断控制器可编程中断控制器:PIC单处理器环境,8259A先进可编程中断控制器:APIC多处理器环境,中断请求和中断控制器响应,中断请求(IRQ)对中断请求的响应中断控制器产生中断的设备,8259A,8259A,80 x86,0,15,异常,80 x86处理器约有20个异常常见异常Divide error:被0除异常Invalid opcode:无效操作码异常Page fault:页失效异常每个异常都有相应的异常处理函数(

3、handler)divide_error(),invalid_op(),page_fault(),.,中断门描述符,内核管理中断使用的数据结构一个中断门描述符由8个字节组成描述符中保存有关中断的各种信息中断向量中断处理函数地址各种权限参数i386共有3种类型的中断门描述符Task Gate Descriptor:任务门描述符Interrupt Gate Descriptor:中断门描述符Trap Gate Descriptor:自陷门描述符,不同类型的中断门描述符,中断门描述符表,内核维护的一个由256个表项的表,每个表项为一个中断门描述符。一个中断门描述符由8个字节组成,整个表共用内存空间2

4、048字节。中断门描述符表保存在内存中,其起始地址保存在一个专用的寄存器中。操作系统在使能中断之前要初始化中断门描述附表。,中断门描述符表结构,0,1,32,33,128,255,0号异常:Divide error,被0除,1号异常:Debug,调试,0号中断:IRQ0,1号中断:IRQ1,中断指令:int 80,Linux对中断的使用,中断指令intint指令可以产生任意向量的中断Linux对中断的划分中断门:interrupt gate,用于硬件中断信号产生的中断,只能在内核模式下使用。系统门:system gate,用于实现系统调用,可由用户模式下的代码产生。int3,into,boun

5、d,int 80.自陷门:trap gate,用于其他异常的中断,只能在内核模式下使用。,初始化中断门描述符表,初级初始化:setup_idt()缺省的中断处理函数:ignore_int()打印Unknown interrupt用ignore_int()填充中断门描述符表中所有表项的中断处理函数ignore_int函数应该永远不会被调用,除非系统硬件或内核出现问题。,/*This is the default interrupt handler:-)*/int_msg:.asciz Unknown interruptnALIGNignore_int:cldpushl%eaxpushl%ecxp

6、ushl%edxpushl%espushl%dsmovl$(_KERNEL_DS),%eaxmovl%eax,%dsmovl%eax,%espushl$int_msgcall SYMBOL_NAME(printk)popl%eaxpopl%dspopl%espopl%edxpopl%ecxpopl%eaxiret,arch/i386/kernel/head.S:ignore_int,/*setup_idt*sets up a idt with 256 entries pointing to*ignore_int,interrupt gates.It doesnt actually load*i

7、dt-that can be done only after paging has been enabled*and the kernel moved to PAGE_OFFSET.Interrupts*are enabled elsewhere,when we can be relatively*sure everything is ok.*/setup_idt:lea ignore_int,%edxmovl$(_KERNEL_CS 16),%eaxmovw%dx,%ax/*selector=0 x0010=cs*/movw$0 x8E00,%dx/*interrupt gate-dpl=0

8、,present*/lea SYMBOL_NAME(idt_table),%edimov$256,%ecxrp_sidt:movl%eax,(%edi)movl%edx,4(%edi)addl$8,%edidec%ecxjne rp_sidtret,arch/i386/kernel/head.S:setup_idt,异常的处理,Linux通常将CPU发出的异常作为错误条件处理页失效异常(page fault)作为内存管理的手段当异常发生时,内核向当前进程发送信号,通知进程有异常状态出现。通常情况下,进程因为错误状态的出现而退出运行。异常的处理将CPU的各种寄存器保存在进程的内核堆栈上调用异常处

9、理函数处理异常调用ret_from_exception()从异常返回,.set_trap_gate(0,.,arch/i386/kernel/trap.c:trap_init,中断的处理,中断的出现与当前进程很可能完全没有关系。中断发生时,内核不能通过向进程发送信号的方式通知进程出现中断信号。中断通常表示某种资源变得可用。中断的分类I/O中断定时器(Timer)中断CPU间中断内核根据中断种类分类处理,I/O中断处理,I/O中断线是系统稀有资源中断共享不同设备可以共享同一个中断信号这种情况下,只使用中断向量不足以区分中断的来源中断动态分配中断资源只有在使用时才真正进行分配,并在使用后予以释放。

10、中断处理函数中不能有任何进入阻塞的调用I/O中断的处理使用进程的内核堆栈保存中断向量以及各种CPU寄存器向中断控制器发送应答信号执行中断处理函数(中断服务程序,ISR)使用ret_from_intr()返回,I/O中断的处理,Linux中使用的中断向量分配,I/O中断向量的分配,IRQ描述符,irqaction描述符,handler指向中断服务程序flagsSA_INTERRUPTSA_SHIRQSA_SAMPLE_RANDOMnamedev_idnext,Softirq,Tasklet,Bottom Halves,内核对中断的处理方式会极大影响系统的效率。为提高系统效率,内核将一个中断的响应

11、分成2部分:需要立即处理的部分,称为top half或上半部,一般是不能再被中断的。可以推后处理的部分,称为bottom half或下半部,是可以再被中断的。下半部中断的实现机制SoftirqTaskletTasklet基于SoftirqBottom HalvesBottom Halves基于Tasklet,中断下半部实现机制的差异,所有的中断下半部都需要顺序执行,Softirq,Linux 2.4内核中只实现了如下4种Softirq:,可以看出,Tasklet是在Softirq基础上实现的。,Tasklet,最常用的中断下半部的实现机制Tasklet描述符next:指向下一个描述符的指针st

12、ate:tasklet的状态TASKLET_STATE_SCHEDTASKLET_STATE_RUNcount:锁计数器func:指向tasklet函数的指针data:一般用于tasklet的私有数据Tasklet由Softirq启动,Bottom Halves,早期使用的中断下半部的实现机制,被称为BH机制。BH机制在一些传统的中断响应中仍被广泛使用。BH在实现方法上缺乏Tasklet的灵活性,一般都使用Tasklet代替BH。,中断的返回,Linux的时钟管理,目标时钟中断:系统心跳信号系统时钟:各种时间戳定时器:时钟种类实时钟:RTC时间戳计数器器:TSC可编程定时器:PIT,几个常用的

13、变量和概念,HZ系统时钟中断1秒钟内产生的中断次数,100tick系统时钟中断的时间间隔,一个嘀嗒jiffies系统启动后所经历的系统时钟嘀嗒数,即tick数,也就是系统时钟中断的次数。时间片或时间量子(time slice,time quantum)分配给进程的时间段,以tick为单位。,IRQ0:系统时钟中断,由一个可编程定时器产生系统时钟中断以HZ为频率产生中断为系统提供基本的时间事件的驱动更新系统启动后经历的时间更新系统时钟的日期和时间判断一个进程是否已经用完所分配的时间量子,决定是否需要进行进程切换用于各种系统资源的统计判断定时器是否到时,IRQ0中断服务程序,首先作为IRQ被初始化

14、:timt_init()中断服务程序:timer_interrupt()根据硬件时钟读取各种时间值并保存调用do_timer_interrupt()调用do_timer()jiffies+update_process_times()mark_bh(TIMER_BH)其他操作,timer_bh():update_times():更新系统时间计算系统负载 run_timer_list():负责处理软件定时器,软件定时器,由软件实现的定时器。使用软件定时器可以实现在给定的时间间隔后执行一个函数。内核提供软件定时器的机制。但这种定时器只能保证定时时刻到时或到时之后才起作用。硬件定时器,如可编程定时器P

15、IT,在定时时刻到时时就会立即发出中断。软件定时器是在系统时钟中断的下半部被处理,不能保证实时性。Linux提供2种定时器动态定时器用于内核中的定时应用时间间隔定时器可由用户空间的进程建立,动态定时器,当某些内核过程需要推迟运行时,可以使用动态定时器。动态定时器可以动态建立和撤销。动态定时器的数量可以有任意多个。动态定时器到时后会执行指定的函数,动态定时器到时之前可以被撤销。动态定时器以tick为最小时间单位。动态定时器的管理由数据结构timer_list保存并形成一个链表。,/*In Linux 2.4,static timers have been removed from the ker

16、nel.*Timers may be dynamically created and destroyed,and should be*initialized by a call to init_timer()upon creation.*The data field enables use of a common timeout function for several*timeouts.You can use this field to distinguish between the different*invocations.*/struct timer_list struct list_

17、head list;unsigned long expires;unsigned long data;void(*function)(unsigned long);,include/linux/timer.h,动态定时器的管理,定时器需要在每个时钟中断时检查是否到期定时器的定时时间可能有非常大的差异使用简单链表或排序的链表在管理大量动态定时器时会消耗很多CPU时间Linux使用分组和链表的方式管理动态定时器tvecs数组:5个元素,指向5个链表组根据剩余到期时间将定时器放到相应的链表中tv1:即将在随后255个tick之后到期的定时器,有256个元素tv2:即将在随后214-1个tick之后到

18、期的定时器,有64个元素.tv5:所有即将在232-1个tick之后到期的定时器,动态定时器管理用链表结构,例1:动态定时器应用,假设内核希望当前进程停顿2秒后再继续运行,timeout=2*HZ;set_current_state(TASK_INTERRUPTIBLE);/*or TASK_UNINTERRUPTIBLE*/remining=schedule_timeout(timeout);,struct timer_list timer;expire=timeout+jiffies;init_timer(,schedule_timeout(),struct task_struct*p=(

19、struct task_struct*)data;wake_up_process(p);,void process_timeout(unsigned long data),获得时间,相关系统调用time()ftime()gettimeofday()时间信息保存在timeval数据结构中根据系统上的时钟类型,可精确到tick(10毫秒)或TSC的时间精度(微秒)用户进程可使用上述系统调用获得时间信息推荐使用gettimeofday()系统调用获得当前系统时间,在用户进程中使用定时器,系统为进程提供时间间隔定时器实现机制基于动态定时器基于进程自身的时间信息相关系统调用setitimer()alar

20、m()时间间隔定时器通过向进程发送相应的信号使进程实现相应的定时功能,例2:使用setitimer(),SYNOPSIS#include int setitimer(int which,const struct itimerval*value,struct itimerval*ovalue);,$man setitimer,whichITIMER_REAL:以系统实时钟为计时标准,时钟到时后发出SIGALRM信号ITIMER_VIRTUAL:以进程运行时间为计时标准,时钟到时后发出SIGVTALRM信号ITIMER_PROF:以进程运行时间和内核以进程身份运行时间之和为计时标准,到时后发出SI

21、GPROF信号struct itimerval struct timeval it_interval;/*next value*/struct timeval it_value;/*current value*/;struct timeval long tv_sec;/*seconds*/long tv_usec;/*microseconds*/;,#include#include#include/*A global variable used to control which string is printed*/int flag=0;/*The signal handler which r

22、uns when the signal is received*/void sighand(int signum)if(flag)flag=0;else flag=1;return;int main(void)struct itimerval itimer;/*Assume the itimer expires every 2.7 sec*/=700000;/*0.7 sec*/=2;/*2 sec*/,mytimer.c,/*The itimer starts after 2 sec*/=0;=2;/*Register the signal handler*/signal(SIGALRM,m

23、ytimer.c(续),$gcc-o mytimer mytimer.c$./mytimerBBBBBBBBAAAAAAAAAAAAAAAABBBBBBBBBBBBAAAAAAAAC,编译和运行,注意:当setitimer使用ITIMER_REAL模式调用时,它与系统调用alarm()和库函数sleep()可能使用相同的动态定时器实现机制,并且都会发出SIGALRM信号。因此不要混合使用上述几种定时函数。,系统调用,系统调用是进程向内核请求资源的唯一手段系统调用的各种过程是内核的一部分应用程序接口(API)与系统调用系统调用是系统以进程身份执行的内核过程系统调用的实现基于特定的中断指令。中断指

24、令将进程从用户模式切换到内核模式。i386:int 0 x80,系统调用的调用过程,系统调用的实现,sys_call_table保存系统调用入口地址的数组,共有NR_syscalls(通常为256)个数组元素。第n个数组元素对应调用号为n的系统调用。初始化中断门描述符表,使用0 x80号中断set_system_gate(0 x80,每个系统调用都有2个部分派遣函数或系统调用句柄系统调用服务程序,系统调用中的参数传递,system_call()是所有系统调用的入口函数,它根据调用号从sys_call_table中调用相应的系统调用服务程序。系统调用使用寄存器进行参数传递一般C函数使用堆栈进行参

25、数传递因为寄存器的大小和数目都是有限的,因此系统调用的参数不能超过寄存器大小并且数目不能超过6个。但可以使用其它技术传递更多参数。最终的系统调用服务程序由C函数完成,因此调用参数仍然会被放到堆栈中。,系统调用相关源代码析读,.dataENTRY(sys_call_table).long SYMBOL_NAME(sys_ni_syscall)/*0,old setup()system call*/.long SYMBOL_NAME(sys_exit).long SYMBOL_NAME(sys_fork).long SYMBOL_NAME(sys_read).long SYMBOL_NAME(sy

26、s_write).long SYMBOL_NAME(sys_open)/*5*/.long SYMBOL_NAME(sys_ni_syscall)/*255 sys_epoll_ctl*/.long SYMBOL_NAME(sys_ni_syscall)/*sys_epoll_wait*/.long SYMBOL_NAME(sys_ni_syscall)/*sys_remap_file_pages*/.long SYMBOL_NAME(sys_set_tid_address),arch/i386/kernel/entry.S:sys_call_table,/*Return to user mo

27、de is not as complex as all this looks,*but we want the default path for a system call return to*go as quickly as possible which is why some of this is*less clear than it otherwise should be.*/ENTRY(system_call)pushl%eax#save orig_eax SAVE_ALL GET_CURRENT(%ebx)testb$0 x02,tsk_ptrace(%ebx)#PT_TRACESY

28、S jne tracesys cmpl$(NR_syscalls),%eax jae badsys call*SYMBOL_NAME(sys_call_table)(,%eax,4)movl%eax,EAX(%esp)#save the return valueENTRY(ret_from_sys_call)cli#need_resched and signals atomic test cmpl$0,need_resched(%ebx)jne reschedule cmpl$0,sigpending(%ebx)jne signal_returnrestore_all:RESTORE_ALL,

29、arch/i386/kernel/entry.S:system_call,asmlinkage ssize_t sys_write(unsigned int fd,const char*buf,size_t count)ssize_t ret;struct file*file;ret=-EBADF;file=fget(fd);if(file)if(file-f_mode,系统调用服务程序,以sys_write为例fs/read_write.c:sys_write,在内核中使用系统调用,系统调用的接口是在库函数中实现的内核不能使用库函数内核使用一系列wrapper例程在内核中实现系统调用接口使用7个宏简化接口定义_syscall0,_syscall1,_syscall2,._syscall6每个宏在编译时展开成相应的汇编函数例:_syscall3(int,write,int,fd,const char*,buf,unsigned int,count),参考资料,深入理解Linux内核第二版第四章,第六章,第九章,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号