嵌入式Linux内核开发教程之深入分析Linux内核源码-进程调度(1).pptx
-
资源ID:67332462
资源大小:118.32KB
全文页数:26页
- 资源格式: PPTX
下载积分:16金币
快捷下载
![游客一键下载](/images/hot.gif)
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
嵌入式Linux内核开发教程之深入分析Linux内核源码-进程调度(1).pptx
千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org嵌入式嵌入式LinuxLinux内核开发教程之深内核开发教程之深入分析入分析LinuxLinux内核源码进程调内核源码进程调度度(1)(1)1 Linux时间系统1.1 时钟硬件1.2 时钟运作机制1.3 Linux时间基准1.4 Linux的时间系统2 时钟中断2.1 时钟中断的产生2.2.Linux实现时钟中断的全过程和时钟中断相关的函数系统调用返回函数千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org计算机最基本的时间单元是时钟周期,例如取指令、执行指令、存取内存等。时间系统是计算机系统非常重要的组成部分,特别是对于Unix类分时系统尤为重要。时间系统主要任务是维持系统时间并且防止某个进程独占CPU及其他资源,也就是驱动进程的调度。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之1 Linux1 Linux时间系统时间系统千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org大部分PC机中有两个时钟源,他们分别叫做RTC和OS(操作系统)时钟。RTC(Real Time Clock,实时时钟)也叫做CMOS时钟,它是PC主机板上的一块芯片,它靠电池供电,即使系统断电,也可以维持日期和时间。由于它独立于操作系统,所以也被称为硬件时钟,它为整个计算机提供一个计时标准,是最原始最底层的时钟数据。Linux只用RTC来获得时间和日期;然而,通过作用于/dev/rtc设备文件,也允许进程对RTC编程。通过执行/sbin/clock系统程序,系统管理员可以配置时钟。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之1.1 1.1 时钟时钟硬件硬件千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgOS时钟产生于PC主板上的定时/计数芯片,由操作系统控制这个芯片的工作,OS时钟的基本单位就是该芯片的计数周期。在开机时操作系统取得RTC中的时间数据来初始化OS时钟,然后通过计数芯片的向下计数形成了OS时钟,它更应该被称为一个计数器。OS时钟只在开机时才有效,而且完全由操作系统控制,所以也被称为软时钟或系统时钟。下面我们重点描述OS时钟的产生。OS时钟输出脉冲信号,接到中断控制器上,产生中断信号,触发后面要讲的时钟中断,由时钟中断服务程序维持OS时钟的正常工作。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgRTC和OS时钟之间的关系通常也被称作操作系统的时钟运作机制。一般来说,RTC是OS时钟的时间基准,操作系统通过读取RTC来初始化OS时钟,此后二者保持同步运行,共同维持着系统时间。保持同步运行是什么意思呢?就是指操作系统运行过程中,每隔一个固定时间会刷新或校正RTC中的信息。图2 时钟运作机制我们可以看到,RTC处于最底层,提供最原始的时钟数据。OS时钟建立在RTC之上,初始化完成后将完全由操作系统控制,和RTC脱离关系。操作系统通过OS时钟提供给应用程序所有和时间有关的服务。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之1.2 1.2 时钟时钟运作机制运作机制千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org以上我们了解了RTC(实时时钟、硬件时钟)和OS时钟(系统时钟、软时钟)。下面我们具体描述OS时钟。OS时钟是由可编程定时/计数器产生的输出脉冲触发中断而产生的。输出脉冲的周期叫做一个“时钟滴答”。计算机中的时间是以时钟滴答为单位的,每一次时钟滴答,系统时间就会加1。操作系统根据当前时钟滴答的数目就可以得到以秒或毫秒等为单位的其他时间格式。定义“时间基准”的目的是为了简化计算,这样计算机中的时间只要表示为从这个时间基准开始的时钟滴答数就可以了。“时间基准是由操作系统的设计者规定的。例如DOS的时间基准是1980年1月1日,Unix的时间基准是1970年1月1日上午12点,Linux的时间基准是1970年1月1日凌晨0点。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之1.3 1.3 LinuxLinux时间基准时间基准千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgOS时钟记录的时间也就是通常所说的系统时间。系统时间是以“时钟滴答”为单位的,而时钟中断的频率决定了一个时钟滴答的长短,例如每秒有100次时钟中断,那么一个时钟滴答的就是10毫秒(记为10ms),相应地,系统时间就会每10ms增1。Linux中用全局变量jiffies表示系统自启动以来的时钟滴答数目。在/kernel/time.c中定义如下:unsigned long volatile jiffies嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之1.4 1.4 LinuxLinux的时间系统的时间系统千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org在jiffies基础上,Linux提供了如下适合人们习惯的时间格式,在/include/linux/time.h中定义如下:struct timespec *这是精度很高的表示*long tv_sec;*秒(second)*long tv_nsec;/*纳秒:十亿分之一秒(nanosecond)*;嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgstruct timeval *普通精度*int tv_sec;/*秒*int tv_usec;/*微秒:百万分之一秒(microsecond)*;struct timezone /*时区*int tz_minuteswest;*格林尼治时间往西方的时差*int tz_dsttime;/*时间修正方式*;嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgtv_sec表示秒(second),tv_usec表示微秒(microsecond),tv_nsec表示纳秒(nanosecond)。定义tb_usec和tv_nsec的目的是为了适用不同的使用要求,不同的场合根据对时间精度的要求选用这两种表示。另外,Linux还定义了用于表示更加符合大众习惯的时间表示:年、月、日。但是万变不离其宗,所有的时间应用都是建立在jiffies基础之上的。简而言之,jiffies产生于时钟中断!嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org.1 时钟中断的产生“时钟中断”是特别重要的一个中断,因为整个操作系统的活动都受到它的激励。系统利用时钟中断维持系统时间、促使环境的切换,以保证所有进程共享CPU;利用时钟中断进行记帐、监督系统工作以及确定未来的调度优先级等工作。可以说,“时钟中断”是整个操作系统的脉搏。时钟中断的物理产生如图3所示:图3 8253和8259A的物理连接方式嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之2 2 时钟中时钟中断断千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org脉冲信号接到中断控制器8259A_1的0号管脚,触发一个周期性的中断,我们就把这个中断叫做时钟中断,时钟中断的周期,也就是脉冲信号的周期,我们叫做“滴答”或“时标”(tick)。从本质上说,时钟中断只是一个周期性的信号,完全是硬件行为,该信号触发CPU去执行一个中断服务程序,我们就把这个服务程序叫做时钟中断。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org 和时钟中断相关的函数下面我们看时钟中断触发的服务程序,该程序代码比较复杂,分布在不同的源文件中,主要包括如下函数:时钟中断程序:timer_interrupt();中断服务通用例程do_timer_interrupt();时钟函数:do_timer();中断安装程序:setup_irq();中断返回函数:ret_from_intr();嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之2.2.Linux2.2.Linux实现时钟中断的全过程实现时钟中断的全过程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org前三个函数的调用关系如下:timer_interrupt()do_timer_interrupt()do_timer()(1)timer_interrupt()这个函数大约每10ms被调用一次,实际上,timer_interrupt()函数是一个封装例程,它真正做的事情并不多,该函数主要语句就是调用do_timer_interrupt()函数。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org(2)do_timer_interrupt()do_timer_interrupt()函数有两个主要任务,一个是调用do_timer(),另一个是维持实时时钟(RTC,每隔一定时间段要回写),其实现代码在/arch/i386/kernel/time.c中,为了突出主题,笔者对以下函数作了改写,以便于读者理解:static inline void do_timer_interrupt(int irq,void*dev_id,struct pt_regs*regs)do_timer(regs);/*调用时钟函数,将时钟函数等同于时钟中断未尝不可*/嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgif(xtime.tv_sec last_rtc_update+660)update_RTC();/*每隔11分钟就更新RTC中的时间信息,以使OS时钟和RTC时钟保持同步,11分钟即660秒,xtime.tv_sec的单位是秒,last_rtc_update记录的是上次RTC更新时的值*/其中,xtime是前面所提到的timeval类型,这是一个全局变量。(3)时钟函数do_timer()(在/kernel/sched.c中)void do_timer(struct pt_regs*regs)(*(unsigned long*)&jiffies)+;/*更新系统时间,这种写法保证对jiffies操作的原子性*/嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgupdate_process_times();+lost_ticks;if(!user_mode(regs)+lost_ticks_system;mark_bh(TIMER_BH);if(tq_timer)mark_bh(TQUEUE_BH);嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org其中,update_process_times()函数与进程调度有关,从函数的名子可以看出,它处理的是与当前进程与时间有关的变量,例如,要更新当前进程的时间片计数器counter,如果counter=0,则要调用调度程序。与时间有关的事情很多,不能全都让这个函数去完成,这是因为这个函数是在关中断的情况下执行,必须处理完最重要的时间信息后退出,以处理其他事情。那么,与时间相关的其他信息谁去处理,何时处理?这就是由第三章讨论的后半部分去去处理。上面timer_interrupt()所做的事情就是上半部分。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org4)中断安装程序从上面的介绍可以看出,时钟中断与进程调度密不可分,因此,一旦开始有时钟中断就可能要进行调度,在系统进行初始化时,所做的大量工作之一就是对时钟进行初始化,其函数time_init()的代码在/arch/i386/kernel/time.c中,对其简写如下:void _init time_init(void)xtime.tv_sec=get_cmos_time();xtime.tv_usec=0;setup_irq(0,irq0);嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org其中的get_cmos_time()函数就是把当时的实际时间从CMOS时钟芯片读入变量xtime中,时间精度为秒。而setup_irq(0,irq0)就是时钟中断安装函数,那么irq0指的是什么呢,它是一个结构类型irqaction,其定义及初值如下:static struct irqaction irq0=timer_interrupt,SA_INTERRUPT,0,timer,NULL,NULL;setup_irq(0,&irq0)的代码在/arch/i386/kernel/irq.c中,其主要功能就是将中断程序连入相应的中断请求队列,以等待中断到来时相应的中断程序被执行。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org我们将有关函数改写如下,体现时钟中断的大意:do_timer_interrupt()*这是一个伪函数*SAVE_ALL*保存处理机现场*intr_count+=1;*这段操作不允许被中断*timer_interrupt()*调用时钟中断程序*intr_count-=1;jmp ret_from_intr/*中断返回函数*其中,jmp ret_from_intr 是一段汇编代码,也是一个较为复杂的过程,它最终要调用jmp ret_from_sys_call,即系统调用返回函数,而这个函数与进程的调度又密切相关,因此,我们重点分析jmp ret_from_sys_call。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org2系统调用返回函数:系统调用返回函数的源代码在/arch/i386/kernel/entry.S中ENTRY(ret_from_sys_call)cli#need_resched and signals atomic testcmpl$0,need_resched(%ebx)jne reschedulecmpl$0,sigpending(%ebx)jne signal_returnrestore_all:嵌入式嵌入式LinuxLinux内核开发教程内核开发教程之之系统调用系统调用返回函数返回函数千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgRESTORE_ALLALIGNsignal_return:sti#we can get here from an interrupt handlertestl$(VM_MASK),EFLAGS(%esp)movl%esp,%eaxjne v86_signal_returnxorl%edx,%edxcall SYMBOL_NAME(do_signal)jmp restore_allALIGN嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.orgv86_signal_return:call SYMBOL_NAME(save_v86_state)movl%eax,%espxorl%edx,%edxcall SYMBOL_NAME(do_signal)jmp restore_all.reschedule:call SYMBOL_NAME(schedule)#testjmp ret_from_sys_call嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org这一段汇编代码就是前面我们所说的“从系统调用返回函数”ret_from_sys_call,它是从中断、异常及系统调用返回时的通用接口。这段代码主体就是ret_from_sys_call函数,在此我们列出相关的几个函数:(1)ret_from_sys_call:主体(2)reschedule:检测是否需要重新调度(3)signal_return:处理当前进程接收到的信号(4)v86_signal_return:处理虚拟86模式下当前进程接收到的信号(5)RESTORE_ALL:我们把这个函数叫做彻底返回函数,因为执行该函数之后,就返回到当前进程的地址空间中去了。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程千锋千锋3G3G嵌入式移动互联网技术研发培训中心嵌入式移动互联网技术研发培训中心www.embedtrain.org www.mobiletrain.org可以看到ret_from_sys_call的主要作用有:检测调度标志need_resched,决定是否要执行调度程序;处理当前进程的信号;恢复当前进程的环境使之继续执行。最后我们再次从总体上浏览一下时钟中断:每个时钟滴答,时钟中断得到执行。时钟中断执行的频率很高:100次/秒,时钟中断的主要工作是处理和时间有关的所有信息、决定是否执行调度程序以及处理下半部分。和时间有关的所有信息包括系统时间、进程的时间片、延时、使用CPU的时间、各种定时器,进程更新后的时间片为进程调度提供依据,然后在时钟中断返回时决定是否要执行调度程序。下半部分处理程序是Linux提供的一种机制,它使一部分工作推迟执行。嵌入式嵌入式LinuxLinux内核开发教程内核开发教程