第4阶段——制作根文件系统 (4)
在上节制作busybox后(位于/work/nfs_root/mini_fs), 然后根据以下5个来构建最小根文件系统:
(1)/dev/console(终端控制台, 提供标准输入、标准输出以及标准错误)
/dev/null (表示空设备终端, 所有写到这个文件中的数据都会被丢弃掉。)
(2)init进程的程序(也就是busybox,因为init程序位于busybox中,已经完成)
(3)/etc/inittab(用于init进程读取配置, 然后执行inittab里的指定应用程序)
(4)应用程序(被inittab配置文件调用的应用程序)
(5)C库(glibc,被应用程序调用的C库函数,比如:printf,strcmp,fopen等)
1.创建终端(/dev/console和/dev/null)
1.1输入ls /dev/console /dev/null -l 查看pc机上终端的设备号:
得出:/dev/console主设备号=5,次设备号=1
/dev/null 主设备号=1,次设备号=3
1.2根据上面得出的设备号,创建console和null字符设备文件
mkdir dev //先在mini_fs目录下创建个dev目录(设备都放在dev目录下)
cd dev/
sudo mknod console c 5 1 //创建console字符设备,
sudo mknod null c 1 3 //创建null 字符设备,
2. busybox已做好,所以init进程的程序也就做好了。
3.构造/etc/inittab (执行inittab里的指定应用程序)
mkdir etc //在mini_fs目录下创建个etc目录
vi etc/inittab //创建inittab文件
inittab里添加内容:
console::askfirst:-/bin/sh //action值必须小写 id可以写成/dev/xx或xx
表示action= askfirst(每次启动/bin/sh进程之前等待用户按下enter键),然后指定/bin/sh的终端对应/dev/console字符设备
4.安装glibc库
mkdir lib //在mini_fs目录下创建个lib目录 (存放库函数)
cd /work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/lib //进入源目录
cp *.so* /work/nfs_root/mini_fs/lib -d //复制glibc库到lib目录(*:匹配符,-d:保持链接)
5.使用mkyaffs2image制作文件系统(yaffs1针对小页512B,yaffs2针对大页2KB)
5.1生成mkyaffs2image工具
在/work/system目录中 有一个压缩文件yaffs_source_util_larger_small_page_nand.tar.bz2(保存了yaffs1和yaffs2)
tar –xjf yaffs_source_util_larger_small_page_nand.tar.bz2 //解压
解压得到Development_util_ok,里面就有yaffs1和yaffs2,如下图:
5.2然后,进入yaffs2/utils,执行make 命令生成mkyaffs2image工具,将它复制到usr/local/bin目录:
cd yaffs2/utils
make
sudo cp mkyaffs2image /usr/local/bin
sudo chmod +x /usr/local/bin/ mkyaffs2image //添加可执行属性
5.3 mkyaffs2image制作yaffs2文件系统
cd /work/nfs_root //进入文件系统目录上一层
mkyaffs2image mini_fs mini_fs.yaffs2 //将mini_fs文件系统制作成mini_fs.yaffs2映像文件系统
6.将制作好的mini_fs.yaffs2通过DNW下载到板子上,进行试验
串口输出如下图,发现无法打开控制台:
发现是在创建console和null字符设备文件那里出了问题,因为没有加权限模式,所以内核无法找到console。
删除console和null设备,重新创建它们:
sudo mknod –m 660 console c 5 1 //创建console字符设备,设置权限用户和组都能读写
sudo mknod –m 660 null c 1 3 //创建null 字符设备, 设置权限用户和组都能读写
重新制作yaffs2并烧写就能成功了, 如下图:
刚好对应inittab配置文件中内容:console:: askfirst:-/bin/sh
askfirst: 启动/bin/sh进程之前等待用户按下enter键
最简单的根文件系统就完成了,接下来开始完善根文件系统。
7 完善系统——添加ps命令
它是通过proc虚拟文件系统挂接到proc目录,然后当前进程的信息会以文件的形式保存到proc目录,就可以用ps命令来查看内存中当前进程的状态了
mkdir proc //创建proc目录
mount –t proc none /proc //挂载proc, none:表示运行mount命令时显示proc相关的输出
接下来就可以使用ps命令了,如下图:
这里的PID进程号都以文件的形式存在了/proc目录里,例如cd proc/1 ,进入init进程(init进程是内核第1个挂载的进程),如下图
其中fd文件就是保存init进程的3个文件描述符--标准输入(0)、标准输出(1)以及标准错误(2)
通过ls –l fd 可以看出这3个文件描述符都指向/dev/console控制台,如下图:
7.1 inittab配置文件中追加内容,避免手动mount挂载proc
方法1:
在inittab里追加内容:
::sysinit:/etc/init.d/rcS //将/etc/init.d/rcS脚本设置成系统的初始化文件
然后mkdir -p etc/init.d 和vi etc/init.d/rcS, 添加一行命令(也可以添加其它命令)
mount -t proc none /proc //挂载proc(前提根文件系统有proc目录)
并加上可执行权限
sudo chmod +x etc/init.d/rcS //使脚本rcS能够执行命令
方法2:
除了使用在rcS中添加mount -t proc non /proc命令
也可以用mount -a 作用是加载文件/etc/fstab中配置的所有设备
它会依赖一个配置文件/etc/fstab
它的格式如下 (参考linux应用开发手册第368页)
vi etc/init.d/rcS, 添加一行命令
mount -a //加载文件/etc/fstab中配置的所有设备
然后创建fstab文件vi etc /fstab,添加内容:
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
可以直接在板子里操作,然后重启就能使用ps命令了。
通过cat proc/mounts 命令就可以查看当前挂载proc虚拟文件系统:
8 完善系统——使用mdev自动在/dev下创建设备节点
现在dev下只有2个字符设备,如果大量增加设备的话,手动创建太麻烦,可以使用udev。
mdev 是udev的一个迷你版, 它主要的功能是管理/dev目录底下的设备节点。它同时也是用来接替devfs及热插拔的功能
mdev使用说明在busybox-1.7.0/docs/medev.txt中以及linux应用开发手册第369页,如下图:
从上面得出mdev都需要内核sysfs、tmpfs、devpts的支持,
sysfs是管理虚拟系统,为udev提供设备入口和uevent通道,sysfs类型,需要挂载到/sys目录下
tmpfs是内存文件系统,tmpfs类型,需要挂载到/dev目录下
devpts是内核虚拟系统, 管理员通过文件系统和内核进行沟通(读\写)的一种渠道, devpts类型,需要挂载到/dev/pts目录下
8.1 创建sysfs、devpts要挂载的目录
mkdir /sys //创建sysfs要挂载的目录
mkdir /dev/pts //创建devpts要挂载的目录
8.2 vi etc/init.d/rcS, 追加热拔插命令和配置/dev设备,添加内容如下:
echo /sbin/mdev > /proc/sys/kernel/hotplug
//自动创建/proc/sys/kernel/hotplug, /sbin/mdev并指向hotplug,使mdev支持热插拔
mdev -s //将/dev目录下的设备文件创建成节点
8.3 vi etc /fstab,添加sysfs、tmpfs、pevpts挂载内容:
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
devpts /dev/pts devpts defaults 0 0
然后烧录至板子中查看效果,如下图,dev目录下自动创建了很多节点,然后/proc/mounts里也有挂载记录
9 mkfs.jffs2制作jffs2文件系统(参考linux应用手册375页)
若需要制作yaffs2映像文件,则参考:http://www.cnblogs.com/lifexy/p/7028739.html
9.1 安装zlib(压缩动态库)
cd /work/GUI/xwindow/X/deps
tar -xzf zlib-1.2.3.tar.gz
cd zlib-1.2.3
./configure --shared --prefix=/usr //配置安装动态库(shared)到指定(prefix)的/usr目录下
make //编译
sudo make install //安装
9.2 然后编译mkfs.jffs2工具
cd /work/tools
tar -xjf mtd-utils-05.07.23.tar.bz2
cd mtd-utils-05.07.23/util
make
sudo make install
9.3制作jffs2文件系统
cd /work/nfs_root //准备制作子目录mini_fs
mkfs.jffs2 -n -s 2048 -e 128KiB -d mini_fs -o mini_fs.jffs2
/*-n:表示每块不添加清除标记,-s:size一页大小为2k,-e:一块大小为128kb
-d:制作的dir目录,-o:输出文件 */
9.4 烧入板子中,并设置bootargs参数为jffs2启动
在uboot中输入:
set bootargs noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0
// rootfstype:将root file system type(根文件系统类型)强制设为jffs2
然后save保存后重新启动内核:
10 使用nfs挂载虚拟机目录
10.1确定板子是否与虚拟机位于同一网段
ifconfig eth0 up //开启网关0,连接网线到路由器
ifconfig eth0 192.168.0.107 //设置ip
ping 192.168.0.106 //与虚拟机ping一下,是否已通
10.2确定虚拟机是否能被挂载目录
首先要使虚拟机能够被别人挂载目录,在/etc/exports中添加需要被挂载的目录即可
例如:
sudo vi /etc/exports
添加以下一段内容:
/work/nfs_root/mini_fs *(rw,sync,no_root_squash) //添加挂载目录:/work/nfs_root/mini_fs
sudo /etc/init.d/nfs-kernel-sever restart //然后重启nfs服务
10.3 然后将板子内核来挂载虚拟机目录
mkdir /mnt //创建要挂载的目录
mount -t nfs -o nolock,vers=2 192.168.0.106:/work/nfs_root/mini_fs /mnt
//将远端虚拟机/work/nfs_root/mini_fs目录挂载到开发板/mnt目录里
//命令详细参数参考: http://www.cnblogs.com/lifexy/p/7380549.html
如下图,然后板子内核的/mnt目录就是虚拟机/work/nfs_root/mini_fs目录了
11 使用nfs 作为根文件系统启动
通过设置u-boot的bootargs来更改开机自动进入nfs文件系统,不需要mount指令
步骤(参考http://www.cnblogs.com/lifexy/p/7049743.html):
进入uboot,输入:
set bootargs noinitrd root=/dev/nfs nfsroot=192.168.0.106:/work/nfs_root/mini_fs ip=192.168.0.107:192.168.0.106:192.168.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
//设置npptargs,添加nfsroot(红色:远端服务器参数,蓝色:开发板客户端参数)
save //保存参数
然后重启开发板进入内核,就启动nfs文件系统了
人间有真情,人间有真爱。