»针对低固存嵌入式系统的uClinux小型化方法 02
![Rank: 8](images/default/star_level3.gif) ![Rank: 8](images/default/star_level3.gif)
- UID
- 872238
|
![](http://images.eccn.com/silabs/silicon_chip_980x60_202203.jpg)
»针对低固存嵌入式系统的uClinux小型化方法 02
在本系统中删除了根文件系统,但仍保留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()完全是跟挂载有关的,可以将它删除,同时内核中有好多涉及操作此数据结构的函数也必须做出更改。比如alloc_vfsmnt()和free_vfsmnt()是分配和释放vfsmount结构,完全可以删去,但有些内核函数只有一部分涉及到对vfsrmnt结构的操作,所以不能全部删除,必须对相应部分做出修改。
1.2.2 对内核启动初始化的影响
由于init()进程不能从根文件系统加载,所以凡是涉及根文件系统初始化函数的都必须删除,以支持内核与应用程序一体化。初始化进程init代码如下:
static int init(void *unused)
{……
if(open("/dev/console",O_RDWR,0)< 0)
……
if(execute_command)
execve(execute_command,argv_init,envp_init);
execve("/sbin/init",argv_init;envp_init);
……
panic("No init found.Try passing init= option to kernel");
}
init()完成系统的初始化,包括外部设备的初始化,释放init()前初始化后代码占用的内存,以及控制台的初始化,最后从根文件系统加载整个系统的第一个进程init,它是所有进程的“鼻祖”。由于根文件的删除,所以可以删除控制台以及调用init进程。 |
|
|
|
|
|