uClinux内存管理分析

2019-07-13 03:48发布

2007-12-25 09:45:58
字体变小字体变大 1 引言
内存管理在嵌入式操作系统中是很重要的子模块,能够对系统性能起决定性作用。uClinux是嵌入式Linux领域非常重要的分支,已成功应用于路由器、机顶盒、PDA等领域,与标准Linux在内存管理方面有着本质的区别。 2 uClinux概述
uClinux从Linux2.0/2.4内核派生而来,其内核二进制映像文件小于512K。无MMU (Memory Management Unit),内存管理单元)处理器设计,具
有完备的TCP/IP、支持多任务、多种网络协议和文件系统。uClinux可移植性很强,用户通过重新配置、编译内核,可方便移植到多种处理器计算平台。
由于去除了与MMU 相关代码,uClinux可生成内核与应用程序。uClinux缺乏内存保护机制和虚拟内存模块,这是uClinux与标准Linux的区别,一些底层系统调用也有变化,其内核结构如图1。

图1 uClinux的内核结构 3 uClinux的内存管理
uClinux不支持虚拟内存,它采用一种不同于标准Linux的内存模型,如图2。
标准Linux和uClinux内存模型
图2 标准Linux和uClinux内存模型
标准Linux中,堆顶和栈底间存在256MB的虚拟内存空隙。系统调用brk可改变堆的大小,C语言的标准库函数malloc,通常用brk动态分配大块内存,再切分成小块分配给内存的申请者。
uClinux 中,系统为进程分配的内存区域是连续的,代码段、数据段和栈段间没任何空隙。为节省内存,进程的私有堆被取消,所有进程共享一个
由操作系统管理的堆空间。uClinux中,用malloc实现一条系统调用,利用mmap从核心的空闲内存池中分配内存,munmap将内存返还核心内存池。
malloc实现方案有以下两个问题:
(1)uClinux中,用户调用mmap获得所有内存块被组成一个链表,先调用核心内存分配例程kmalloc,再将得到的内存块加到链表尾部。每次mmap调用,kmalloc和链表的开销是56个字节,这对于那些须分配大量小块内存的应用来说,56字节的开销会造成可观的内存浪费,而大量的小内存块会增加链表长度,降低内存的分配和释放速度。
(2)标准核心内存分配器(即kmalloc例程)仅分配2k字节的内存。
基于以上缺点,对malloc的实现做了(核心层和用户层)改进。即在核心层提供kmalloc2例程,取消kmalloc只分配2k字节内存的限制;在用户层
改进malloc算法,可一次分配更多内存,再切分成小块分给内存的申请者,以减少mmap的调用次数。由于栈和静态数据段之间没有间隙,栈段不能动态增长和缩减,必须估算出栈所需的内存空间,并以编译选项的形式告诉编译器,以确保栈段既不会侵犯数据段,又不浪费过多的内存。
uClinux不能使用处理器的虚拟内存管理技术,它仍然采用存储器的分页管理。系统启动时对存储器分页,加载应用程序对程序分页加载。由于没有MMU管理,所以uClinux采用实存储器管理。uClinux系统对内存的访问是直接的(它对地址的访问不经MMU,而是直接送到地址线上输出),所有程序访问的地址是物理地址。那些比物理内存还大的程序将无法执行。
uClinux将整个物理内存划分成为4KB的页面。由数据结构page管理,有多少页面就有多少page结构,它们又作为元素组成数组men_map[]。物理页面可作为进程代码、数据和堆栈的一部分,还可存储装入的文件,也可作缓冲区。
uClinux用标准Linux内核变型BuddySystem机制管理空闲物理页面。bitmap表和free_area数组及相关函数或宏_get_free_pages()、free_pages()、_get_free_page()仍在被使用。 4 uClinux内存管理的局限性
由于缺少MMU硬件的支持,uClinux的多任务管理功能受到一定的限制:
  1. uClinux中无法实现fork()只能用vfork()。父进程在调用vfork()后必须在子进程调用exec()或者exit()前阻塞;
  2. uClinux为可执行程序在紧随它的数据段结束处分配堆栈空间。如果堆增长太大,可能覆盖程序的静态数据段和代码段;
  3. uClinux中没有自动扩展的栈,也没有brk()调用。用户必须使用mmap()分配内存空间,也可在程序编译过程中指定使用栈的大小;
  4. 不具内存保护,系统安全性和可靠性降低。
内存管理上,uClinux未使用虚拟内存机制,因此,标准Linux内存管理模块中许多功能无法使用。为解决此问题,uClinux设计可执行文件格式:
flat,并修改进程管理代码。如用vfork()代替fork()调用,实现无法共享页面的do_mmap()。 5 结束语
uClinux内存管理和标准Linux系统功能相差很多。从嵌入式设备实现的功能来看。嵌入式设备通常在某一特定环境下运行,只实现特定功能,其功能相对简单,内存管理要求可由开发人员考虑。