Board logo

标题: linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(6) [打印本页]

作者: yuyang911220    时间: 2015-5-29 18:34     标题: linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(6)

Adeos分析

1        简介
Adeos的全称是Adaptive Domain Environment for Operating System,它的目标是为操作系统提供了一个灵活的、可扩展的自适应环境,在这个环境下,多个相同或不同的操作系统可以共存,共享硬件资源;
随着历史的发展,目前已经存在了不少优秀的操作系统,正是因为这些操作系统的共同存在发展,而产生了以下的问题:
一方面,对于那些面向相同的用户,具有相似设计理念和功能的操作系统来说,它们之间是不兼容或不完全兼容的,例如,在Windows操作系统上的应用程序是不能直接在Linux上运行的;这就将用户(包括程序设计者和系统管理员)限制在了一个固定的软件环境下,用户在应用的选择上缺少灵活性。
另一方面,由于最初的应用环境和面向的用户的不同,有些操作系统在设计理念和功能上完全不同;但是,随着计算机技术的发展,现在的一个计算机系统往往具有以前多个系统的功能,各种计算机系统之间的界限越来越模糊;例如,现在的终端电子设备对实时性的要求越来越高(如智能手机),而某些实时系统也对人机界面的交互有了更高的要求,这就会促使这两种应用环境下的操作系统相互融合。
目前,主要存在两类方法使多个操作系统运行在同一个系统上;第一类方法是模拟,例如,VMWare,Plex86和VirtualPC等;它们都是在已有的操作系统上提供一个虚拟的硬件环境,在这个虚拟硬件环境下可以运行另外操作系统。这样,用户就可以充分的利用两个或多个系统所提供的功能和软件;但这种方法最大的缺点就是会极大的降低系统的性能,因为它包含三个软件层次:主机操作系统(Host OperatingSystem)->虚拟硬件环境->客户操作系统(Guest OperatingSystem)。第二类方法,是在硬件上实现一个所谓的超微内核(nano-kernel),通过这个超微内核实现硬件的共享,然后再在这个内核上构建实用的操作系统,例如,SPACE,Cache kernel和Exokernel等,但这些方法都没有考虑当前已经存在的操作系统和用户。
而Adeos是在已有的操作系统下插入一个软件层,通过向上层多个操作系统提供某些原语和机制而实现硬件共享。但是Adeos并不对硬件的使用强加任何的限制,上层的操作系统仍然可以自由的操作硬件,而不会因为Adeos的存在而有任何的约束(实际上,上层的操作系统可以完全不知道有Adeos的存在)。Adeos除了可以实现操作系统对系统资源的共享之外,还可以用于新的操作系统的开发、操作系统内核的调试、跟踪等。
目前,Adeos是基于Linux内核实现的,主要的应用是在Linux的实时化方面,使基于Linux的系统能满足硬实时的要求(Linux+RTAI)。

---------
2        基本原理
在基于Adeos的系统中,每个操作系统都在独立的域内运行(但不一定所有的域内实现的都是操作系统,也可以是完成其它功能的软件实体),每个域可以有独立的地址空间和类似于进程、虚拟内存等的软件抽象层,而且这些资源也可以由不同的域共享。
在基于Adeos的系统中,存在着四种类型的交互,如图3-1所示;

A类交互是各个域对硬件的直接操作,这些操作包括访存和和对硬件的设置等,在这种情况下,就和Adeos不存在一样;B类交互是双向的,一方面Adeos接收硬件产生的中断和异常,另一方面,Adeos也直接控制硬件;C类交互指当Adeos接收到硬件中断后,会执行相应域的中断服务程序;D类交互指当域内的操作系统知道有Adeos存在的时候,它可以主动向Adeos请求某些服务,例如,请求共享其它域中的资源、请求授权域优先级等。通过D类交互,可以实现各个域之间的通讯。
对于一个计算机系统来说,系统的运行是由内部和外部的中断和异常所触发的,例如系统时钟中断对操作系统来说就是最重要的,操作系统没有了系统时钟中断,就像人没有了心跳一样,所以说,如果想要控制操作系统的运行,最直接的方法就是接管操作系统的中断处理机制。所以,Adeos的主要工作就是管理硬件的中断,根据域的优先级依次执行相应域的中断服务程序,从而驱动域内的系统运行;同时,Adeos还提供域之间的通信机制、实现域的调度等。
为了实现对中断的管理和域之间的优先级控制,Adeos使用了中断管道(Interrupt Pipe)的概念,如图3-2所示;

Adeos通过中断管道在不同的域之间传播中断,而且提供了相应的机制可以让域改变自己在中断管道中的优先级,在图3-2中,各个域的优先级为:域1>域2>……>域N>Idle域;
通常,在操作系统中,对中断的处理方式有两种:允许中断和禁止中断;但在基于Adeos的系统中,由于存在着中断管道,域内的操作系统对中断的处理方式还有另外两种:抛弃中断和终止中断。如果某个域允许中断,中断产生后,Adeos会调用相应域的中断处理程序,这和不存在Adeos的情况是类似的,只不过在这种情况下,中断服务程序由Adeos负责调用;如果某个域禁止中断(实际上并没有真正禁止硬件中断,而只是设置了一个软件标志),当硬件中断沿着中断管道传播到这个域的时候,Adeos既不调用相应域的中断处理程序,也不会将此中断沿着中断管道进一步向下传播,而只是将这个硬件中断的中断类型和环境参数保存起来,并更新这个中断的中断次数。当域允许中断后,Adeos再根据中断类型、环境参数和中断次数调用相应的中断处理程序,并将此硬件中断沿着中断管道进一步向下传播。如果某个域抛弃某个硬件中断,当中断传播到这个域的时候,Adeos不做任何的处理,直接将这个中断沿着中断管道向后传播。如果某个域终止某个中断,当中断传播到这个域的时候,Adeos根据这个域的设置处理完这个中断之后,不再将这个中断沿着中断管道向后传播,也就是说,后面低优先级的域将不知道有这个硬件中断的产生。
所以,Adeos就是通过控制系统的中断来实现对各个域内操作系统的控制。从图3-3可以对基于Adeos的系统的运行模型有一个整体的概念;其中,D1、D2分别代表两个域,且优先级为D1>D2,为了使描述更加清晰明了,对系统作如下的假设:
系统有两个域D1和D2,两个域完全一样,除了优先级D1>D2,且两个域都允许中断;
整个系统只有两个硬件中断INT1和INT2;
每个域有两个中断服务程序ISR1和ISR2,分别对应于INT1和INT2;
每个域有两个任务TASK1和TASK2(不包括IDLE任务),分别由ISR1和ISR2触发运行;且TASK1的优先级高于TASK2(只有当TASK1任务完成后,TASK2才能开始运行);

从图3-3可以看出,在T1时刻,Adeos接收到了硬件的中断信号,然后就开始遍历中断管道,找到最高优先级的域D1,然后执行域D1的中断服务程序ISR1,ISR1执行完后,就切换到域D1,D1内的任务TASK1开始运行;TASK1运行完成后,域D1就被挂起(Suspended),Adeos然后执行D2的中断服务程序ISR1,ISR1执行完后,就切换到域D2,开始D2内TASK1的运行;当D2的TASK1运行到T2时刻时,硬件产生了中断信号INT2,域D2被中断,Adeos接收到INT2后,又再一次开始从头遍历中断管道,找到了最高优先级的域D1,然后执行D2的中断服务程序ISR2,ISR2执行完后,就切换到域D1,开始D1内任务TASK2的运行;TASK2运行完成后,域D1被挂起,Adeos然后执行D2的中断服务程序ISR2,ISR2执行完后,就切换到域D2,并开始域D2内被中断的任务TASK1和新触发的任务TASK2的执行;当域D2的任务都执行完成后,域D2被挂起,系统进入IDLE状态。
3        基于Linux的实现
考虑到从硬件层开始构建一个操作系统的难度,Adeos并没有并没有从零开始构建一个硬件抽象层;目前,Adeos是基于Linux内核实现的,这样的话,就可以将系统的启动和初始化工作都由Linux来完成,在系统完成初始化后,再进行Adeos的初始化工作(包括接管Linux的中断管理机制),Adeos功能既可以直接编译进内核,也可以作为一个内核模块在系统运行时动态加载,就和内核的驱动程序模块一样。
在这种实现方法下,Linux作为Adeos的一个特殊的域存在,我们称之为根域(RootDomain)。Adeos的很多功能都是依靠根域(也就是Linux内核)来实现的,例如,动态注册其它的域模块是通过Linux的动态模块加载功能实现的,为其它域的任务分配任务堆栈是通过Linux内存分配接口实现的等。根域的初始化是在Adeos的初始化过程中完成的;根域对于Adeos来说,有一点类似于Linux初始化过程中创建的INIT进程;
------------------
3.1        基本架构
Adeos在Linux配置中增加了三个配置开关来配置Adeos的代码:CONFIG_ADEOS_CORE,CONFIG_ADEOS和CONFIG_ADEOS_MODULE。如果定义了CONFIG_ADEOS_CORE,Adeos的核心支持就被编译进了Linux内核,不论Adeos功能最终编译进内核还是编译成可动态加载的模块,这个编译选项都必须被定义;如果定义了CONFIG_ADEOS,则也隐含着对CONFIG_ADEOS_CORE的定义,Adeos功能就被编译进了内核,那么,从Linux启动以后,Adeos功能就被使能了;如果定义了CONFIG_ADEOS_MODULE,则也隐含着对CONFIG_ADEOS_CORE的定义,Adeos功能被编译成可动态加载的模块,只有当这个模块被加载后,Adeos的功能才会起作用。
Adeos对Linux源代码树的修改涉及到30多个文件(包括新增加的文件),如图3-4所示。

其中的Makefie和Config.in文件,是为Adeos代码添加内核编译选项和内核配置选项;
adeos目录下的generic.c包含了与平台无关的通用的Adeos代码,而armv.c则包含了与ARM平台相关的通用于ARM平台的Adeos代码;
在arch/arm/kernel目录下,adeos.c中包含了Adeos关于中断处理的代码;armksyms.c中增加了代码,导出了ARM体系相关的Adeos接口;entry-armv.S和entry-common.S中增加了截获Linux中断和系统事件的代码,域的切换代码也在此处实现;同时,修改了irq.c以适应Adeos的中断处理机制;在process.c中修改了Linux的idle进程,当Linux进入idle状态时,将通知Adeos;time.c中增加了Adeos中修改定时器频率的接口;
Documentation/adeos.txt对Adeos进行了简单的介绍;
在init/main.c中增加了对Adeos进行初始化的代码;
kernel/adeos.c中包含的是Adeos对根域也就是Linux操作的代码;对kernel目录下的其它文件的修改,主要是为了增加Adeos对Linux系统事件进行捕获所需的代码;
3.2        源代码分析
-------------------------
3.2.1        Adeos相关实体
这里根据Adeos内全局量的重要性,对所有组成Adeos实体的全局量进行分析,包括其初始化、取值范围、功能等。

struct list_head __adeos_pipeline;
spinlock_t __adeos_pipelock = SPIN_LOCK_UNLOCKED;

在文件kernel/adeos.c中定义;Adeos的中断管道是用Linux的标准链表来实现的,而这个链表的头就是__adeos_pipeline,它实际上就是中断管道的访问入口,每个域都通过一个链表项按优先级连接在这个链表上。而__adeos_pipelock则是用来保护中断管道的互斥访问。

static adomain_t adeos_root_domain;
adomain_t *adp_root = &adeos_root_domain;
adomain_t *adp_cpu_current[ADEOS_NR_CPUS] = { [ 0 ... ADEOS_NR_CPUS - 1] = &adeos_root_domain };

在文件kernel/adeos.c中定义(本分析中的文件路径都是相对于Linux内核代码树的根目录而言的);adeos_root_domain是由Adeos静态定义的根域(也就是Linux);adp_root是指向根域的指针;而数组adp_cpu_current[]则是保存着指向CPU上当前运行的域的指针,ADEOS_NR_CPUS是系统中CPU的个数。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0