uCLinux简介--

2019-07-12 21:48发布

嵌入linux发布版: 嵌入式LinuxMontaVista Software, Inc.Hard Hat LinuxLineo Inc.EmbedixTransvirtual Technologies Inc.PocketLinuxLynuxWorks Inc.BlueCatPalmPalm Technology Inc.Tynux等等。 中文的有:博利思的POCKET IX、红旗的嵌入式LinuxControLinux、蓝点的蓝点嵌入、移软科技的mLinux、共创联盟的CC-Linux等等。   分类:          不支持实时性。解决uclinux实时性支持有两种方案:RTLRTLinux)和RTAIReal Time Application Interface)。 分类: 1.第一类是在利用Linux强大功能的前提下,使它尽可能的小,以满足许多嵌入式系统对体积的要求,如uClinux(http://www.uclinux.org) 2.第二类是将Linux开发成实时系统尤其是硬/firm实时系统,应用于一些关键的控制场合,如Fsmlabs公司(http://www.rtlinux.org)RTLinuxMontaVista(http://www.mvista.com)Hard Hat Linux等; 3.第三类的产品就是将实时性和嵌入式方案结合起来的方案,很多公司都这么做,并且提供集成化的开发方案,如LineoTimeSys、合肥华恒等。     uCLinux仍然保留了Linux的大多数的优点:稳定、良好的移植性、优秀的网络功能、完备的对各种文件系统的支持、以及标准丰富的API。它的主要特征如下: ●通用Linux API ●内核体积 512 KB ●内核 +文件系统<900 KB ●完整的TCP/IP 协议栈 ●支持大量其它的网络协议 ●支持各种文件系统,包括 NFSext2ROMfs and JFFSMS-DOSFAT16/32     uCLinux小型化的另一个做法是重写了应用程序库,相对于越来越大且越来越全的glibc库,uClibclibc做了精简。 uCLinux对用户程序采用静态链接的形式。     uClinux与标准linux在内存处理方面的区别:          标准linux          ◇标准Linux是针对有内存管理单元的处理器设计的。虚拟地址被送到内存管理单元(MMU),把虚拟地址映射为物理地址。采用分页的方式来载入进程。实际存储器分割为相同大小的页面。 ◇虚拟存储器由存储器管理机制及一个大容量的快速硬盘存储器支持。它的实现基于局部性原理,当一个程序在运行之前,没有必要全部装入内存,而是仅将那些当前要运行的那些部分页面装入内存运行(copy-on-write),其余暂时留在硬盘上程序运行时如果它所要访问的页已存在,则程序继续运行,如果发现不存在的页,操作系统将产生一个页失效异常,导致操作系统把需要运行的部分加载到内存中。必要时操作系统还可以把不需要的内存页交换到磁盘上。         通过赋予每个任务不同的虚拟--物理地址转换映射(页表),还可支持不同任务之间的保护、共享等。         对于多进程管理当处理器进行进程切换并执行一个新任务时,一个重要部分就是为新任务切换页表。          ◇可以运行只加载了部分的程序,缩短了程序启动的时间 运行比内存还要大的程序。理想情况下应该可以运行任意大小的程序
可以使多个程序同时驻留在内存中提高CPU的利用率
◇可以运行重定位程序。即程序可以方于内存中的任何一处,而且可以在执行过程中移动
◇写机器无关的代码。程序不必事先约定机器的配置情况
◇减轻程序员分配和管理内存资源的负担 可以进行程序代码共享
提供内存保护,进程不能以非授权方式访问或修改页面,内核保护单个进程的数据和代码以防止其它进程修改它们。否则,用户程序可能会偶然(或恶意)的破坏内核或其它用户程序 代价:内存管理需要地址转换表和其他一些数据结构,留给程序的内存减少了。地址转换增加了每条指令的执行时间,而对于有额外内存操作的指令会更严重。当进程访问不在内存的页面时,系统处理失效的磁盘I/O操作极耗时间。 uClinux: uClinux针对没有MMU的处理器设计,不能使用处理器的虚拟内存管理技术,但出现简单和尽量靠拢标准Linux得需要,uClinux仍然沿用标准Linux的分页内存管理结构,系统在启动时把实际存储器进行分页,但实际上采用的是实存储器管理策略。 uClinux系统对于内存的访问是直接的,(它对地址的访问不需要经过MMU,而是直接送到地址线上输出),所有程序中访问的地址都是实际的物理地址。 操作系统对内存空间没有保护(这实际上是很多嵌入式系统的特点),各个进程实际上共享一个运行空间(没有独立的地址转换表)。 一个进程在执行前,系统必须为进程分配足够的连续地址空间,然后全部载入主存储器的连续空间中。由于程序加载地址与预期(ld文件中指出的)通常都不相同,这样relocation过程就是必须的。 磁盘交换空间无法使用的,系统执行时如果缺少内存将无法通过磁盘交换来得到改善。   从易用性来说,uClinux的内存管理实际上是一种倒退,退回了到了UNIX早期或是Dos系统时代。开发人员不得不参与系统的内存管理。从编译内核开始,开发人员必须告诉系统这块开发板到底拥有多少的内存。 由于应用程序加载时必须分配连续的地址空间,而针对可连续地址分配内存大小是受限的,开发人员在开发应用程序时必须考虑内存的分配情况并关注应用程序需要运行空间的大小。另外由于采用实存储器管理策略, 用户程序同内核以及其它用户程序在一个地址空间,程序开发时要保证不侵犯其它程序的地址空间,以使得程序不至于破坏系统的正常工作,或导致其它程序的运行异常。从内存的访问角度来看,开发人员的权利增大了(开发人员在编程时可以访问任意的地址空间),但与此同时系统的安全性也大为下降。 从嵌入式设备实现的功能来看,嵌入式设备通常在某一特定的环境下运行,只要实现特定的功能,其功能相对简单,内存管理的要求完全可以由开发人员考虑。   标准Linux系统系统数据段,代码段,堆和栈在虚存层面是连续的。堆向上增长,栈向下增长,在堆底和栈顶之间有256MB的内存可供分配。 uClinux采用了实内存模式,各个内存段在物理内存层面是连续的,栈段在同数据段在一起,堆有系统内存管理,所有进程共享,由于内存连续和保护的要求,栈段,数据段,代码段都是在程序加载是分配。这种内存空间布局阻碍了动态连接库的运用。栈段的大小固定(在生成应用时可以指定栈段大小),开发人员在开发时不得不使用一些方法估计判断栈段的大小,使其即能满足程序的需要,又不浪费内存。     文件系统:    uCLinux系统采用romfs文件系统,这种文件系统相对于一般的ext2文件系统要求更少的空间。空间的节约来自于两个方面:首先内核支持romfs文件系统比支持ext2文件系统需要更少的代码;其次romfs文件系统相对简单,在建立文件系统超级块(superblock)需要更少的存储空间。Romfs文件系统不支持动态擦写保存,对于系统需要动态保存的数据采用虚拟ram/JFFS的方法进行处理(ram盘将采用ext2文件系统)。 UCLinux系统使用flat可执行文件格式,目前也支持elf文件格式。先解释几种可执行文件格式。
  coffcommon object file format):一种通用的对象文件格式; elfexecutive linked file):一种为Linux系统所采用的通用文件格式,支持动态连接和重定位; flatelf格式有很大的文件头,flat文件对文件头和一些段信息做了简化,可执行程序小。     uClinux的多线程: fork创建的进程几乎是父进程的精确复制,从fork返回后,父子进程执行同样的程序,有同样的数据和堆栈区,并从紧跟fork后的指令继续执行。 exec系统调用提供一个进程去执行另一个进程的能力,exec系统调用是采用覆盖旧有进程存储器内容的方式,所以原来程序的堆栈、数据段与程序段都会被修改。
fork
的优化: (1)COW (写时拷贝),首先由System V使用。不进行页面复制,父子进程共享页面,页面置为只读,无论父进程还是子进程试图修改页时,发生页失效,页失效处理程序进行页面复制,并清除只读标志。 (2)BSD采用的vfork,多数程序调用完成fork后会马上执行exec,因此vfork不进行页面复制,父进程将地址空间租界给子进程,并将自己阻塞,直到子进程将地址空间还给它。因此,子进程会一直使用父进程的地址空间直到它调用execexit,内核再将地址空间返回给父进程并唤醒它。fork非常快,甚至无需拷贝页表。它允许一个进程使用修改另一进程的地址空间。   MMU不是支持多进程的必要条件,只是更好的支持了多进程操作系统的实现。uClinux没有MMU管理存储器,不支持COW的机制,因此fork 的优化只有采用vfork这一途径,并且由于不支持虚拟地址空间,简单复制的fork实现也必须修正reloc段。最终,uClinuxfork/vfork都用vfork实现。子进程要么代替父进程执行(此时父进程已经sleep)直到子进程调用exit退出,要么调用exec执行一个新的进程,这个时候将产生可执行文件的加载,即使这个进程只是父进程的拷贝,这个过程也不能避免。当子进程执行exitexec后,子进程使用wakeup把父进程唤醒,父进程继续往下执行。     运行方式: uCLinux的内核有两种可选的运行方式:可以在flash上直接运行,也可以加载到内存中运行。后者可以减少内存需要。
    Flash
运行方式(XIP):把内核的可执行映像烧写到flash上,系统启动时从flash的某个地址开始逐句执行。这种方法实际上是很多嵌入式系统采用的方法。
   
内核加载方式:把内核的压缩文件存放在flash上,系统启动时读取压缩文件在内存里解压,然后开始执行,这种方式相对复杂一些,但是运行速度可能更快(RAM的存取速率要比Flash高)。     交叉开发环境: 交叉开发环境:在一个平台上生成另一个平台上运行的代码。 平台包含两个概念:体系结构(Architecture)、操作系统(Operating System)   建立交叉开发环境:   1.安装交叉编译工具
  针对uCLinux目前有两套编译工具:m68k-coffm68k-elf,它们都是GNU组织开发的优秀的编译器GCC的不同应用版本。它们的区别在于形成最终flat目标码之前的中间代码格式分别是coffelf类型。elf格式的编译器比coff格式的编译器有许多优越性,建议使用m68k-elf交叉编译器。编译工具包中除了交叉编译器以外,还有链接器(ld)、汇编器(as)以及一些为了方便开发的二进制处理工具,包括生成静态库工具(arranlib)、二进制码察看工具(nmsize)、二进制格式转换工具(objcopy)。这些都要安装在宿主机上。 2.安装uCLinux内核
  利用已安装的交叉编译器编译生成运行与目标机上的uCLinux内核。与标准Linux相同的是,uCLinux内核可以以配置的方式选择需要安装的模块,而增加系统的灵活性。 3.安装应用程序库
  用交叉编译器编译uC-libcuC-libm源码,生成libc.a应用程序库和libm.a数学库。 4.安装其他工具
  用GCC编译elf2flt源码,生成格式转换工具elf2flt。用GCC编译genromfs源码,得到生成romfs工具genromfs
  经过以上的准备工作之后,下面要针对特定应用所需要的设备编写或改造设备驱动程序。有一些设备驱动,uCLinux本身就已经具有。即便没有,因为uCLinux开放源码的特性,用户也可以很方便地把自己的驱动程序加入内核。如果用户对系统实时性,特别是硬实时有特殊的要求,uCLinux可以加入RT-Linux的实时模块。完成这些工作,一个嵌入式应用开发平台就已经搭建好了,在此之上,根据不同需要可以开发不同的嵌入式应用。