linux挂载rootfs到运行第一个程序分析

本文详细解读了Linux启动过程中的init_post函数,介绍了文件系统和挂载根文件系统的工作原理,重点剖析了init程序(如busybox)及其与inittab的关系,以及如何使用busybox制作基本和完善的根文件系统,包括NFS挂载。
摘要由CSDN通过智能技术生成

书接上回

在上一篇博客“linux启动流程学习与总结”里,我们提到挂载根文件系统后,内核代码调用了init_post()函数执行了第一个应用程序,那么这个init_post()里面是干了什么呢?

从init_post()函数开始分析

红框部分的意思是指定输出信息的设备,sys_dup(0)是复制的意思,就是说标准输入/输出/错误都由这个中断打印

前面可以理解为设定输出信息的端口,下面就是运行第一个应用程序了

如果bootargs有指定init=xxx,就用xxx程序,如果没有,就用/sbin/init这个程序,这个程序是哪里来的,我们可以看到它是以绝对路径的方式调用的,说明这个程序是存着于一个根文件系统中的,在明白init这个程序哪里来的之前,我们有必要认识一下“文件系统”以及“挂载根文件系统”这个概念。

“文件系统”以及“挂载根文件系统”

文件系统,可以理解为固态存储的某一个区域,在逻辑上被组织成了某种格式,举两个例子比较好理解,就拿根文件系统来说,我们在某个路径下增删文件,实际是在固态存储增删文件,那么操控这个增删的过程,就是文件系统的功能之一,再例如windows的文件系统,一个磁盘我们可以复制电影到磁盘,还可以打开某软件来看电影,并且我们可以看见磁盘的容量在变小,这个过程中磁盘容量的多少、将电影复制过去后放在固态存储的哪个地方,调用某软件来加载电影,都是文件系统帮我们做的。说白了,文件系统就是一个帮我们管理固态存储空间的东西,并且由于文件系统里安装了一些软件,我们可以对文件进一步的操作。

当然,文件系统不止和固态存储有关,和内存还有关,不然速度该多慢,io操作得有多频繁。不过从逻辑上来理解文件系统,它很大一部分功能是为了管理固态存储管理文件的。

现在我们可以知道了,根文件系统的本质,就是一个可以管理固态存储、管理文件的东西,并且里面有一些软件可以给你用,那我们现在可能又有些奇怪了,根文件系统到底是个什么东西,它是一个程序还是一个类似磁盘的东西?

答案是它是一个类似程序的东西,它做的事情是将每一个文件夹、每一个文件都打上一个标记,并且各个文件、文件夹之间的关系都被记录着,这个标记的过程,其实就是在管理固态存储管理文件了,那它文件系统怎么能复制/删除电影呢?也很简单,电影实际也是文件,它在文件系统留有个标记,假如我们固态存储里有个删除电影的工具,这个工具本质不也是文件嘛,它同样在文件系统留有个标记,文件系统既知道电影的地址,也知道删除工具的地址,当然可以拜托cpu去删除电影啦,复制之类的操作也同理。

挂载根文件系统,其实就是把文件系统这个程序搞到后台去运行,这个程序呢是什么都不做的,但是呢如果你输入了ls,它就会像中断一样响应你做出对应的操作,把当前文件夹所有的文件都打出来。

我们知道ls之类的指令都是程序,那么ls是哪里来的呢?ls等linux指令,甚至根文件系统,都是由busybox制作出来的(现在有个叫buildroot的也能做根文件系统),但是busybox只是做了rootfs的主体而已,还有很多没有做完,/dev,mnt目录等,需要我们自己添加到根文件系统中。

后面会提怎么全面地用busybox制作根文件系统,现在我们知道了第一个应用程序是从busybox来的,继续启动流程分析,我们就要知道这个init做了什么事情。

分析init程序

其实我们ls -l /sbin/init 就会发现,init其实是链接于busybox这个文件的(有的可能显示的是system这个程序,其实是同类的一个东西,就是制作根文件系统的那个东西)

ls,cd等指令,也同样是链接于busybox这个文件的,事实上,ls,cd就是busybox这个程序的子程序,只不过,busybox将各种命令分成不同类型,对应不同的函数,因此能响应不同的命令。

既然ls,cd,init等程序都是链接于busybox,我们就不得不分析busybox这个程序做了什么事情。

分析busybox源码

可见busybox一开始就要解析inittab,下面那个函数new_init_action()不妨直接告诉大家,这个函数的作用与inittable这个文件是一样的,也就是说,如果没有找到inittab这个文件,就会执行一系列new_init_action()函数。它们的作用,都是配置!因此inittab是配置文件。

且看inittab文件的描述格式:

且看配置函数的原型:

函数参数1.事件驱动2.指定处理脚本3.指定设备

它们的对照关系就如下图两个红框所示,它们是可以互相转换的

通过看这个配置函数,我们大概能够知道配置文件/配置函数的作用。其作用就是,将一些动作分类,并且指定其处理函数,和中断不能说很像,只能说一毛一样,只不过这个是用软件实现的。我们可以猜测的是,它这个配置文件的每一个条目,都是“发生了xxx事,就用xxx设备,去执行xxx函数”。

举个实例:

就以上面的条目为例,解释一些是什么意思

<id>:<runlevels>:<action>:<process>
::ctrlaltdel:reboot
翻译过来就是
id可不填:runlevels可不填:当按键ctrl+alt+del按下时:就进行reboot操作

我们说inittab的作用是规定了一堆事情驱动的函数,这个和QT的信号和槽机制一样,它既可以被动

地被驱动,也可以有一个函数,发射出事件,让其对应的函数运行。

现在大家知道了inittab的作用和原理了,接下来继续分析busybox

busybox搞完inittab之后,主动发射了一堆的事件,且看下图:

ONCE类型的程序不需要等待其执行完。

可见,它发射了好几类的事件,有SYSINIT的,有WAIT的,有ONCE类型的,有RESPAWN类型的,有ASKFIRST类型的,可以看到while里面ONCE类型后面,还有一个while,里面有那些RESPAWN类型对应的进程,有ASKFIRST类型对应的子进程,并且它们这些子进程不像之前那些进程一样执行以此就完事了,它们会源源不断地被运行。其实这里面就有ls,cd这些程序,它们的进程随时都在后台嗷嗷待哺,等着ls,cd这些指令被调用(事件发生),它们就会执行对应的打印操作。(不要奇怪,因为如果ls,cd没有出现在控制台,那ls,cd的函数当然只是做一些初始化的事情或者什么都没做,这个是程序执行深度的问题)

到这里我们就知道了,init就是busybox这个程序,所谓执行init,实际就是读取inittab配置文件,然后初始化一堆的事件驱动,然后就是等着用户按下ls,cd之类的指令,之后就执行对应的操作。

由此我们也可以再次证明,其实根文件系统,就是一个程序!

下面来全面得了解怎么用busybox制作根文件系统。

基本根文件系统

一共需要如下五个东西

②配置busybox

源码的install有教人怎么编译

设置交叉工具链

配置menuconfig

TAB 补全

...

make

设置安装目录,不能直接安装否则会破坏原来的系统。

指定安装目录

CONFIG_PREFIX=路径

现在busybox就完成了

这样一个基本的根文件系统的框架就有了

①mknod console c 5 1

mknod null 1 3

③/etc/inittab 上面也讲了其格式和内容,busybox也有默认的

④暂且不做

⑤c库,不需要静态库(.a)只要动态库(*.so*)

从编译工具链那里拷贝

制作完成了,接下来将其打包成镜像

可作成yaffs格式的(适合小页的512B nand flash )

yaffs2适合大页的(一页2048B  nand flash )

打包烧写就可以就进去了

完善根文件系统

当然还需要补充一些完善根文件系统,比如了解内核信息的目录proc(虚拟的文件系统)

ps命令就是去proc目录里面得到内核进程信息的,如果之前没有proc,可以创建目录之后使用

mount -t proc none /proc

想要自动挂载,可以这样

在/etc/inittab加入:这个启动自动执行的脚本文件

然后再创建这个脚本文件,/etc/init.d/rcS

再rcS里面,加入

mount -t proc none /proc

记得加一个可执行的权限        chmod +x etc/init.d/rcS

挂载根文件系统之后就会自动执行了

其实mount -a也可

它会自动挂载/etc/fstab里的内容

解释:

1.device(名字) 挂到哪里  类型 选项  dump fsck order

名字可以随便写

文件系统类型 虚拟文件系统proc jffs2、yaffs、ext2、nfs等,也可是auto自动会检测

选项 是挂载参数,多个参数可用逗号隔开

dump

一些硬盘、共享文件系统之类的也是在这里挂载的,一般的启动脚本都有mount -a

cat /proc/mounts可以查看当前挂载的情况

继续完善

udev机制,自动创建/dev目录下的设备节点(可以参考讯为的教程或者[嵌入式Linux应用开发完全手册].完整版有目录第17章)

mdev是udev的简化版本,busybox里有提供,能够动态跟新/dev目录,还支持热拔插。

首先需要内核支持sysfs文件系统、tmpfs文件系统(减少对flash的读写)(确保内核设置了CONFIG_SYSFS,CONFIG_TMPFS)

总的来说,它需要做如下这些事

但是我们要让内核启动自动mdev,要改/etc/fstab和rcS

上面这些流程化的,纯抄书了

制作完成~打包

制作jffs2镜像也可以的,只是工具不同。

是可以强制指定根文件系统类型的

网络文件系统NFS

先从flash启动,试试手动命令挂接NFS

  1. 服务器允许其目录能被挂接

/etc/exports

完事后重启nfs服务,自测一下

  1. 单板去挂接

执行命令

mount -t nfs -o nolock 服务器ip:/服务端nfs目录 /本地目录

这样说明单板和pc都是支持nfs的,下面可以修改uboot命令行参数bootargs直接nfs挂接根文件系统

nfs启动参数:linux文档有,搜索nfsroot就能找到

中括号的参数可以省略,尖括号的不能省略

setenv bootargs 'noinitrd root=/dev/nfs rw nfsroot=服务端ip:/服务端目录ip=自己ip:服务端ip:网关:255.255.255.0:hostname(可空):eth0:off(不autoconf) init=/linuxrc';saveenv

完~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值