楼主估计也像我这种非计算机科班出生的半路程序员,以前刚接触的单片机是51,其次是ARM7,程序所运行的地址和实际总线上的地址完全一样,都是实地址。第一次接触MMU很晕,这种内存管理对于简单的系统是足够的,因为简单,容易理解,不绕弯。但也带了实际的问题,当一个任务破坏了系统,比如产生了内存越界,必须重启整个系统,才能解决问题。每一个任务都可以威胁内核或者其他任务,系统的安全性也比较差,无法提供更复杂的应用。
所以在高级的处理器上都集成了MMU单元,每个进程都是通过页表来间接访问实际的内存,每个进程都有自己的页表,那么进程间从逻辑上就把内存隔离开了,一个进程访问不了另外一个进程的内存空间,同时在页表中还有内存访问权限的控制,比如访问了空指针,会触发CPU的缺页异常,这个时候只需要杀掉出问题的进程,但整个系统还是正常的。
对于linux虽然用户进程内存空间是分离的,但kernel还是个大的线程池,所有的内核线程都共享一个页表,主要为了处理简单,带了的问题是一个内核驱动出问题,一般的解决方法就是重启系统。
有本书叫 Linux内核情景分析 开始章节介绍了X86处理器段页式的内存映射,可以仔细看看。ARM9/ARM11/CORTEX-A系列有MMU功能,内存映射相对简单一些,因为X86有着段地址的历史包袱,而ARM没有。
|