具体实施方式
下面将参照附图更详细地描述本公开的示例性实施方式。虽然附图中显示了本公开的示例性实施方式,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施方式所限制。相反,提供这些实施方式是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
需要注意的是,除非另有说明,本申请使用的技术术语或者科学术语应当为本申请所属领域技术人员所理解的通常意义。
另外,术语“第一”和“第二”等是用于区别不同对象,而不是用于描述特定顺序。此外,术语“包括”和“具有”以及它们任何变形,意图在于覆盖不排他的包含。例如包含了一系列步骤或单元的过程、方法、系统、产品或设备没有限定于已列出的步骤或单元,而是可选地还包括没有列出的步骤或单元,或可选地还包括对于这些过程、方法、产品或设备固有的其它步骤或单元。
为了便于理解本申请,首先对内存保护单元介绍如下:
由于成本和性能等原因,大多嵌入式CPU都没有MMU(Memory Management Unit,内存管理单元),但一般嵌入式CPU会提供一个内存保护单元,如ARM架构上会提供一个MPU(Memory Protect Unit,内存保护单元)实现内存的保护,同样在RISC-V架构处理器上,为每个CPU核心提供了一个物理内存保护(PMP,Physical Memory Protection)功能,以提供在各种模式下的内存保护。通过配置内存保护单元,可以为指定大小的内存区域设置访问权限,如读、写、执行。下面分别介绍MPU和PMP。
ARM架构对于没有MMU的CPU可以选配一个内存保护单元MPU,通过MPU可以对内存地址空间的访问权限进行设置,实现地址空间的访问控制。MPU通过将内存空间划分为多个“region”进行权限设置。一个region就是一段连续的地址空间,一般MPU支持设置8~16个regions。同时还可以启用一个“背景region”,用于配置地址空间的默认访问权限,启用背景region后,特权模式默认可以访问所有地址空间,非特权模式默认无法访问地址空间。在启用MPU后,就无法访问定义之外的地址区间,也不得访问未经授权的region。否则,将会触发内存访问错误。
通过设置MPU相关寄存器来配置内存地址空间的访问权限,下面对本发明主要用到的寄存器配置方法进行介绍,包括如下寄存器:
1) MPU类型寄存器MPUTR
通过读取类型寄存器MPUTR,可以获取MPU的一些系统信息,MPUTR各字段如下:
IREGION字段:MPU支持的指令region数量;
DREGION字段:MPU支持的数量。若系统中配了MPU则为8,否则为零;
SEPARATE字段:固定为0;
2) MPU控制寄存器MPUCR
PRIVDEFENA字段:设置MPU是否启用背景region。字段为1时启用背景region,为0时不启用背景region;
HFNMIENA字段:用于设置在不可屏蔽中断和硬件错误时是否强制除能MPU,字段为1时在发生不可屏蔽中断和硬件错误时不强制除能MPU,字段为0时在发生不可屏蔽中断和硬件错误时强制除能MPU;
ENABLE字段:ENABLE为0时除能MPU,ENABLE为1时使能MPU;
3) MPU region基址寄存器MPURBAR和region属性及容量寄存器MPURASR,MPURBAR和MPURASR共同配置一个region的访问权限,MPURBAR和MPURASR各字段如下:
在MPURBAR中:
ADDR字段:ADDR字段用于设置一个region的起始地址;
ALID和REGION字段:VALID和REGION字段用于指定一个region,当VALID为1时,REGION字段的值为设置的region号。
在MPURASR中,各字段用于设置region的具体权限:
XN字段:用于设置该region是否允许取指操作,XN=0则该region不允许取指,NX=1则允许取指操作;
AP字段:用于设置该region在特权模式和非特权模式下的读、写权限,几种常用的设置为:AP=001,特权模式可读写,非特权模式不允许访问;AP=010,特权模式可读写,非特权模式只读,AP=011,特权模式和非特权模式均可读写;AP=101,特权模式为只读,用户模式不允许访问;AP=110或111,特权模式和用户模式均为只读;
TEX字段:扩展字段,本发明未使用扩展功能,TEX字段为0;
S字段:用于设置该region是否允许共享,S=0,不共享;S=1,可以共享;C字段:用于设置该region是否允许缓存,C=0,不缓存;C=1,可以缓存;B字段:用于设置该region是否允许缓冲,B=0,不缓冲;S=1,可以缓冲;
SRD字段:子region除能字段。每个容量大于128字节的region还可以进一步划分为8个子region,SRD字段每设置一个位,就会除能与之对应的一个子region;
REGIONSIZE字段:设置region容量大小;
SZENABLE字段:SZENABLE为0时除能此region,SZENABLE为1时使能此region。
类似的,RISC-V架构提供PMP对内存地址空间的访问权限进行设置,实现地址空间的访问控制。PMP通过两类寄存器进行配置:配置寄存器和地址寄存器,一个配置寄存器(pmpcfg)和一个地址寄存器(pmpaddr)组成一个PMP入口(PMP entry),一般PMP提供8或16组PMP入口供使用者配置使用,其中pmp[i]cfg、pmpaddr[i]表示第i组PMP入口的配置寄存器和地址寄存器。这里配置寄存器pmp[i]cfg的长度为8位,无论是对于RV32还是RV64,都不会存在一个只有8位(一个字节大小)的寄存器。故实际的实现上,是把几个控制寄存器组合到一个寄存器中;
通过设置的每组PMP entry,可以具体配置一块内存区域的访问权限,PMP配置寄存器各字段说明如下:
R、W、X字段:分别对应内存的读、写、执行权限,相应字段为1时拥有该权限,0时无权限。
A字段:A字段地址匹配字段,当A=0时,该PMP条目处于未启用状态,不匹配任何地址,当A不等于零的时候,分为三种地址匹配模式:TOR(01), NA4(10), NAPOT(11),该字段配合地址寄存器,可以设置指定大小的内存区域。
L字段:L字段表示PMP 入口处于锁定状态,此时对于配置寄存器和对应的地址寄存器的写入会被忽略。被锁定的PMPentry在设备重置之前都将保持锁定。当L字段为1时,M、U模式都必须遵循配置寄存器的权限设置(是否读、写、执行权限)。而当L字段为0时,在M模式下匹配到此PMP entry的任何操作都将成功,而U模式需要遵循配置寄存器中的权限设置。
本申请实施例提供一种操作系统中进程地址空间隔离保护方法及装置、一种物联网设备,下面结合附图进行说明。
请参考图1,其示出了本申请的一些实施方式所提供的一种操作系统中进程地址空间隔离保护装置的示意图,如图所示,该隔离保护装置10包括:记录模块100和配置模块200。其中,
记录模块100,用于预先构建地址空间保护表,所述地址空间保护表中保存有当前操作系统中所有进程的可访问内存地址空间和访问权限;
所述地址空间保护表中的每一行为一个进程地址空间保护记录,所述进程地址空间保护记录包括进程标识、预设数量的地址空间保护条目、及所述地址空间保护条目的已配置数量;一个地址空间保护条目用于设置一块内存地址空间的访问权限。
具体的,地址空间保护SYSTEM_ADDR_Table表共有4列,第一列是进程标识PROCESS_ID,用来标识操作系统中的一个进程,第二列是PROCESS_ADDR_Count,用于记录一个进程当前已使用的内存条目数(地址空间保护条目的已配置数量),初始值为0,第三列和第四列分别是长度为N的进程地址空间配置数组PROCESS_ ADDR _Cfg [N]和进程地址空间数组PROCESS_Address[N]。N的大小取决于具体芯片的实现。SYSTEM_ADDR_Table表中的每一行称为一个进程地址空间保护记录,其中PROCESS_ADDR_Cfg中的每一个元素与PROCESS_Address中对应的元素组成一个地址空间保护条目,如PROCESS_ADDR_Cfg[0]和PROCESS_Address[0]就组成一个地址空间保护条目。
配置模块200,用于根据所述地址空间保护表配置处理器的内存保护单元,以对操作系统中进程地址空间进行隔离保护。
如图2所示,所述配置模块200可以包括加载单元210、设置单元220;
加载单元210,用于接收目标进程加载指令,所述目标进程加载指令中包括目标进程的进程标识;根据所述进程标识,从所述地址空间保护表中读取对应进程的全部已配置的地址空间保护条目来重新配置所述内存保护单元。
具体的,加载单元210根据传入的PROCESS_ID,从记录模块100的SYSTEM_ADDR_Table表读取对应进程的PROCESS_ADDR_Cfg和PROCESS_Address两个数组,并根据PROCESS_ADDR_Cfg、PROCESS_Address两个数组的全部配置信息,重新设置内存保护单元。
设置单元220,用于接收目标进程设置指令,所述目标进程设置指令中包括目标进程的进程标识、新增或删除的目标地址空间保护条目;根据所述进程标识,将所述地址空间保护表中新增或删除的目标地址空间保护条目更新至所述内存保护单元。
具体的,设置单元220根据进程某一条地址空间保护条目的新增或删除,对内存保护单元进行相应设置,如进程新增了一条地址空间保护条目,则调用设置单元,将新增的内存空间保护条目配置信息更新至内存保护单元中,使其生效,如果进程删除了一条地址空间保护条目,调用设置单元,将相应的保护条目从内存保护单元中清除。
如图2所示,所述配置模块200还可以包括初始化单元230、更新单元240、删除单元250、销毁单元260。
初始化单元230,用于接收目标进程初始化指令,所述目标进程初始化指令中包括目标进程的进程标识;根据所述进程标识,在所述地址空间保护表中为目标进程创建一个进程地址空间保护记录,并从预设数量的地址空间保护条目中分配一条地址空间保护条目,用于配置目标进程的默认访问权限。
具体的,初始化单元230根据传入的进程ID,在SYSTEM_ADDR_Table表中为该进程创建一个进程地址空间保护记录,并从PROCESS_ADDR_Cfg和PROCESS_Address数组中分配一条地址空间保护条目,用于配置进程的默认访问权限,默认访问权限的配置原则为:内核进程允许访问所有地址空间,用户进程只允许访问自己的地址空间。
更新单元240,用于接收目标进程更新指令,所述目标进程更新指令中包括目标进程的进程标识、内存地址空间信息和权限信息;根据所述进程标识,在所述地址空间保护表中找到目标进程的进程地址空间保护记录,判断该进程地址空间保护记录中地址空间保护条目的已配置数量是否已达到预设数量;若未达到预设数量,则继续配置,配置完成后令所述已配置数量加1;若已达到预设数量,则结束配置。
具体的,更新单元240根据传入的进程ID、内存地址空间信息和权限信息,在SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,根据记录中PROCESS_ADDR_Count字段的值判断该进程的地址空间保护条目数量是否已达到最大值,若未达到最大值,则可以继续配置,并在进程地址空间保护记录的配置数组和地址数组寻找一组未使用的地址空间保护条目,用于配置这个进程对于这块内存地址空间的访问权限,配置完成后令PROCESS_ADDR_Count加1;若已达到最大值,则返回该进程地址空间保护条目可配置数量已满。
删除单元250,用于接收目标进程删除指令,所述目标进程删除指令中包括目标进程的进程标识和待删除的内存地址空间信息;根据所述进程标识,在所述地址空间保护表中找到目标进程的进程地址空间保护记录,从该进程地址空间保护记录中找到并清零待删除的内存地址空间信息对应的地址空间保护条目,同时该进程地址空间保护记录中地址空间保护条目的已配置数量减1。
具体的,删除单元250根据进程ID、内存地址空间信息,在系统地址空间保护表中找到该进程的地址空间保护记录,从进程地址空间配置数组和进程地址空间数组中找到这块内存地址空间对应的保护条目,并将该保护条目清零,同时PROCESS_ADDR_Count值减1。
销毁单元260,用于接收目标进程销毁指令,所述目标进程销毁指令中包括目标进程的进程标识;根据所述进程标识,在所述地址空间保护表中找到并删除目标进程的进程地址空间保护记录。
具体的,销毁单元根据传入的进程ID,在SYSTEM_ADDR_Table表中找到该进程相关的地址空间保护记录并删除。
本申请提的上述隔离防护装置基于内存保护单元,限制每个用户进程在运行过程中只能访问被授予访问权限的内存区域,保证用户进程无法破坏操作系统或者其它任务进程。
下面通过更具体的实施例对本申请进行进一步地介绍。
实施例一
本实施例基于勘智K210上实现,勘智K210是基于RISC-V64位架构的芯片,并为每个CPU核心实现了内存保护单元PMP。
图3为本申请实施例一的装置模块示意图,其中记录模块100中的SYSTEM_ADDR_Table表包括PROCESS_ID、PROCESS_ADDR_Count、PROCESS_ ADDR _Cfg [N]及PROCESS_Address[N],PROCESS_ ADDR _Cfg和PROCESS_Address组成保护条目与PMPentry一一对应,如PROCESS_ADDR_Cfg[0]与PROCESS_Address[0]组成的保护条目与MPUentry0对应,依此类推。其中配置数组和地址数组长度N为16,配置数组每个元素为8位,地址数组每个元素为64位。其中PROCESS_Address[0] ~ PROCESS_Address[15]与PMP地址寄存器pmpaddr[0]~pmpaddr[15]一一映射。而PROCESS_ADDR_Cfg[0]~ PROCESS_ADDR_Cfg[7]映射到pmpcfg[0]上,PROCESS_ADDR_Cfg[8]~ PROCESS_ADDR_Cfg[15]映射到pmpcfg[2]上,映射关系如图4所示。
加载单元210将根据进程的全部地址空间保护条目对PMP进行设置。设置单元220根据进程某一条地址空间保护条目对PMPentry配置进行更新。
下面结合操作系统与隔离保护装置10分5个方面具体阐述如下:
方面A,操作系统在创建进程时,操作系统内存管理单元在为进程分配内存空间后,调用初始化单元和更新单元,对进程的地址空间权限进行配置。具体步骤描述如下:
步骤A1,初始化单元根据传入的进程ID,在系统地址空间保护表中查找该进程ID,如果找到,则将该进程ID对应的记录清空,若没找到,则在系统地址空间保护表中为该进程新建一条记录。
步骤A2,进程地址空间保护记录创建好后,配置进程对于整个内存区域的默认访问权限。分配PROCESS_ ADDR_Cfg数组和PROCESS_ Address数组的第16项,用于配置进程的默认访问权限,即PROCESS_ ADDR_Cfg[15]中的L字段为0,A字段为02,XWR字段为000,PROCESS_Address[15]配置为全部地址空间。表明运行在机器模式的内核进程可以访问整个内存地址空间,但运行在用户模式的用户进程默认无法访问内存地址空间。
步骤A3,完成进程的地址空间保护记录初始化后,内存管理单元会将进程的内存空间进一步细分为代码段空间、数据段空间、bss段空间、栈空间,并依次调用更新单元为每一个段空间创建一条地址空间保护条目并设置相应权限。进一步的,
步骤A31,配置进程代码段访问权限,分配第一条地址空间保护条目,即PROCESS_ADDR_Cfg[0],PROCESS_Address[0],PROCESS_ADDR_Cfg[0]配置如下:L=0,A=02,XWR=101,PROCESS_Address[0]= 代码段地址空间,配置完成后PROCESS_ADDR_Count加1;
步骤A32,配置进程数据段访问权限,分配第二条地址空间保护条目,即PROCESS_ADDR_Cfg[1],PROCESS_Address[1],PROCESS_ADDR_Cfg[1]配置如下:L=0,A=02,XWR=001,PROCESS_ Address[1]=数据段地址空间;
步骤A33,配置进程bss段和栈空间访问权限,分配第三条地址空间保护条目,即PROCESS_ ADDR_Cfg[2],PROCESS_Address[2],PROCESS_ ADDR_Cfg[2]配置如下:L=0,A=02,XWR=111,PROCESS_ Address[2]=bss段加栈空间地址空间。
方面B,在多任务的操作系统中,每一个CPU上都会发生频繁的进程切换,当某一个CPU发生进程切换时,需要配置新进程可访问的内存空间及权限,操作系统调用加载单元,加载单元根据进程地址空间配置数组和地址数组中的值设置各个PMP entry,具体步骤如下:
步骤B1:判断地址空间配置数组PROCESS_ADDR_Cfg[0]和地址空间数组PROCESS_Address[0]的值是否为0,若不为0,则将PROCESS_ADDR_Cfg[0]和PROCESS_Address[0]的值分别加载到PMP配置寄存器pmpcfg[0]和PMP地址寄存器pmpaddr[0]中,用于配置PMP entry[0]的访问权限,若为0则跳过;
步骤B2:判断地址空间配置数组PROCESS_ADDR_Cfg[1]和地址空间数组PROCESS_Address[1]的值是否为0,若不为0,则将PROCESS_ADDR_Cfg [1]和PROCESS_Address [1]的值分别加载到PMP配置寄存器pmpcfg[1]和PMP地址寄存器pmpaddr[1]中,用于配置PMPentry[1]的访问权限,若为0则跳过;
步骤B3:以此类推,根据PROCESS_ADDR_Cfg和PROCESS_Address剩余元素,设置其它PMPentry访问权限;
方面C,进程在运行过程中,可能会动态的向操作系统申请和释放内存空间。当操作系统收到进程的内存申请/释放请求时,除了为进程分配和回收内存资源,相应的还需要能够动态的配置进程的地址空间保护记录。从两个方面进行描述,
方面C1,进程在运行过程中,向操作系统申请内存空间,如malloc()函数,操作系统接收到进程申请内存请求时,操作系统从空闲的内存块中为进程分配指定大小的内存区域,并将进程ID、此内存区域的地址信息和权限信息传给更新单元,更新单元根据传入的信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,判断PROCESS_ADDR_Count的值是否小于15,如果不是,则返回更新失败。如果小于15,则从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到一条未使用(数值全为0)的条目,假设为第X条条目,设置其PROCESS_ADDR_Cfg[X]配置为L=0,A=02,XWR=111,PROCESS_Address[X]=新分配的地址空间。设置完后将PROCESS_ADDR_Count值加1。
如果进程地址空间保护记录更新成功,操作系统调用设置单元,根据进程更新后的地址空间保护记录设置PMP配置寄存器pmpcfg[X]和PMP地址寄存器pmpaddr[X],用于设置PMPentry[X]。若进程地址空间保护记录更新失败,则通知进程内存申请失败。
方面C2,进程申请的内存使用完毕后,向操作系统申请释放内存空间,如free()函数,操作系统接收到进程释放内存请求时,操作系统调用删除单元,删除单元根据传入的进程ID和内存地址信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,并从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到这块内存区域对应的地址空间保护条目,假设为第X条条目,将这条条目清空。清空成功后,操作系统调用设置单元,根据进程更新后的地址空间保护记录设置PMP配置寄存器pmpcfg[X]和PMP地址寄存器pmpaddr[X],将该条PMPentry[X]清空。
方面D,进程在运行过程中,需要与其它进程进行内存共享,操作系统需要为进程创建一块内存区域用于共享,并为需要内存共享的进程设置访问权限。
进一步的,方面D包含以下步骤:
步骤D1:当进程向内核申请一块内存区域用于内存共享,如进程调用shmget()函数,操作系统会分配一块内存区域用于内存共享,并调用更新单元,更新单元根据传入的信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,判断PROCESS_ADDR_Count的值是否小于15,如果不是,则返回更新失败。如果小于15,则从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到一条未使用(数值全为0)的条目,假设为第X条条目,根据共享内存区域的权限,如果该进程对共享区域只有只读权限,则其PROCESS_ADDR_Cfg[X]配置为L=0,A=02,XWR=001,PROCESS_Address[X]=共享内存地址空间。设置完后将PROCESS_ADDR_Count值加1。
如果进程地址空间保护记录更新成功,操作系统调用设置单元,根据进程更新后的地址空间保护记录设置PMP配置寄存器pmpcfg[X]和PMP地址寄存器pmpaddr[X],用于设置PMPentry[X]。若进程地址空间保护记录更新失败,则通知进程内存申请失败。
步骤D2:当某一个进程需要访问共享内存区域时,该进程向操作系统发出申请,如调用shmat()函数,类似的,操作系统根据这块共享内存区域的内存的地址信息和权限调用更新单元,为该进程新增这块内存区域的地址空间保护条目,并调用设置单元根据更新后的地址空间保护记录对PMP进行配置,允许该进程访问共享内存区域。
步骤D3:当某一个进程向内核申请断开共享内存的访问时,操作系统根据这块共享内存区域的内存的地址信息和权限调删除单元,从该进程地址空间保护记录中清空这块内存区域的地址空间保护条目,并调用设置单元,根据清空的地址空间保护记录,将对应的PMPentry清空,回收该进程对这块内存区域的访问权限。
步骤D4:当进程向内核申请释放共享内存区域时,操作系统检查该内存区域是否还有进程连接这块内存区域,如果没有,则回收这块内存区域;否则等待所有进程都断开连接时再回收。
方面E,当某个进程结束时,操作系统调用销毁模块,销毁模块根据传入的进程ID,在SYSTEM_ADDR_Table表中查找该进程的相关地址空间保护记录,如果找到,则将其从SYSTEM_ADDR_Table中删除。
实施例二
STM32F4Discovery是基于ARM 32位架构的开发板,STM32F4Discovery上实现了内存保护单元MPU(Memory Protection Unit),图5为本发明实施例二的装置模块示意图。如图2所示,本发明提供的隔离保护装置10可以非常容易的集成到STM32系列的嵌入式系统中。
第一模块中,包括系统地址空间保护表单元,记录模块100中的SYSTEM_ADDR_Table表中包含每个进程的内存地址空间配置数组和地址数组,配置数组和地址数组长度N为8,对应MPU的8个region配置信息,进程每一条保护条目与MPU的一个region一一对应,如PROCESS_ADDR_Cfg[0]与PROCESS_Address[0]组成的保护条目与MPUregion[0]对应,依此类推。配置数组每个元素为32位,每个元素各字段对应MPUregion属性及容量寄存器MPURASR,地址数组每个元素为32位,每个元素各字段对应MPUregion基址寄存器MPURBAR。
加载单元将根据进程的全部地址空间保护条目对MPU的全部配置进行更新。设置单元根据进程某一条地址空间保护条目对MPU配置进行更新。
下面结合操作系统与隔离保护装置10分5个方面具体阐述如下:
方面A,操作系统在创建进程时,操作系统内存管理单元在为进程分配内存空间后,调用初始化单元和更新单元,对进程的地址空间权限进行配置。具体步骤描述如下:
步骤A1,初始化单元根据传入的进程ID,在系统地址空间保护表中查找该进程ID,如果找到,则将该进程ID对应的记录清空,若没找到,则在系统地址空间保护表中为该进程新建一条记录。
步骤A2,为进程创建好地址空间保护记录后,内存管理单元会将进程的内存空间进一步细分为代码段空间、数据段空间、bss段空间、栈空间,并依次调用更新单元为每一个段空间创建一条地址空间保护条目并设置相应权限。进一步的,
步骤A31,配置进程代码段访问权限,分配第一条地址空间保护条目,即PROCESS_ADDR_Cfg[0],PROCESS_Address[0],PROCESS_ ADDR_Cfg[0]中各字段配置如下:NX=0,AP=110,TEX=0,S=0,C=1,B=1,REGIONSIZE=代码段长度,SZENABLE=1,PROCESS_Address[0]中各字段配置如下,ADDR=代码段起始地址,VALID=1,REGION=0,配置完成后PROCESS_ADDR_Count加1;
步骤A32,配置进程数据段访问权限,分配第二条地址空间保护条目,PROCESS_ADDR_Cfg[1]中各字段配置如下:NX=1,AP=011,TEX=0,S=0,C=1,B=1,REGIONSIZE=代码段长度,SZENABLE=1,PROCESS_Address[1]中各字段配置如下,ADDR=代码段起始地址,VALID=1,REGION=1,配置完成后PROCESS_ADDR_Count加1;
步骤A33,配置进程bss段和栈空间访问权限,分配第三条地址空间保护条目,即PROCESS_ ADDR_Cfg[2]中各字段配置如下:NX=0,AP=011,TEX=0,S=0,C=1,B=1,REGIONSIZE=代码段长度,SZENABLE=1,PROCESS_Address[2]中各字段配置如下,ADDR=代码段起始地址,VALID=1,REGION=2,配置完成后PROCESS_ADDR_Count加1。
方面B,在多任务的操作系统中,每一个CPU上都会发生频繁的进程切换,当某一个CPU发生进程切换时,需要配置新进程可访问的内存空间及权限,操作系统调用加载单元,将该进程的地址空间保护记录中PROCESS_ADDR_Cfg和PROCESS_Address配置信息对MPU进行配置,具体步骤如下:
步骤B1:加载单元读取MPU类型寄存器MPUTR中的DREGION字段,判断设备是否存在MPU,如果DREGION字段值为8,则设备存在MPU,转到步骤二继续配置,若DREGION字段值为0,则设备不存在MPU,直接返回错误原因;
步骤B2:设置MPU控制寄存器MPUCR中的ENABLE字段值为0,对MPU进行除能操作;转到步骤B3;
步骤B3:加载单元根据进程地址空间配置数组和地址数组中的值设置MPU各个region,进一步的:
步骤B31:判断地址空间配置数组PROCESS_ADDR_Cfg[0]和地址空间数组PROCESS_Address[0]的值是否为0,若不为0,则将PROCESS_Address[0]和PROCESS_ADDR_Cfg[0]的值分别加载到MPURegion 基址寄存器和Region 属性及容量寄存器,用于配置region[0]的访问权限,若为0则跳过;
步骤B32:判断地址空间配置数组PROCESS_ADDR_Cfg[1]和地址空间数组PROCESS_Address[1]的值是否为0,若不为0,则将PROCESS_Address[1]和PROCESS_ADDR_Cfg[1]的值分别加载到MPURegion 基址寄存器和Region 属性及容量寄存器,用于配置region[1]的访问权限,若为0则跳过;
步骤B33:依次根据PROCESS_ADDR_Cfg和PROCESS_Address剩余元素,设置其它region访问权限;
步骤B4:建立好各个region后,加载单元将设置MPU控制寄存器MPUCR的字段PRIVDEFENA=1和字段ENABLE=1,用于打开MPU背景region和使能MPU,完成MPU的配置。
方面C,进程在运行过程中,可能会动态的向操作系统申请和释放内存空间。当操作系统收到进程的内存申请/释放请求时,除了为进程分配和回收内存资源,相应的还需要能够动态的配置进程的地址空间保护记录。包括两个方面进行描述,
方面C1,进程在运行过程中,向操作系统申请内存空间,如malloc()函数,操作系统接收到进程申请内存请求时,操作系统从空闲的内存块中为进行分配指定大小的内存区域,并将进程ID、此内存区域的地址信息和权限信息传给更新单元,更新单元根据传入的信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,判断PROCESS_ADDR_Count的值是否小于8,如果不是,则返回更新失败。如果小于8,则从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到一条未使用(数值全为0)的条目,假设为第X条条目,设置其PROCESS_ADDR_Cfg[X]配置为NX=0,AP=011,TEX=0,S=0,C=1,B=1,REGIONSIZE=内存空间长度,SZENABLE=1,PROCESS_Address[X]中各字段配置如下,ADDR=内存空间起始地址,VALID=1,REGION=X。设置完后将PROCESS_ADDR_Count值加1。
如果进程地址空间保护记录更新成功,操作系统调用设置单元,根据进程新增的地址空间保护记录对MPU进行设置。若进程地址空间保护记录更新失败,则通知进程内存申请失败。
方面C2,进程申请的内存使用完毕后,向操作系统申请释放内存空间,如free()函数,操作系统接收到进程释放内存请求时,操作系统调用删除单元,删除单元根据传入的进程ID和内存地址信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,并从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到这块内存区域对应的地址空间保护条目,假设为条目X,将这条条目对应的PROCESS_ADDR_Cfg[X]和PROCESS_Address[X]的值清零,然后操作系统调用设置单元,对regionx进行除能,即设置MPU region基址寄存器MPURBAR中VALID=1,REGION=X,MPU region属性及容量寄存器MPURASR中SZENABLE=0,除能此region。
方面D,进程在运行过程中,需要与其它进程进行内存共享,操作系统需要为进程创建一块内存区域用于共享,并为需要内存共享的进程设置访问权限。
进一步的,方面D包含以下步骤:
步骤D1:当进程向内核申请一块内存区域用于内存共享,如进程调用shmget()函数,操作系统会分配一块内存区域用于内存共享,并调用更新单元,更新单元根据传入的信息,从SYSTEM_ADDR_Table表中找到该进程的地址空间保护记录,判断PROCESS_ADDR_Count的值是否小于8,如果不是,则返回更新失败。如果小于8,则从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到一条未使用(数值全为0)的条目,假设为第X条条目,设置其PROCESS_ADDR_Cfg[X]配置为NX=1,AP=011,TEX=0,S=0,C=1,B=1,REGIONSIZE=内存空间长度,SZENABLE=1,PROCESS_Address[X]中各字段配置如下,ADDR=内存空间起始地址,VALID=1,REGION=X。设置完后将PROCESS_ADDR_Count值加1。
如果进程地址空间保护记录更新成功,操作系统调用设置单元,根据进程新增的地址空间保护记录对MPU进行设置。若进程地址空间保护记录更新失败,则通知进程内存申请失败。
步骤D2:当某一个进程需要访问共享内存区域时,该进程向操作系统发出申请,如调用shmat()函数,类似的,操作系统根据这块共享内存区域的内存的地址信息和权限调用更新单元,为该进程新增这块内存区域的地址空间保护条目,并调用设置单元,根据更新后的地址空间保护记录对MPU进行设置,允许该进程访问共享内存区域。
步骤D3:当某一个进程向内核申请断开共享内存的访问时,操作系统根据这块共享内存区域的内存的地址信息调删除单元,删除单元从PROCESS_ADDR_Cfg和PROCESS_Address数组中找到这块内存区域对应的地址空间保护条目,假设为条目X,将这条条目对应的PROCESS_ADDR_Cfg[X]和PROCESS_Address[X]的值清零,然后操作系统调用设置单元,对regionx进行除能,即设置MPU region基址寄存器MPURBAR中VALID=1,REGION=X,MPUregion属性及容量寄存器MPURASR中SZENABLE=0,除能此region。
步骤D4:当进程向内核申请释放共享内存区域时,操作系统检查该内存区域是否还有进程连接这块内存区域,如果没有,则回收这块内存区域;否则等待所有进程都断开连接时再回收。
方面E,当某个进程结束时,操作系统调用销毁模块,销毁模块根据传入的进程ID,在SYSTEM_ADDR_Table表中查找该进程的相关地址空间保护记录,如果找到,则将其从SYSTEM_ADDR_Table中删除。
本申请上述各实施例的操作系统中进程地址空间隔离保护装置面向物联网操作系统,在不影响应用程序运行的基础上,对每个用户程序所允许访问的内存地址空间进行限制,对于未授权的内存地址空间拒绝用户进程访问。并支持应用程序在运行过程中动态申请内存、释放内存、进行内存共享等。
在上述的实施例中,提供了一种操作系统中进程地址空间隔离保护装置,与之相对应的,本申请还提供一种操作系统中进程地址空间隔离保护方法。请参考图6,其示出了本申请的一些实施方式所提供的一种操作系统中进程地址空间隔离保护方法的示意图。由于方法实施例基本相似于装置实施例,所以描述得比较简单,相关之处参见装置实施例的部分说明即可。下述描述的装置实施例仅仅是示意性的。
如图6所示,操作系统中进程地址空间隔离保护方法可以包括:
步骤S101:预先构建地址空间保护表,所述地址空间保护表中保存有当前操作系统中所有进程的可访问内存地址空间和访问权限;
步骤S102:根据所述地址空间保护表配置处理器的内存保护单元,以对操作系统中进程地址空间进行隔离保护。
具体的,所述地址空间保护表中的每一行为一个进程地址空间保护记录,所述进程地址空间保护记录包括进程标识、预设数量的地址空间保护条目、及所述地址空间保护条目的已配置数量;一个地址空间保护条目用于设置一块内存地址空间的访问权限。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程加载指令,所述目标进程加载指令中包括目标进程的进程标识;根据所述进程标识,从所述地址空间保护表中读取对应进程的全部已配置的地址空间保护条目来重新配置所述内存保护单元。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程设置指令,所述目标进程设置指令中包括目标进程的进程标识、新增或删除的目标地址空间保护条目;根据所述进程标识,将所述地址空间保护表中新增或删除的目标地址空间保护条目更新至所述内存保护单元。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程初始化指令,所述目标进程初始化指令中包括目标进程的进程标识;根据所述进程标识,在所述地址空间保护表中为目标进程创建一个进程地址空间保护记录,并从预设数量的地址空间保护条目中分配一条地址空间保护条目,用于配置目标进程的默认访问权限。
所述默认访问权限的配置原则为:内核进程允许访问所有地址空间,用户进程只允许访问自己的地址空间。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程更新指令,所述目标进程更新指令中包括目标进程的进程标识、内存地址空间信息和权限信息;根据所述进程标识,在所述地址空间保护表中找到目标进程的进程地址空间保护记录,判断该进程地址空间保护记录中地址空间保护条目的已配置数量是否已达到预设数量;若未达到预设数量,则继续配置,配置完成后令所述已配置数量加1;若已达到预设数量,则结束配置。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程删除指令,所述目标进程删除指令中包括目标进程的进程标识和待删除的内存地址空间信息;根据所述进程标识,在所述地址空间保护表中找到目标进程的进程地址空间保护记录,从该进程地址空间保护记录中找到并清零待删除的内存地址空间信息对应的地址空间保护条目,同时该进程地址空间保护记录中地址空间保护条目的已配置数量减1。
根据本申请的一些实施方式中,所述步骤S102包括:
接收目标进程销毁指令,所述目标进程销毁指令中包括目标进程的进程标识;根据所述进程标识,在所述地址空间保护表中找到并删除目标进程的进程地址空间保护记录。
本申请实施例提供的操作系统中进程地址空间隔离保护方法,与本申请前述实施例提供的操作系统中进程地址空间隔离保护装置出于相同的发明构思,具有相同的有益效果。
本申请实施方式还提供一种物联网设备,该物联网设备包括前述实施方式所提供的操作系统中进程地址空间隔离保护装置。
最后应说明的是:以上各实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述各实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的范围,其均应涵盖在本申请的权利要求和说明书的范围当中。