以非特权模式运行用户代码
使用MPU时,以特权模式运行应用代码。这意味着应用程序代码将能够更改MPU设置,并破坏使用MPU的目的。以特权模式运行应用可能更容易地迁移应用代码。在某些时候,大多数应用程序代码将需要在非特权模式下运行,用户需要添加SVC处理程序。
ISR具有完全访问权限
当识别到中断并且启动ISR时,处理器将切换到特权模式。由于MPU控制寄存器的PRIVDEFENA为1,因此ISR可以访问所有I/O内存。
此外,ISR应该尽可能短,并简单地发信号给任务,由任务执行中断设备所需的大部分工作。当然,这假设ISR是内核感知的ISR,并且该中断设备有相当多的工作处理。例如,不应在ISR中上处理以太网数据包。然而,闪烁LED或更新脉冲宽度调制(PWM)计时器的占空比可以直接在ISR中完成。
防止在RAM中执行代码
大多数MPU可以防止从RAM执行代码,从而限制代码注入攻击。防止外设执行代码可能看起来很奇怪,但可以防止想方设法进入系统的黑客。
限制进程对外设的访问
应该留出一个或多个MPU区域,以限制进程只能访问自己的外设。换言之,如果一个进程管理USB端口,那么它应该只能访问USB外设或与USB控制器的需求相关的外设,例如DMA。
可用的RTOS API
设计者必须确定应用代码可使用哪些RTOS API。例如,是否禁止应用代码在系统初始化后创建和删除任务或RTOS对象?换言之,RTOS对象是否只能系统启动时创建,而非运行时创建?
如果是,SVC处理程序查找表应只包含向应用公开的API。即使ISR在特权模式下运行,可以访问所有的RTOS API,一个好的RTOS也会阻止从ISR中创建和删除RTOS对象。
在RTOS空间中分配RTOS对象
任务堆栈位于进程空间内,但是,RTOS对象(信号量、队列、任务控制块等)应在内核空间中分配,并通过引用进行访问。不应在进程空间中分配RTOS对象,因为这意味着应用代码可以不调用RTOS API,即可有意或意外地修改内核对象。
保护对代码的访问
虽然MPU区域通常用于提供或限制对RAM和外设的访问,但如果有空闲区域,并且能够通过进程组织代码,那么限制对代码的访问非常有用,可以防止某些类型的安全攻击,如Return-to-libc攻击。
减少进程间的通信
正如设计时,尽可能保持任务独立一样,进程也应该遵循同样的规则。因此,进程间应尽量不交互,或者将进程间通信保持在限度。如果必须与其它进程通信,只需留出一个包含Out和In缓冲区的共享区域。
发送者将其数据放入Out缓冲区中,然后触发一个中断来唤醒接收进程。一旦数据被处理,响应可以放在发送者的In缓冲区中,并且可以使用中断来通知发送进程。
确定出现MPU故障时应如何操作
理想情况下,在开发过程中检测并纠正所有MPU故障。你还需考虑由于意外故障或错误或系统受到安全攻击而出现的故障处理。在大多数情况下,建议对每个任务或每个进程设置一个可控的关机顺序。是否重新启动违规任务、进程内或整个系统内的所有任务都取决于故障的严重程度。
记录和报告故障
理想情况下,系统应该能够记录(可能是文件系统)并显示故障原因,以便开发人员解决问题。
大多数RTOS在特权模式下运行应用代码,使得应用程序完全控制CPU及其资源。所有任务和ISR都可以不受限制地访问内存和外设。这意味着应用程序代码可能会意外或故意损坏其他任务的堆栈或变量。通过MPU机制,可以限制应用代码的访问权限,极大提供应用的功能安全。