Linux:一步一步制作自己的根文件系统

  • 一步一步制作自己的根文件系统

在这里,实验过程使用的是九鼎提供的S5PV210开发板,实验内核同样来自其官方资料盘中Linux资料包中的的QT4.8中的相关源码,实验的NFS文件系统在虚拟中的Ubuntu14.04中建立.

 

  • 建立文件系统根目录

rootfs有2种提现形式:nfs方式启动的文件夹形式和用来烧录的镜像形式,当然这里指的是前者.

开干了,随便找个位置新建一个新的文件夹作为NFS文件系统的根目录,这里我创建的文件夹的绝对路径是"/root/s5pv210-qt/s5pv210_qt4.8/rootfs-self/:

 如果需要开发板进行NFS挂载的朋友,记得将新建的目录导出到NFS服务器上,否则这个文件夹是不支持NFS的方式挂载的,相关NFS服务器的搭建请自行百度,或者参考我的相关博客,在这里我是通过开发板挂载自制的这个NFS来验证的.

 这个时候从开发版挂载这个文件系统并启动时,会失败,提示如下:

[   24.157685] VFS: Mounted root (nfs filesystem) on device 0:12.
[   24.162105] Freeing init memory: 208K
[   24.168151] Failed to execute /linuxrc.  Attempting defaults...
[   24.180174] Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.

意思是NFS挂载成功了,但是启动/linuxrc失败了,这说明我们根目录下需要这个/linuxrc,不难猜测这应该是在系统启动后第一个从文件系统运行的程序了,我们目前自制的根目录下是空的,这当然不行,我也试了在根目录下给它创建一个该文件,结果仍然也是失败的,这里不做过多研究,但是我猜测这个跟我们在开发版中uboot的启动参数中设置的内容有关,在我的另外一篇博客中,设置开发板加载NFS文件系统的相关步骤中,就有给uboot设置了一个这个参数"init=/linuxrc",所以我觉得应该是这里指定的启动程序是谁,有兴趣的朋友请自己尝试.

那么既然缺少这个程序,我们就得想办法给他安放一个,这里可以选择安装busybox.

 

  • 安装"/linuxrc"(这里是busybox)

busybox是一个开源项目,所以源代码可以直接从官网等网站下载,busybox的版本差异不大,这里用的是busybox-1.19.2.tar.gz,解压后进入busybox-1.19.2目录下,因为我们编译后是跑在开发板上的,所以这里要进行交叉编译工具的确认或修改,首先修改Makefile,确认下面两个变量的值设置满足要求,我这边的是:

ARCH = arm
CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-

使用"make menuconfig"命令修改并生成新的文件,相关配置参考如下:

Busybox Settings  --->
	Build Options  --->
		[*]	Build BusyBox as a static binary(no shared libs)
Busybox Settings  --->		
	Busybox Library Tuning--->
		[*]	vi-style line editing commands
		[*]	Fancy shell prompts
	
Linux Module Utilities  --->
	[ ]	Simplified modutils
	[*]	insmod
	[*]	rmmod
	[*]	lsmod
	[*]	modprobe
	[*]	depmod
	
Linux System Utilities  --->
	[*]	mdev
	[*]		Support /etc/mdev.conf
	[*]			Support subdirs/symlinks
	[*]				Support regular expressions substitutions when renaming dev
	[*]			Support command execution at device addition/removal
	[*]		Support loading of firmwares

继续修改配置文件,设置busybox的安装路径为我们要制作的NFS文件系统的根目录,譬如我的路径是"/root/s5pv210-qt/s5pv210_qt4.8/rootfs-self/",设置的地方在:

Busybox Settings  --->
	Installation Options ("make install" behavior)  --->
		(./_install) BusyBox installation prefix

如上所示,默认的安装路径会是当前busybox源码所在路径的_install下.设置完成后执行"make"及"make install"命令即可.

这个时候我们的NFS根文件里面不是空无一物了,有linuxrc等一些东西,接下来我们继续打开开发板挂载这个NFS文件系统,看看如何:

[   27.219456] VFS: Mounted root (nfs filesystem) on device 0:12.
[   27.223865] Freeing init memory: 208K
can't run '/etc/init.d/rcS': No such file or directory
can't open /dev/tty2: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty4: No such file or directory

可以看到,没有了之前的错误,也不会内核崩溃,但是会提示一些文件找不到,比如"/etc/init.d/rcS"和一些tty的设备文件,这个时候我们敲击回车,可以发现命令行已经出来了,这说明我们能够跑起来了,只是还不够完美,有一些问题需要解决,我们一步一步来.

 

  • 创建"/etc/init.d/rcS"文件

既然说找不到"/etc/init.d/rcS"这个文件,那么我们就创建一个这个文件,可以在网上查看一些资料学习一下这个文件,不难了解到这个文件是一个启动脚本,有兴趣的朋友可以查看自己的ubuntu主机中的该文件和其他资料进行学习,算是比较简单的一个脚本,这里直接贴出内容,并在后续分析一些现象时对相关内容做一些归纳:

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
/bin/hostname -F /etc/sysconfig/HOSTNAME
ifconfig eth0 192.168.1.88

创建完成后记得修改这个文件的权限,否则开发板开机后提示无该文件的执行权限,一般是给个运行权限就够了,不过这里我没有试,我是直接给的所有权限,执行命令"chmod 0777 /root/s5pv210-qt/s5pv210_qt4.8/rootfs-self/etc/init.d/rcS"后重启开发板,看看现在启动这个NFS后的情况会怎样:

[   23.169821] VFS: Mounted root (nfs filesystem) on device 0:12.
[   23.174233] Freeing init memory: 208K
mount: can't read '/etc/fstab': No such file or directory
/etc/init.d/rcS: line 8: can't create /proc/sys/kernel/hotplug: nonexistent directory
mdev: chdir(/dev): No such file or directory
hostname: can't open '/etc/sysconfig/HOSTNAME': No such file or directory
can't open /dev/tty2: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty4: No such file or directory

OK,有一个mount命令的错误,等等,说明我们要一一解决这些错误,并且这些错误都是由我们上面创建的这个脚本在执行过程中引出来的.

 

  • 创建"/etc/fstab"文件

"/etc/fstab"文件其实就是我们执行"mount -a"时所去加载的配置文件,他会按照该配置文件执行挂载操作.

# /etc/fstab: static file system information.
#
# Use 'vol_id --uuid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# 	 	 	 	 	 	
	proc 			/proc 			proc 	defaults 	0 		0
	sysfs 			/sys 			sysfs 	defaults 	0 		0
	tmpfs 			/var 			tmpfs 	defaults 	0 		0
	tmpfs 			/tmp 			tmpfs 	defaults 	0 		0
	tmpfs 			/dev 			tmpfs 	defaults 	0 		0

关于这个文件的细节有兴趣的朋友自行百度学习,这里只做简单了解,不难看出我们配置文件的意思就是我们会挂载一些文件系统,挂载点是在配置文件中定义的对应目录,譬如这里的prop文件系统会挂载在"/proc"下,可想而知,我们当前制作的文件系统中没有这些目录,如果只创建了这个文件,等文件系统被挂在后,肯定会提示找不到对应挂载点的一些错误,那么是不是这样呢,我们保存这个配置文件后,重启开发板看看:

[   23.184087] VFS: Mounted root (nfs filesystem) on device 0:12.
[   23.188501] Freeing init memory: 208K
mount: mounting proc on /proc failed: No such file or directory
mount: mounting sysfs on /sys failed: No such file or directory
mount: mounting tmpfs on /var failed: No such file or directory
mount: mounting tmpfs on /tmp failed: No such file or directory
mount: mounting tmpfs on /dev failed: No such file or directory
/etc/init.d/rcS: line 8: can't create /proc/sys/kernel/hotplug: nonexistent directory
mdev: chdir(/dev): No such file or directory
hostname: can't open '/etc/sysconfig/HOSTNAME': No such file or directory

can't open /dev/tty2: No such file or directory
can't open /dev/tty3: No such file or directory
can't open /dev/tty4: No such file or directory

果然,如我们猜想一样,那么解决这些mounting就非常简单了,原因已知,解决它就是创建这些对用的挂载点目录,之后重启开发板再看看:

[   24.194705] VFS: Mounted root (nfs filesystem) on device 0:12.
[   24.199113] Freeing init memory: 208K
hostname: can't open '/etc/sysconfig/HOSTNAME': No such file or directory

诶,神奇的发现不仅mounting失败的消息没有了,后面很多错误也没有了,其实仔细一看就能发现,其他的错误是对应的挂载点中的文件或者目录找不到的错误,这说明我们挂载了这些文件系统后,这些工作的文件系统就正常了.

在这里,不得不对"/etc/init.d/rcS"中的mdev的作用进行归纳,脚本中其他的命令都很简单理解.

mdev是udev的嵌入式简化版本,udev/mdev是用来配合linux驱动工作的一个应用层的软件,udev/mdev的工作就是配合linux驱动生成相应的/dev目录下的设备文件这里我们只是通过一些直观的现象来初步理解udev/mdev的工作效果.在rcS文件中没有启动mdev的时候,/dev目录下启动后是空的;在rcS文件中添加上mdev有关的2行配置项后,再次启动系统后发现/dev目录下生成了很多的设备驱动文件。

那么其实到这一步,基于嵌入式这种小型的文件系统可以说是完成了,但是不够完美,很多功能有缺陷,为什么呢?我们可以参考我们ubuntu主机中的文件系统,发现他有很多的配置文件,当然我们没必要做的那么庞大,没有意义,但是我们可以尽量完美一些,有兴趣的朋友还可以去分析busybox源码,这里不做分析了,没记错的话busybox首先将试图解析"/etc/inittab"来获取进一步的初始化配置信息,可以参考busybox源代码init/init.c中的parse_inittab()函数,而事实上,一些文件系统中并没有"/etc/inittab"这个配置文件,而之前却先看到了找不到"etc/init.d/rcS"文件的错误而不是找不到"/etc/inittab"文件,这些答案都能通过分析busybox源码得到,这里给出答案,其实busybox试图解析"/etc/inittab"失败后并不会报错,而会继续使用默认定义的初始化脚本,也就是源码中"INIT_SCRIPT"宏所定义的值,这个宏的默认值是"etc/init.d/rcS",再比如我们不在这个脚本中设置PATH环境变量,却仍能有PATH环境变量的一些功效(诸如使用"ls"命令等),这其实也是busybox中硬编码帮我们设置了这些环境变量的.

 

  • 创建"/etc/inittab"文件

 

 

你可能感兴趣的:(Linux)