- 论坛徽章:
- 0
|
首先我在linux内核上还是个新手,还请大家多帮助。
在linux内核中,用户进程之间和用户与内核之间存在内存保护,内核之内各模块(通常意义上的模块,不特指可装载模块)间是没有保护的,这是因为内核对于简洁和效率的要求所决定的。但随着linux在各种嵌入式系统上的广泛应用,传统的嵌入式系统中各任务运行在内核态,并共享内存空间,linux使用内核线程来移植会比较容易,这样内核会有大量的任务运行,产生内存问题的可能性会越
来越高。在vxworks 6.0以后,就提供了进程间内存保护的特性。在linux上为了解决这个问题,我想了一种内核的内存保护方案,作为调试选项来实现。
基本来说,就是为内存分配模块ID,只有本模块的代码可以访问本模块内存,避免其他模块的意外访问。为实现这个目标,最简单的想法是进入模块时,将它的内存的页表设置present标志,离开模块前再清除present标志,但在SMP下,页表是被各CPU共享的,虽然也可以使用多内核页表,各CPU使用自己的内核页表,但修改比较复杂,并且不利于移植到其它没有硬件页表的架构上。我的办法是页表中始终清除present标志,各CPU通过自己的TLB来访问内存。在分配内存时保存一个地址-模块表,记录该页所属的模块ID,将页表项清除present标志,在缺页异常中查找地址-模块表,如果属于当前模块ID,暂时设置present标志,然后装入TLB,然后马上再清除present标志,但这次不刷新TLB,让这个页表项保留在TLB中,虽然会有个窗口时间,但这也是难以避免的。
因为内存保护只是部分模块需要,很多内存是必须要被共享访问的,所以必须可以同时使用不保护方式,这样就要为分配私有内存单独提供一套接口,这个接口应该尽可能的简单,并且在调试选项关
闭时变为原来的接口。可以有两种方法,一种是为每个alloc_pages、kmalloc这样的接口提供另一套alloc_pages_p、kmalloc_p,在调试选项关闭时定义宏为alloc_pages、kmalloc,这个方法需要增加很多函数接口,另一种是我现在使用的,使用原来的函数接口,增加一些标志位,在调试选项关闭时将标志位定义为0。这其中kmap_high和vmalloc的输入参数中没有flag,可以使用page的最低位和size的最高位来传递,正常情况下它们是不会被使用的。
我现在只是修改了最基本的__alloc_pages_internal、__free_pages两个接口,以分配页为基础,可以很容易的修改slab和vmalloc,中断处理我只修改了smp_apic_timer_interrupt和do_IRQ,其它中断大概也没太大需要修改。这个patch是基于2.6.27版本的,没考虑PAE和64位,仅仅是个概念性的东西。
刚才我在linux内核列表上贴了这个PATCH,真奇怪那里PATCH不能贴为附件。以前在论坛上发过一部分,这次算是比较全的。
[ 本帖最后由 bjhpf 于 2008-11-2 22:35 编辑 ] |
|