文库网
ImageVerifierCode 换一换
首页 文库网 > 资源分类 > PPT文档下载
分享到微信 分享到微博 分享到QQ空间

嵌入式ppt第五章.ppt

  • 资源ID:20014191       资源大小:1.83MB        全文页数:136页
  • 资源格式: PPT        下载积分:10文币
微信登录下载
快捷下载 游客一键下载
账号登录下载
三方登录下载: QQ登录 微博登录
二维码
扫码关注公众号登录
下载资源需要10文币
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
如填写123,账号就是123,密码也是123。
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 
账号:
密码:
验证码:   换一换
  忘记密码?
    
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

嵌入式ppt第五章.ppt

1、第第5章章 ARM-Linux内核内核目目 录录 5.1 5.1 ARM-LinuxARM-Linux概述概述5.2 5.2 ARM-LinuxARM-Linux进程管理进程管理5.3 5.3 ARM-LinuxARM-Linux内存管理内存管理5.4 5.4 ARM-LinuxARM-Linux模块模块5.5 5.5 ARM-LinuxARM-Linux中断管理中断管理5.6 5.6 ARM-LinuxARM-Linux系统调用系统调用Linux操作系统诞生于1991年,可安装在各种计算机硬件设备中,比如各种智能移动终端、路由器、台式计算机、大型机和超级计算机等。Linux支持包括x86、A

2、RM、MIPS和POWER-PC等在内的多种硬件体系结构。Linux存在着许多不同的版本,但它们都使用了Linux内核。Linux是一个一体化内核(monolithic kernel)系统。这里的“内核”指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件,一个内核不是一套完整的操作系统。一套建立在Linux内核的完整操作系统叫作Linux操作系统,或是GNU/Linux。LinuxLinux操作系统的灵魂是操作系统的灵魂是LinuxLinux内核内核,内核为系统其他部分提供系统服务。ARM-Linux内核是专门适应ARM体系结构设计的Linux内核,它负责整个系统的:进程管理

3、和调度、内存管理、文件管理、设备管理和网络管理等主要系统功能。ARM-Linux概述概述Part One5.15.15.1.1 GNU/Linux 操作系操作系统的基本体系的基本体系结构构用户空间包括用户应用程序和GNUC库(glibc库),负责执行用户应用程序。内核空间可以进一步划分成3层:系统调用接口(SystemCallInterface),它是用户空间与内核空间的桥梁独立于体系结构的内核代码依赖于体系结构的代码,构成了通常称为板级支持包BSP(BoardSupportPackage)的部分5.1.2 ARM-Linux内核版本及特点内核版本及特点ARM-Linux内核版本变化与内核版本

4、变化与Linux内核版本变内核版本变化保持同步。化保持同步。嵌入式linxu系统内核(如ARM_Linux内核)往往在标准linux基础上通过安装patch实现,如ARM_Linux内核就是对linux安装rmk补丁形成的,只有安装了这些补丁,内核才能顺利地移植到ARM_Linux上。当然也可以通过已经安装好补丁的内核源码包实现。在2.6版本之前,Linux内核版本的命名格式为“A.B.C”。数字A是内核版本号,数字B是内核主版本号,主版本号根据传统的奇-偶系统版本编号来分配:奇数为开发版,偶数为稳定版;数字C是内核次版本号,次版本号是无论在内核增加安全补丁、修复bug、实现新的特性或者驱动时

5、都会改变。2011年5月29号,设计者LinusTorvalds宣布为了纪念Linux发布20周年,在2.6.39版本发布之后,内核版本将升到3.0。Linux继续使用在2.6.0版本引入的基于时间的发布规律,但是使用第二个数例如在3.0发布的几个月之后发布3.1,同时当需要修复bug和安全漏洞的时候,增加一个数字(现在是第三个数)来表示,如3.0.18。Mainline是主线版本,Stable是稳定版,由Longterm是长期支持版Linux是一个内核运行在单独的内核地址空间的单内核单内核,但是汲取了微内核的精华汲取了微内核的精华如模块化设计、抢占式内核、支持内核线程以及动态装载内核模块等特

6、点。以2.6版本为例,其主要特点有:(1)支持动态加载内核模块机制。(2)支持对称多处理机制(SMP)。(3)O(1)的调度算法。(4)linux内核可抢占,linux内核具有允许在内核运行的任务优先执行的能力。(5)linux不区分线程和其他一般的进程,对内核来说,所有的进程都一样(仅部分共享资源)。(6)linux提供具有设备类的面向对象的设备模块、热插拔事件,以及用户空间的设备文件系统。5.1.3 ARM-Linux内核的主要架构及功能内核的主要架构及功能根据内核的核心功能,Linux内核具有5个主要的子系统,分别负责如下的功能:进程管理、内存管理、虚拟文件系统、进程间通信和网络接口。1

7、.1.进程管理进程管理进程管理负责管理CPU资源,以便让各个进程能够以尽量公平的方式访问CPU。进程管理负责进程的创建和销毁,并处理它们和外部世界之间的连接(输入输出)。除此之外,控制进程如何共享的调度器也是进程管理的一部分。概括来说,内核进程管理活动就是在单个或多个CPU上实现了多个进程的抽象。进程管理源码可参考./linux/kernel目录。2.内存管理内存管理Linux内核所管理的另外一个重要资源是内存。内存管理策略是决定系统性能好坏的一个关键因素。内核在有限的可用资源之上为每个进程都创建了一个虚拟空间。内存管理的源代码可以在./linux/mm中找到。3.虚拟文件系统虚拟文件系统文件

8、系统在Linux内核中具有十分重要的地位,用于对外设的驱动和存储,隐藏了各种硬件的具体细节。Linux引入了虚拟文件系统(VirtualFileSystem)为用户提供了统一、抽象的文件系统界面,以支持越来越繁杂的具体的文件系统。Linux内核将不同功能的外部设备,例如Disk设备、输入输出设备、显示设备等,抽象为可以通过统一的文件操作接口来访问。Linux中的绝大部分对象都可以视为文件并进行相关操作。4.进程间通信进程间通信不同进程之间的通信是操作系统的基本功能之一。Linux内核通过支持POSIX规范中标准的IPC(InterProcessCommunication,相互通信)机制和其他许

9、多广泛使用的IPC机制实现进程间通信。IPC不管理任何的硬件,它主要负责Linux系统中进程之间的通信。比如UNIX中最常见的管道、信号量、消息队列和共享内存等。另外,信号(signal)也常被用来作为进程间的通信手段。Linux内核支持POSIX规范的信号及信号处理并广泛应用。5.网络管理网络管理网络管理提供了各种网络标准的存取和各种网络硬件的支持,负责管理系统的网络设备,并实现多种多样的网络标准。网络接口可以分为网络设备驱动程序和网络协议。这五个系统相互依赖,缺一不可,但是相对而言进程管理处于比较重要的地位,其他子系统的挂起和恢复进程的运行都必须依靠进程调度子系统的参与。调度程序的初始化及

10、执行过程中需要内存管理模块分配其内存地址空间并进行处理;进程间通信需要内存管理实现进程间的内存共享;而内存管理利用虚拟文件系统支持数据交换,交换进程(swapd)定期由调度程序调度;虚拟文件系统需要使用网络接口实现网络文件系统,而且使用内存管理子系统实现内存设备管理,同时虚拟文件系统实现了内存管理中内存的交换。5.1.4 linux内核源内核源码目目录结构构Arch目录包括了所有和体系结构相关的核心代码。它下面的每一个子目录都代表一种Linux支持的体系结构Include目录包括编译核心所需要的大部分头文件,Init目录包含核心的初始化代码,需要注意的是该代码不是系统的引导代码。Mm目录包含了

11、所有的内存管理代码。与Drivers目录中是系统中所有的设备驱动程序。Ipc目录包含了核心进程间的通信代码。Modules目录存放了已建好的、可动态加载的模块。Fs目录存放Linux支持的文件系统代码。不同的文件系统有不同的子目录对应,如jffs2文件系统对应的就是jffs2子目录。Kernel内核管理的核心代码放在这里。另外与处理器结构相关代码都放在arch/*/kernel目录下。Net目录里是核心的网络部分代码。Lib目录包含了核心的库代码,但是与处理器结构相关的库代码被放在arch/*/lib/目录下。Scripts目录包含用于配置核心的脚本文件。Documentation目录下是一些

12、文档,是对目录作用的具体说明。ARM-Linux进程管理进程管理Part Two5.25.2进程是处于执行期的程序以及它所管理的资源的总称进程是处于执行期的程序以及它所管理的资源的总称,这些资源包括如打开的文件、挂起的信号、进程状态、地址空间等。程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源。进程管理是进程管理是LinuxLinux内核中最重要的子系统,它主要提供对内核中最重要的子系统,它主要提供对CPUCPU的访问控制。的访问控制。由于计算机中,CPU资源是有限的,而众多的应用程序都要使用CPU资源,所以需要“进程调度子系统”对CPU进行调度管理。

13、图5-4Linux进程管理调度子系统基本架构Scheduling Policy模块。模块。该模块实现进程调度的策略,它决定哪个(或者哪几个)进程将拥有CPU资源。Architecture-specific Schedulers模块模块。该模块涉及体系结构相关的部分,用于将对不同CPU的控制抽象为统一的接口。这些控制功能主要在suspend和resume进程时使用,包含CPU的寄存器访问、汇编指令操作等。Architecture-independent Scheduler模块。模块。该模块涉及体系结构无关的部分,会和“SchedulingPolicy模块”沟通,决定接下来要执行哪个进程,然后通过

14、“Architecture-specificSchedulers模块”指定的进程予以实现。System Call Interface,系统调用接口。,系统调用接口。进程调度子系统通过系统调用接口将需要提供给用户空间的接口开放出去,同时屏蔽掉不需要用户空间程序关心的细节。5.2.1 进程的表示和切换进程的表示和切换Linux内核通过一个被称为进程描述符的task_struct结构体(也叫进程控制块)来管理进程,这个结构体记录了进程的最基本的信息,进程描述符进程描述符中不仅包含了许多描述进程属性的字段,而且还包含一系列指向其他数据结构的指针。内核把每个进程的描述符放在一个叫做任务队列的双向循环链表

15、当中,它定义在./include/linux/sched.h文件中。系统中的每个进程都必然处于以上所列进程状态中的一种。这里对进程状态给予说明TASK_RUNNING表示进程要么正在执行,要么正要准备执行。TASK_INTERRUPTIBLE表示进程被阻塞(睡眠),直到某个条件变为真。条件一旦达成,进程的状态就被设置为TASK_RUNNING。TASK_UNINTERRUPTIBLE的意义与TASK_INTERRUPTIBLE基本类似,除了不能通过接受一个信号来唤醒以外。_TASK_STOPPED表示进程被停止执行。_TASK_TRACED表示进程被debugger等进程监视。TASK-WAK

16、EKILL该状态是当进程收到致命错误信号时唤醒进程。TASK_WAKING:该状态说明该任务正在唤醒,其他唤醒操作均会失败。都被置为TASK_DEAD状态。TASK_DEAD:一个进程在退出时,state字段都被置于该状态。EXIT_ZOMBIE:表示进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息。EXIT_DEAD:进程在系统中被删除时将进入该状态。该状态表示进程的最终状态。EXIT_ZOMBIE和EXIT_DEAD也可以存放在exit_state成员中。图5-5进程状态的切换5.2.2 进程、程、线程和内核程和内核线程程在Linux内核中,内核是采用进程、

17、线程和内核线程统一管理的方法实现进程管理的。内核将进程、线程和内核线程一视同仁内核将进程、线程和内核线程一视同仁1.即内核使用唯一的数据结构task_struct来分别表示它们;2.内核使用相同的调度算法对这三者进行调度;3.内核也使用同一个函数do_fork()来分别创建这三种执行线程(threadofexecution)。执行线程通常是指任何正在执行的代码实例,比如一个内核线程,一个中断处理程序或一个进入内核的进程。进程是系统资源分配的基本单位,线程是程序独立运行的基本单位线程有时候也被称作小型进程如果内核要对线程进行调度,那么线程必须如同进程那样在内核中对应一个数据结构。进程在内核中有相

18、应的进程进程描述符,即描述符,即task_struct结构结构。在内核中还有一种特殊的线程,称之为内核线程(KernelThread)。由于在内核中进程和线程不做区分,因此也可以将其称为内核进程。内核线程在内核中也是通过task_struct结构来表示的内核线程和普通进程的不同:内核线程和普通进程的不同:1.内核线程永远都运行在内核态,而不同进程既可以运行在用户态也可以运行在内核态。从地址空间的使用角度来讲,内核线程只能使用大于3GB的地址空间,而普通进程则可以使用整个4GB的地址空间。2.内核线程只能调用内核函数无法使用用户空间的函数,而普通进程必须通过系统调用才能使用内核函数。5.2.3

19、进程描述符进程描述符task_struct的几个特殊字段的几个特殊字段(1)mm字段:指向mm_struct结构的指针,该类型用来描述进程整个的虚拟地址空间。其数据结构如下:structmm_struct*mm,*active_mm;#ifdefCONFIG_COMPAT_BRKunsignedbrk_randomized:1;#endif#ifdefined(SPLIT_RSS_COUNTING)structtask_rss_statrss_stat;#endif(2)fs字段:指向fs_struct结构的指针,该字段用来描述进程所在文件系统的根目录和当前进程所在的目录信息。3)files字

20、段:指向files_struct结构的指针,该字段用来描述当前进程所打开文件的信息。5.2.3 进程描述符进程描述符task_struct的几个特殊字段的几个特殊字段(4)signal字段:指向signal_struct结构(信号描述符)的指针,该字段用来描述进程所能处理的信号。其数据结构如下;/*signalhandlers*/structsignal_struct*signal;structsighand_struct*sighand;sigset_tblocked,real_blocked;sigset_tsaved_sigmask;/*restoredifset_restore_sig

21、mask()wasused*/structsigpendingpending;unsignedlongsas_ss_sp;size_tsas_ss_size;int(*notifier)(void*priv);void*notifier_data;sigset_t*notifier_mask;对于普通进程来说,上述字段分别指向具体的数据结构以表示该进程所拥有的资源。对应每个线程而言,内核通过轻量级进程与其进行关联。轻量级进程之所轻量,是因为它与其它进程共享上述所提及的进程资源。举例:进进程程A A创创建建了了线线程程B B,则则B B线线程程会会在在内内核核中中对对应应一一个个轻轻量量级级进进

22、程程。这这个个轻轻量量级级进进程程对对应应一一个个进进程程描描述述符符,而而且且B B线线程程的的进进程程描描述述符符中中的的某某些些代代表表资资源源指指针针会会和和A A进进程程中中对对应应的的字字段段指指向向同同一一个个数数据据结结构构,这样就实现了多线程之间的资源共享。这样就实现了多线程之间的资源共享。5.2.4 do_fork()函数函数图5-6do_fork()函数对于进程、线程以及内核线程的应用内核中创建进程的核心函数即为do_fork(),该函数的原型如下:longdo_fork(unsignedlongclone_flags,unsignedlongstack_start,st

23、ructpt_regs*regs,unsignedlongstack_size,int_user*parent_tidptr,int_user*child_tidptr)该函数的参数的功能说明如下:clone_flagsclone_flags:代表进程各种特性的标志。低字节指定子进程结:代表进程各种特性的标志。低字节指定子进程结束时发送给父进程的信号代码,一般为束时发送给父进程的信号代码,一般为SIGCHLDSIGCHLD信号,剩余三个信号,剩余三个字节是若干个标志或运算的结果。字节是若干个标志或运算的结果。stack_startstack_start:子进程用户态堆栈的指针,该参数会被赋值给

24、子子进程用户态堆栈的指针,该参数会被赋值给子进程的进程的espesp寄存器寄存器。regs:指向通用寄存器值的指针,当进程从用户态切换到内核态时通用寄存器中的值会被保存到内核态堆栈中。stack_size:未被使用,默认值为0。parent_tidptr:该子进程的父进程用户态变量的地址,仅当CLONE_PARENT_SETTID被设置时有效。child_tidptr:该子进程用户态变量的地址,仅当CLONE_CHILD_SETTID被设置时有效。一个问题:一个问题:既然进程、线程和内核线程在内核中都既然进程、线程和内核线程在内核中都是通过是通过do_fork()完成创建的,那么完成创建的,那

25、么do_fork()是如何是如何体现其功能的多样性?体现其功能的多样性?clone_flags参数在这里起到了关键作用参数在这里起到了关键作用,通过选取不同的标志,从而保证了do_fork()函数实现多角色创建进程、线程和内核线程功能的实现。下面只介绍其中几个主要的标志。CLONE_VIM:子进程共享父进程内存描述符和所有的页表。CLONE_FS:子进程共享父进程所在文件系统的根目录和当前工作目录。CLONE_FILES:子进程共享父进程打开的文件。CLONE_SIGHAND:子进程共享父进程的信号处理程序、阻塞信号和挂起的信号。使用该标志必须同时设置CLONE_VM标志。如果创建子进程时设置

26、了上述标志,那么子进程会共享这些标志所代表的父进程资源。5.2.5 进程的创建进程的创建在用户态程序中,可以通过fork()、vfork()和clone()三个接口函数创建进程,这三个函数在库中分别对应同名的系统调用。系统调用函数通过128号软中断进入内核后,会调用相应的系统调用服务例程。分别是sys_fork()、sys_vfork()和sys_clone()。int sys_fork(struct pt_regs*regs)return do_fork(SIGCHLD,regs-sp,regs,0,NULL,NULL);int sys_vfork(struct pt_regs*regs)r

27、eturn do_fork(CLONE_VFORK|CLONE_VM|SIGCHLD,regs-sp,regs,0,NULL,NULL);Long sys_clone(unsigned long clone_flags,unsigned long newsp,void _user*parent_tid,void _user*child_tid,struct pt_regs*regs)if(!newsp)newsp=regs-sp;return do_fork(clone_flags,newsp,regs,0,parent_tid,child_tid);三个系统服务例程内部都调用了do_fork

28、()do_fork(),主要差别在于第一个参数所传的值不同。下面予以说明:(1)fork():由于do_fork()中clone_flags参数除了子进程结束时返回给父进程的SIGCHLD信号外并无其他特性标志,因此由fork()创建的进程不会共享父进程的任何资源。子进程会完全复制父进程的资源,也就是说父子进程相对独立。不过由于写时复制技术(CopyOnWrite)的引入,子进程可以只读父进程的物理页,只有当父进程或者子进程去写某个物理页时,内核此时才会将这个页的内容拷贝到一个新的物理页,并把这个新的物理页分配给正在写的进程。(2)vfork():do_fork()中的clone_flags使

29、用了CLONE_VFORK和CLONE_VM两个标志。CLONE_VFORK标志使得子进程先于父进程执行,父进程会阻塞到子进程结束或执行新的程序。CLONE_VM标志使得子进程可以共享父进程的内存地址空间(父进程的页表项除外)。在写时复制技术引入之前,vfork()适用子进程形成后立即执行execv()的情形。因此,vfork()现如今已经没有特别的使用之处,因为写时复制技术完全可以取代它创建进程时所带来的高效性。(3 3)clone()clone():cloneclone通常用于创建轻量级进程。通常用于创建轻量级进程。通过传递不同的标志可以对父子进程之间数据的共享和复制作精确的控制,一般fl

30、ags的取值为CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND。由上述标志可以看到,轻量级进程通常共享父进程的内存地址空间、父进程所在文件系统的根目录以及工作目录信息、父进程当前打开的文件以及父进程所拥有的信号处理函数。5.2.6 线程和内核程和内核线程的程的创建建每个线程在内核中对应一个轻量级进程,两者的关联是通过线程库完成的。因此通过pthread_create()创建的线程最终在内核中是通过clone()完成创建的,而clone()最终调用do_fork()。一个新内核线程的创建是通过在现有的内核线程中使用kernel_thread()而创建的,其本

31、质也是向do_fork()提供特定的flags标志而创建的。Intkernel_thread(int(*fn)(void*),void*arg,unsignedlongflags)returndo_fork(flags|CLONE_VM|CLONE_UNTRACED,0,®s,0,NULL,NULL);从上面的组合的flags标志可以看出,新的内核线程至少会共享父内核线程的内存地址空间。5.2.7 进程的程的执行行-exec函数族函数族在linux中中exec函数族提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代

32、码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。在Linux中使用exec函数族主要有两种情况:(1)当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用exec函数族中的任意一个函数让自己重生。(2)如果一个进程希望执行另一个程序,那么它就可以调用fork()函数新建一个进程,然后调用exec函数族中的任意一个函数,这样看起来就像通过执行应用程序而产生了一个新进程。实际上,在Linux中并没有exec()函数,而是有6个以exec开头的函数事实上,这6个函数中真正的系统调用只有execve(),其他5个都是库函数,它们最终都会调用execve()这个

33、系统调用。这里简要介绍execve()执行的流程:(1)打开可执行文件,获取该文件的file结构;(2)获取参数区长度,将存放参数的页面清零;(3)对linux_binprm结构的其它项作初始化。这里的linux_binprm结构用来读取并存储运行可执行文件的必要信息。5.2.8 进程的程的终止止当进程终结时,内核必须释放它所占有的资源,并告知其父进程。进程的终止可以通过以下三个事件驱动:正常的进程结束正常的进程结束信号信号exitexit()函数的调用。()函数的调用。进程的终结最终都要通过进程的终结最终都要通过do_exit()do_exit()来完成。来完成。exit()函数所需的头文件

34、为#include,函数原型是:void exit(int status)do_exitdo_exit()的执行过程:()的执行过程:(1)将task_struct中的标志成员设置PF_EXITING,表明该进程正在被删除,释放当前进程占用的mm_struct,如果没有别的进程使用,即没有被共享,就彻底释放它们(2)如果进程排队等候IPC信号,则离开队列(3)分别递减文件描述符、文件系统数据、进程名字空间的引用计数。如果这些引用计数的数值降为0,则表示没有进程在使用这些资源,可以释放。(4)向父进程发送信号:将当前进程的子进程的父进程重新设置为线程组中的其他线程或者init进程,并把进程状态设

35、成TASK_ZOMBIE(5)切换到其他进程,处于TASK_ZOMBIE状态的进程不会再被调用。此时进程占用的资源就是内核堆栈、thread_info结构、task_struct结构。此时进程存在的唯一目的就是向它的父进程提供信息。父进程检索到信息后,或者通知内核那是无关的信息后,由进程所持有的剩余内存被释放,归还给系统使用。5.2.9 进程的程的调度度LinuxLinux进程调度分为进程调度分为主动调度主动调度和和被动调度被动调度两种方式:两种方式:主动调度随时都可以进行,内核里可以通过schedule()启动一次调度,当然也可以将进程状态设置为TASK_INTERRUPTIBLE、TASK

36、_UNINTERRUPTIBLE,暂时放弃运行而进入睡眠,用户空间也可以通过pause()达到同样的目的;如果为这种暂时的睡眠放弃加上时间限制,内核态有schedule_timeout,用户态有nanosleep()用于此目的。从Linux2.6内核后,linux实现了抢占式内核抢占式内核,linux2.6内核之前的版本会恢复原进程的运行,直到该进程退出内核态才会引发调度程序;而linux2.6抢占式内核,在处理完中断后,会立即引发调度,切换到高权值进程。为支持内核代码可抢占,在2.6版内核中通过采用禁止抢占的自旋自旋锁(锁(spin_unlock_mutexspin_unlock_mutex

37、)来保护临界区。2.进程调度的一般原理进程调度的一般原理调度程序运行时,要在所有可运行的进程中选择最值得运行的进程。选择进程的依据主要有:进程的调度策略(进程的调度策略(policypolicy)、)、静态优先级(静态优先级(prioritypriority)、)、动态优先级(动态优先级(countercounter)、)、实时优先级(实时优先级(rt-priorityrt-priority)。Policy是进程的调度策略,用来区分实时进程和普通进程Counter是实际意义上的进程动态优先级,它是进程剩余的时间片,起始值就是priority的值。在在linuxlinux中,用函数中,用函数go

38、ognessgoogness()综合四项依据及其他因素,赋予各影响因素权重()综合四项依据及其他因素,赋予各影响因素权重(weightweight),调度程序以权重作为选择进程的依据。),调度程序以权重作为选择进程的依据。3.Linux O(1)调度调度O(1)调度程序:内核实现了一种新型的调度算法,不管有多少个线程在竞争 CPU,这种算法都可以在固定时间内进行操作。这个名字就表示它调度多个线程所使用的时间和调度一个线程所使用的时间是相同的。Linux2.6实现O(1)调度,每个CPU都有两个进程队列,采用优先级优先级为基础为基础的调度策略。内核为每个进程计算出一个反映其运行“资格”的权值,然

39、后挑选权值最高的进程投入运行。在运行过程中,当前进程的资格随时间而递减,从而在下一次调度的时候原来资格较低的进程可能就有资格运行了。到所有进程的资格都为零时,就重新计算。Schedule()函数是完成进程调度的主要函数,并完成进程切换的工作。它在/kernel/sched.c中的定义如下:/*schedule()isthemainschedulerfunction.*/asmlinkagevoid_schedschedule(void)structtask_struct*prev,*next;unsignedlong*switch_count;structrq*rq;intcpu;need_r

40、esched:preempt_disable();cpu=smp_processor_id();rq=cpu_rq(cpu);rcu_sched_qs(cpu);prev=rq-curr;switch_count=&prev-nivcsw;release_kernel_lock(prev);schedule的主要工作可以分为两步。首先是找到next。1.schedule()检查prev的状态。2.检查本地运行队列中是否有进程。3.若本地运行队列中有进程,但没有活动进程队列为空集。这时把活动进程队列改为过期进程队列,把原过期进程队列改为活动进程队列。空集用于接收过期进程。4.在活动进程队列中搜索

41、一个可运行进程。5.检查next是否是实时进程以及是否从TASK_INTERRUPTIBLE或TASK_STOPPED状态中被唤醒。找到next后,就可以实施进程切换了。1.把next的进程描述符第一部分字段的内容装入硬件高速缓存。2.清除prev的TIF_NEED_RESCHED的标志。3.设置prev的进程切换时刻。4.重新计算并设置prev的平均睡眠时间。5.如果prev!=next,切换prev和next硬件上下文。这时,CPU已经开始执行next进程了。ARM-Linux内存管理内存管理Part Three5.35.35.3.1 ARM-Linux内存管理概述内存管理概述内存管理是L

42、inux内核中最重要的子系统之一,它主要提供对内存资源的访问控制机制。这种机制主要涵盖了:内存的分配和回收。内存的分配和回收。地址转换。地址转换。内存扩充。内存扩充。内存的共享与保护。内存的共享与保护。Linux系统会在硬件物理内存和进程所使用的内存(称作虚拟内存)之间建立一种映射关系,这种映射是以进程为单位,因而不同的进程可以使用相同的虚拟内存,而这些相同的虚拟内存,可以映射到不同的物理内存上。图5-7内存管理主要子系统架构ArchitectureSpecificManagers子模块,涉及体系结构相关部分,提供用于访问硬件Memory的虚拟接口。ArchitectureIndependen

43、tManager子模块,涉及体系结构无关部分,提供所有的内存管理机制,包括以进程为单位的memorymapping、虚拟内存的交换技术Swapping等。SystemCallInterface系统调用接口。通过该接口,向用户空间程序应用程序提供内存的分配、释放,文件的映射等功能。ARM-Linux内核的内存管理功能是采用请求调页式的虚请求调页式的虚拟存储技术拟存储技术实现的。ARM-Linux内核根据内存的当前使用情况动态换进换出进程页,通过外存上的交换空间存放换出页。内存与外存之间的相互交换信息是以页为单以页为单位位进行的,这样的管理方法具有良好的灵活性,并具有很高的内存利用率。5.3.2

44、ARM-Linux虚虚拟存存储空空间及分布及分布在系统空间,即在内核中,虚拟地址与物理地址在数值上是相同的,至于用户空间的地址映射是动态的,根据需要分配物理内存,并且建立起具体进程的虚拟地址与所分配的物理内存间的映射。需要值得注意的是,系统空间的一部分不是映射到物理内存,而是映射到一些I/O设备,包括寄存器和一些小块的存储器。代码段:代码段是用来存放可执代码段:代码段是用来存放可执行文件的操作指令行文件的操作指令数据段:数据段用来存放可执行文件中已初始化全局变量BSSBSS段:段:BSSBSS段包含了程序中未初段包含了程序中未初始化的全局变量,始化的全局变量,堆(堆(heapheap):堆是用

45、于存放进程):堆是用于存放进程运行中被动态分配的内存段,运行中被动态分配的内存段,栈:栈是用户存放程序临时创栈:栈是用户存放程序临时创建的局部变量建的局部变量BSS段:段:BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文BlockStartedbySymbol的简称。BSS段属于静态内存分配。数据段:数据段:数据段(datasegment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。代码段:代码段:代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域

46、的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。堆(堆(heap):):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)栈栈(stack):栈又称堆栈,是用户存放程序临时创建的局部变量,也就是说我们函数括弧“”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外

47、,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。例一】用cl编译两个小程序如下:程序1:intar30000;voidmain().程序2:intar300000=1,2,3,4,5,6;voidmain().发现程序2编译之后所得的.exe文件比程序1的要大得多。手工编译了一下,并使用了/FAs编译选项来查看了一下其各自的.asm,发现在程序1.asm中ar的定义如下:_BSSSEGMENT?ar3PAHADD0

48、493e0HDUP(?);ar_BSSENDS而在程序2.asm中,ar被定义为:_DATASEGMENT?ar3PAHADD01H;arDD02HDD03HORG$+1199988_DATAENDS区别很明显,一个位于.bss段,而另一个位于.data段,两者的区别在于:全局的未初始化变量存在于.bss段中,具体体现为一个占位符;全局的已初始化变量存于.data段中;而函数内的自动变量都在栈上分配空间。.bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);而.data却需要占用,其内容由程序初始化,因此造成了上述情况。【例二】编译如下程序(test.cpp):#include#

49、defineLEN1002000intinbssLEN;floatfA;intindataLEN=1,2,3,4,5,6,7,8,9;doubledbB=100.0;constintcst=100;intmain(void)intrun100=1,2,3,4,5,6,7,8,9;for(inti=0;iflags值;第四个参数prot为映射时页保护。(4)voidvunmap(void*addr)该函数的作用是释放由vmap映射的虚拟内存,释放从addr地址开始的连续虚拟区域。5.3.6 页面回收简述页面回收简述页面回收的方法大体上可分为两种:一是主动释放。一是主动释放。就像用户程序通过fre

50、e函数释放曾经通过malloc函数分配的内存一样,页面的使用者明确知道页面的使用时机。前文所述的伙伴算法和slab分配器机制,一般都是由内核程序主动释放的。对于直接从伙伴系统分配的页面,这是由使用者使用free_pages之类的函数主动释放的,页面释放后被直接放归伙伴系统;从slab中分配的对象(使用kmem_cache_alloc函数),也是由使用者主动释放的(使用kmem_cache_free函数)。二是通过linux内核提供的页框回收算法(页框回收算法(PFRA)进行回收。页面的使用者一般将页面当作某种缓存,以提高系统的运行效率。缓存一直存在固然好,但是如果缓存没有了也不会造成什么错误,


注意事项

本文(嵌入式ppt第五章.ppt)为本站会员(bubibi)主动上传,文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文库网(点击联系客服),我们立即给予删除!




关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

文库网用户QQ群:731843829  微博官方号:文库网官方   知乎号:文库网

Copyright© 2025 文库网 wenkunet.com 网站版权所有世界地图

经营许可证编号:粤ICP备2021046453号   营业执照商标

1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png