微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 低固存嵌入式系统的uClinux小型化方法

低固存嵌入式系统的uClinux小型化方法

时间:06-21 来源:互联网 点击:

在许多嵌入式系统中,往往只有低容量的固存,比如MCF5282芯片内只有512k FLASH,而有些微处理器固存可能更低。在不外扩固存容量,降低系统稳定性的条件下,特别是在干扰源严重的工控环境下,采用短小、精炼的嵌入式操作系统将具有非常大的实用意义。文中以下内容将针对低固存嵌入式系统,讨论uClinux的几种特殊简化方法,应用这些方法,将非常有助于开发者开发出适合于自已的嵌入式系统。

1 内核移植

移植前首先要搭建交叉编译平台,安装交叉编译工具链,包括GCC,Binutils,uClibc。准备就绪后即可开始进行移植操作,移植过程中最大困难是如何减小uClinux系统的大小。为此文中从以下两个方面着手:内核配置级裁剪和内核源代码级裁剪。

1.1 内核配置级裁剪

Linux内核采用模块化的设计,即很多功能块可以独立地加上或卸下,开发人员在设计内核时把这些内核模块作为可选的选项,可以在编译系统内核时指定。因此一种较通用的做法是对Linux内核重新编译,在编译时仔细地选择嵌入式设备所需要的功能支持模块,同时删除不需要的功能。通过对内核的重新配置,可以使系统运行所需要的内核显著减小,从而缩减资源使用量。对于内核中不支持的设备,可以自已编制设备驱动程序,然后添加进内核。配置完内核,接下来需要对内核源代码文件的依赖性和完整性进行检验,并进行编译。

1.2 内核源代码级裁剪

Linux核心包括:进程管理模块、内存管理模块、文件系统、设备驱动模块、网络模块。在内核中文件系统和设备驱动程序占了大比重,约1/3以上,所以去除不必要的文件系统和设备驱动程序将会使内核大小有较大范围的缩减,这已在上一步骤中实现。所以文件系统的裁剪是重中之重。考虑到制作整个根文件系统的高昂代价,约有700kbyte大小,而一般嵌入式微处理器的FLASH一般小于512kbyte,根本就不可能固化,所以为了缩减系统的大小必须删除根文件系统,同时也导致内核与应用程序必须一体化。要删除根文件系统,并不是简单删除源代码,而是一个错综复杂的宏大工程。整个系统的框架如图1所示。

在本系统中删除了根文件系统,但仍保留VFS,主要保持VFS向上层提供统一接口,隐藏下层具体细节等作用,方便开发应用程序。同时针对文件规模小、数量少的嵌入式系统VFS在这里要减小它的规模和简化它的功能。规模的减小工作主要靠删除在嵌入式设备不支持的物理文件系统、设备驱动程序及其系统调用的源码。功能的简化主要靠简化部分数据结构和系统调用,这样可以进一步使系统规模精简。ReFS文件系统,是根据嵌入式系统的特性开发的一种新的文件系统。具体参见第3节新型文件系统(ReFS)开发。

由于根文件系统的缺失带来一些重大影响,分析如下。

1.2.1 对系统调用的影响

系统调用约有177个,包括关于进程的调用函数、文件的调用函数,以及其它相关的调用,其中文件系统的调用占了71个。由于没有根系统,系统调用中涉及到从根文件系统上或挂接在它某个文件节点上的其它文件系统上,装载、执行可执行文件的系统调用都是没必要的,所以必须做相应的更改。典型的是系统调用execve(),其执行流程主干线如图2所示。

exeeve()

do_exeeve()

open_execve()

prepare_binpma()

search_binary_hanlder()

图2 execve()执行流程

do_execve()是execve()的核心,它调用open_exec()寻找可执行文件并打开,函数open_exec()返回一个file结构指针,代表着读入可执行文件的上下文,将其保存在数据结构bprm中。然后调用prepare_binprm()完成对bprm的进一步工作,包括从可执行文件头读取相关信息,以及拷贝运行环境参数等到bprm 中。内核中有一个叫formats的队列,队列中的每个成员只认识并且处理一种特定格式的可执行文件的运行。search_binary_handler()就是在formats的队列中,寻找跟bprm中信息相符的一个成员,并由此成员来完成可执行文件的装载并初始化运行。由于不存在从文件系统加载可执行文件,所以bpma数据结构,及涉及prepare_binprm(),search_binary_hanlder()等相关操作都是可以删除的。

再者,由于没有可供mount的文件节点,所以有关挂接的系统调用也必须做出调整。比如:mount()是用于文件系统挂接的系统调用,完全可以删去;内核函数mount_root()在初始化时用于安装根文件系统,也是可以删去的;vfsmount()是内核数据结构,用于描述挂载节点的信息,包括挂载点的根目录,被挂载系统的级块指针等信息。vfsmount()完全是跟挂载有关的,可以将它删除,同时内核中有好多涉及操作此数据结构的函数也必须做出更改。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top