嵌入式实时操作系统高效可靠的内存保护方法

文档序号:6361869阅读:222来源:国知局
专利名称:嵌入式实时操作系统高效可靠的内存保护方法
技术领域
本发明涉及一种计算机操作系统内存保护的方法,尤其涉及嵌入式系统和实时系统领域的内存保护。
背景技术
内存保护是嵌入式实时操作系统(称为RTOS)的重要内容,内存保护方法的优劣,直接关系到RTOS的安全性、稳定性和可靠性。
现有RTOS在内存保护方面缺乏行之有效的办法,对于内存越界,即一个进程向不属于自身的内存空间写入数据的事件无法有效的捕获。
一些大型通用操作系统,如UNIx、Linux以及Mocrosoft Windows系列均采用“隔离”的策略,即把各个进程的空间(虚拟地址空间)通过不同的页表完全分开。但这种方式的缺点是进程间切换开销过大,并且无法通过共享内存交换数据,不适合RTOS。
一些商用RTOS,如VxWorks、pSOS等,完全利用基于处理器MMU(存储器管理单元)的页保护机制,对代码段和中断向量表实现了写保护,但对进程间的保护非常欠缺。此外,在更多的应用场合,处理器硬件没有MMU,在此情况下现有的RTOS均没有实现内存保护。
综上所述,现有技术的缺点有两个一是内存保护的粒度太大,无法对小于一页的数据结构实施保护;二是过于依赖硬件,不能在没有MMU的情况下实现内存保护。

发明内容
本发明所要解决的技术问题在于克服上述现有技术的不足之处而提出一种嵌入式实时操作系统的内存保护方法,所述方法具有适用范围广、可靠性高、实时性强的特点,在有无MMU的情况下均实现了对堆栈、核心数据以及各种用户数据结构实施单独的、细粒度的有效保护,从而极大的提高了RTOS的安全性、稳定性和可靠性。
本发明的目的可以通过采用以下技术措施来达到设计一种嵌入式实时操作系统高效、可靠的内存保护方法,设置若干内存块,供不同应用程序和不同进程调用或共享;尤其是在被启用内存连接部件的边缘设立至少一保护标志。
采用本发明所述方法,与现有技术相比,由于采取了“保护字和/或保护页”的技术措施,使得在有无MMU的情况下均实现了高可靠、细粒度的有效内存保护,极大的提高了系统的安全性、稳定性和可靠性。


图1是带保护字的连接部件及链表结构示意图;其中图1a是带保护字的连接部件;图1b是带保护字连接部件形成的链表;图2是基于带保护字连接部件的用户链表示意图;图3是偏移量OFFSET示意图;图4是带保护字的内存块示意图;图5是带保护页的内存块示意图。
具体实施例方式
以下结合附图详述本发明的实施例。
一种嵌入式实时操作系统高效、可靠的内存保护方法,设置若干内存块,供不同应用程序和不同进程调用或共享;其特征在于在被启用内存连接部件的边缘设立至少一保护标志。
实现以所述外连接部件为节点的链表基础库;所述应用程序和实时操作系统(RTOS)其它程序在节点结构的声明中用连接部件代替指针,并且所有涉及链表的操作均使用所述链表基础库。
该内存保护方法还包括以下步骤1)、所述应用程序和RTOS其它程序申请内存块及创建堆栈时,在所述内存块首、尾分别附上所述保护字;2)、每次对一个内存数据块进行操作之前,验证每一个保护字是否是原始值;验证不通过则抛出一个异常信息,等待处理;通过则继续操作。
所述验证可以在用户调用free释放此内存时进行单个验证,也可使用一个低优先级任务在系统空闲时逐一验证。
所述保护字被赋予一个特殊的值。
在使用MMU(存储管理单元)的情况下,所述保护标志是MMU可操作的保护页。
所述保护页的大小为4K,分别加在应用程序申请的内存块或堆栈的首尾部分。并且所述保护页被映射到无效的物理地址。
本发明所述嵌入式实时操作系统的内存保护方法可简述如下第一步定义带保护字的连接部件,并且实现以此连接部件为节点的链表基础库,其中包括此类链表上的全部操作,参见图1。
第二步应用程序和RTOS的其它程序中所有涉及链表的操作均使用已定义的所述链表基础库,不再直接操作指针,其前提是节点结构的声明中用连接部件代替相应的指针。参见图2
第三步在应用程序和RTOS的其它程序申请内存块(包括创建堆栈)时,把此内存块的首尾分别附上保护字,参见图3。
第四步每次对一个数据块进行操作之前,验证每一个保护字是否为原始值,验证不通过则抛出一个异常,通过则继续。
显然,第一步至第四步的操作对于有无MMU的情况均适用。
第五步对于有MMU的情况,当应用程序申请内存块或分配堆栈时,在其首尾可以分别添加一个保护页,并把保护页映射到无效的物理地址。
第五步仅适用于有MMU的情况。在此情况下,仅使用保护页,而不使用保护字。
下面结合附图,基本按照附图的顺序对技术方案的实施作进一步的详细描述图1(a)介绍了带保护字的连接部件。该部件分为两部分逻辑部分和保护部分。逻辑部分为一个普通的双向链表连接节点,由一个“next”指针和一个“prev”指针组成,分别用于指向其后继节点和前驱节点。保护部分是在逻辑部分前后分别添加保护指针(“guard1”和“guard2”),并使其均指向本节点。图1(b)介绍了使用这种带保护字的连接部件形成的链表。带保护字连接部件的C语言定义如下typedef struct T_ConnectNode{struct T_ConnectNode*guard1;struct T_ConnectNode*next;struct T_ConnectNode*prev;struct T_ConnectNode*guard2;}CNODE;除定义带保护字连接部件外,还应当实现一个链表库,该库中封装了全部链表操作,包括插入、删除、判空、查找(通过回调函数实现)等。链表库的所有操作仅对带保护字连接部件的逻辑部分进行读写,读写之前对保护部分进行验证。相关代码示例如下<pre listing-type="program-listing">  /*******************************************************/  void InitNode(CNODE*pNode)  {  pNode->guard1=pNode->guard2=pNode;  }  /*******************************************************/  STATUS Verify(CNODE*pNode) /*节点验证*/  {  if((pNode->guard1==pNode)&amp;amp;&amp;amp;(pNode->guard2==pNode))  return OK;  else   return ERROR;  }  /*******************************************************/  typedef struct/*定义链表*/  {   CNODE*head;   CNODE*tail;  }List;  /*******************************************************/  STATUS RemoveNode(List*pList,CNODE*pNode)/*从链表删除节点*/  {&lt;dp n="d5"/&gt;   if(Verify(pNode)!=OK)   return ERROR;   else   {   if(pNode->prev==NULL)   pList->head=pNode->next;   else   pNode->preV->next=pNode->next;   if (pNode->next==NULL)   pList->tail=pNode->prev;   else   pNode->next->preV=pNode->prev;   }  }  /*******************************************************/</pre>这样,通过分离链表操作,可以完全保证链表操作的安全性和独立性。
图2介绍了基于带保护字连接部件的用户链表。用户在定义一个链表的节点结构时,不再需要定义“next”之类的指针,取而代之的是一个带保护字的连接部件;操作链表时,也不再需要自己实现具体的操作,而是直接使用链表库提供的操作函数。示例如下<pre listing-type="program-listing">  /*******************************************************/  typedef struct/*定义用户链表*/  {  int Mydata;  CNODE Connect;&lt;dp n="d6"/&gt;   char Name[10];  }MyStruct;  /*******************************************************/  /*从用户链表删除节点*/  STATUS MyRemoveNode(List *myList,MyStruct *myNode)  {  return(RemoveNode(myList,&amp;amp;(myNode->Connect)));  }  /*******************************************************/</pre>上面的示例中,连接部件被定义到了用户结构的中部而非用户结构的第一个成员,这种情况下,链表库的某些函数(比如获得链表的第一个节点)返回的可能是一个指向连接部件的指针,而用户需要获得指向用户结构的指针。
如图3所示,为解决这个问题,我们定义了这样一个宏(定义宏的优点是无需理会字节对齐之类的问题)#define OFFSET(structure,member)\((int)&amp;(((structure*)0)-&gt;member))通过OFFSET宏可以获得结构中一个成员的偏移量,由此可以得到如下公式结构地址=成员地址-OFFSET(结构,成员)具体地,对于上面的MyStruct结构,如果已通过某一函数获得Connect成员的地址CNODE pNode=GetNode(myList);则有如下关系#define ULONG(unsigned int)myNode=(MyStruct*)((ULONG)pNode-OFFSET(MyStruct,Connect));
图4介绍了带保护字的内存块。这种结构适合于用户通过malloc获得一块内存,为避免用户写越界,在其前后均加上了保护字,与图1a介绍的带保护字连接部件类似,保护字被赋上特殊的值,便于验证其有效性。可以在用户调用free释放此内存时进行单个验证,也可使用一个低优先级任务在系统空闲时逐一验证,验证不通过则抛出一个异常,产生告警。
图5介绍了在有MMU支持的情况下带保护页的内存块。与图4类似,内存块的首尾均有保护,区别在于保护字换成了保护页。保护页的属性被设置为不可写,当用户写越界时,将由CPU抛出一个“Page Fault”异常。页保护方式的实时性很高,可能成为有MMU时常用的内存保护方法。
上述内容就是本方法的核心部分,具体细节不再赘述。由上述核心方法所派生的其他具体应用,都在本发明专利的保护之列。
权利要求
1.一种嵌入式实时操作系统高效可靠的内存保护方法,设置若干内存块,供不同应用程序和不同进程调用或共享;其特征在于在被启用内存连接部件的边缘设立至少一个保护标志。
2.根据权利要求1所述的内存保护方法,其特征在于实现以所述连接部件为节点的链表基础库;所述应用程序和实时操作系统(RTOS)其它程序在节点结构的声明中用连接部件代替指针,并且所有涉及链表的操作均使用所述链表基础库。
3.根据权利要求2所述的内存保护方法,其特征在于该内存保护方法还包括以下步骤1)所述应用程序和RTOS其它程序申请内存块及创建堆栈时,在所述内存块首、尾分别附上所述保护字;2)每次对一个内存数据块进行操作之前,验证每一个保护字是否是原始值;验证不通过则抛出一个异常信息,等待处理;通过则继续操作。
4.根据权利要求3所述的内存保护方法,其特征在于所述保护字被赋予一个特殊的值;所述验证可以在用户调用free释放此内存时进行单个验证,也可使用一个低优先级任务在系统空闲时逐一验证。
5.根据权利要求1所述的内存保护方法,其特征在于所述保护标志是MMU(存储管理单元)可操作的保护页。
6.根据权利要求5所述的内存保护方法,其特征在于所述保护页分别加在应用程序申请的内存块或堆栈的首尾部分;所述保护页的大小为4K。
7.根据权利要求6所述的内存保护方法,其特征在于所述保护页被映射到无效的物理地址。
全文摘要
一种嵌入式实时操作系统高效可靠的内存保护方法,设置若干内存块,供不同应用程序和不同进程调用或共享;尤其是在被启用内存连接部件的边缘设立至少一个保护标志。本方法由于采取了“保护字和/或保护页”的技术措施,在有无MMU的情况下均实现了对堆栈、核心数据以及各种用户数据结构实施单独的、细粒度的有效保护,从而极大的提高了RTOS的安全性、稳定性和可靠性,适用范围广、可靠性高、实时性强。
文档编号G06F12/16GK1567254SQ0313195
公开日2005年1月19日 申请日期2003年6月17日 优先权日2003年6月17日
发明者危才华, 王陈, 徐立锋, 张华强, 鲁旭 申请人:深圳市中兴通讯股份有限公司南京分公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1