根据下面五项创建根文件系统:
/dev/console,/dev/null;
init ⇒ busybox;
/etc/inittab;
配置文件中指定的程序;
C库。
/dev/console,/dev/null
首先先创建/dev/console和/dev/null两个设备,先看一下在PC机中这两个设备的描述。(各种设备都以文件的形式存在 /dev 目录下,称为设备文件)
crw中的C表示是字符类设备,5为主设备号,然后1是次设备号。(在嵌入式系统中,一个字符设备或者块设备都有一个主设备号和次设备号,主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序,次设备号用来表示该驱动程序的各个设备。例如一个嵌入式系统,有两个LED灯,需要可以独立的打开或者关断,那么可以写一个LED灯的字符设备驱动程序,将其的主设备号注册为10,次设备号分别为1和2,表示两个LED灯)
那么,我们首先创建一个dev目录,然后在dev目录下创建console和null。
使用mknod指令创建设备文件,c表示创建的是字符类设备(b的话则是块设备),然后主设备号5,次设备号1,null类似。
创建完毕后,使用ll查看。
init ⇒ busybox
第二项,init到busybox的链接,我们的init = /linuxrc,所以就是linuxrc到busybox的链接,这一项已经做好了。
/etc/inittab
第三项,构造一个inittab,如果不构造一个我们自己的inittab文件,那么就会使用默认的配置,下图是之前总结的默认的配置。
我们不需要这么多,只要一个::askfirst:-/bin/sh就好。
创建一个etc目录,在该目录下再创建一个inittab文件,注意终端需要设置为console,将标准输入,标准输出,标准错误都定位到console里面去。
最终结果如下,使用cat命令查看一下文件内容。
这样,inittab文件就配置好了,这是一个最简单的inittab文件,它只执行一个执行时机为ASKFIRST的程序-/bin/sh,该程序的标准输入,标准输出,标准错误都从/dev/console控制。
配置文件中指定的程序
第四,配置文件中指定的程序,由于我们只想做一个最小的根文件系统,不执行任何应用程序,所以这里先不配置,等后面再完善。
C库
第五,C库。
查看应用手册,里面有说怎么安装C库。
把所有的.so文件复制过来就可以了,-d表示如果该文件是一个链接文件,那么复制过去也是一个链接文件,不会把动态链接的那些文件也复制过去,这样就不会很大。(.a表示静态库,我们不需要静态库)
在046下创建一个lib目录,然后把.so文件全部复制过去,注意-d不要忘了。
这样,我们就做好了一个最小的根文件系统,需要注意一下,这个根文件系统是没有应用程序的。
烧录根文件系统
那么,这个根文件系统要怎么烧到我们开发板上呢?
答:需要做一个映像文件,查看《嵌入式Linux应用开发手册》,17.4.4和17.4.5分别讲述了怎么制作yaffs和yaffs2根文件系统,其中,yaffs是给小页(一页512字节)的Flash使用的,我们的nand flash每一页有2048字节,所以要使用支持大页的yaffs2根文件系统。
编译映像文件使用的工具名叫做mkyaffs2image,格式为:mkyaffs2image 目录名 映像文件名。
执行如下编译指令,编译得到一个映像文件046_first_fs.yaffs2,把这个文件发送到windows下,再烧录开发板。
在uboot中的菜单页选择y,使用DNW烧写工具烧写映像文件。
烧写完成后,加载根文件系统时报错了,错误信息如下。
查看了一下init_main函数,发现是name比对的时候出的错,action是小写的,但是inittab里面是大写,导致匹配失败。
将ASKFIRST改为小写再重新编译映像文件并烧录,可以正常启动了。
这样,我的第一个根文件系统就成功烧录并运行了。
完善根文件系统
现在编译的根文件系统没有什么功能,比如我们想要使用ps命令,会发现不支持这个命令。
我们需要再完善一下它,怎么完善呢?
首先,使用mkdir proc创建一个proc文件夹,虽然创建了一个proc文件夹,但是此时ps命令还是无效的,还要挂接一个虚拟的根文件系统。
那么,要怎么做呢?
答:在内核中,当前有哪些应用程序在运行,这些信息都存在内核里面一个叫proc的虚拟的根文件系统,将刚刚创建的proc目录挂接到这个虚拟的根文件系统就可以实现ps命令了。
使用mount -t proc none /proc进行挂接,之后ps指令可以正常使用了。
这时候进入proc目录,可以看到,里面有很多文件,这是因为proc已经被挂载到了内核提供的那个虚拟的根文件系统了。
如果不想手动挂载,那么可以在/etc/inittab配置文件中进行自动挂载。
在inittab文件中添加一行,::sysinit:etc/init.d/rcS,然后在etc路径下创建init.d目录,并在该目录下创建rcS文件,这是一个脚本文件。
在rcS文件中输入挂接的命令,并且给它加上一个可执行的属性,之后每次运行就会在初始化的时候自动将proc挂载过去了。
除了上面这个方法,还有一个方法是使用 mount -a 指令,这个指令会将/etc/fstab中定义的所有档案系统挂上。
使用这个方法,首先修改rcS脚本,将mount -t proc none /proc注释掉,并添上一句mount -a。
然后,需要在etc目录下增加一个fstab文件,在该文件下依次添加proc /proc等等,每一项需要用空格隔开。
#行是格式说明:
device,要挂接的设备;
mount-point,挂载点;
type,文件系统类型;
options,挂接参数,用逗号隔开;
这两种方法都可以实现自动挂接。
载入新的根文件系统后,可以直接使用ps命令,可以通过查看/proc/mounts文件查看挂接了哪些文件。
继续完善。
现在的dev目录下只有两个东西,dev目录下的文件对应于设备和驱动,如果我们有成千上百个驱动,每个驱动都要单独创建一个dev文件,那会很麻烦,有一种udev机制,可以自动创建dev目录下的设备节点(/dev/设备节点)。
在嵌入式Linux系统中,有一个udev的简化版本叫做mdev,那么这个mdev要怎么使用呢?
在docs目录下有一个mdev.txt,里面有讲怎么使用。
可以看到第一步和第四步分别是将/sys和/dev挂载到sysfs和tmpfs,这两个也是虚拟的根文件系统。
在fstab中将sys和dev挂载过去。
用rcS自动执行剩下的操作,修改后的rcS文件如下。
/proc/sys/kernel/hotplug,热拔插,在动态加载设备插入U盘等热拔插设备时,内核就调用这个hotplug,hotplug指向mdev,这样内核就会自动创建对应的设备节点。
mdev -s把内核已经有的设备节点创建出来。
具体的说明可以看这篇文章(https://blog.csdn.net/qq_33160790/article/details/79266306)
重新编译yaffs2根文件系统,烧录重启,可以看到在dev目录下多了很多设备,
挂载了很多文件系统。
这样,我们这个最小的根文件系统就比较完善了。
如果我们想使用别的格式的根文件系统,比如说jffs2,这个格式一般是用在NOR Flash上的,当然它也可以用在Nand Flash上。(没找到zlib压缩包,该文件系统目前也不是重点,关于jffs2的学习以后再说)
使用NFS挂载根文件系统
我们现在每改动一次根文件系统都要重新烧写,那有什么办法可以不烧写呢?
答:使用 NFS挂载根文件系统 ,将根文件系统放在服务器上,内核启动时直接将服务器上的根文件系统当做设备的根文件系统就行。
要用NFS挂接根文件系统的话,开发板不可以直接连到电脑,需要连到一台路由器或交换机,然后电脑也连到这台路由器或交换机。
将开发板接到路由器,电脑与路由器无线连接,开发板插上网线还是没反应,设置ip地址之后显示如下,此时再ping电脑可以成功了。
挂接NFS需要两个条件:
服务器允许那个目录可以被别人挂接;
开发板去挂接那个目录。
设置服务器允许挂载
那个,服务器怎么允许那个目录被别人挂接呢?
答:通过NFS服务,修改/etc/exports文件,在文件中将需要挂载的目录加进去就好了。
然后要重启一下NFS服务,指令和结果如下图所示。
一般来说,这样做完这个目录就可以被别人挂载了,但是我们要先在服务器上实验一下,先将它挂载到服务器的/mnt目录上试一下。
使用mount指令挂载,发现挂载成功,说明服务器可以被挂载。
设置开发板挂载服务器
设置服务器可以被挂载之后,就可以将开发板挂载到服务器。
开发板挂载到服务器有两种方法,一种是手动挂载,一种是自动挂载。
手动挂载
手动挂载就是从Flash启动根文件系统之后,再用命令挂接NFS,需要执行以下步骤:
在开发板创建一个/mnt目录;
使用mount -t nfs -o nolock 192.168.0.103:/home/book/Desktop/test/046_first_fs /mnt指令,将/mnt挂载到服务器上;
执行完这两步之后,就将服务器上的/home/book/Desktop/test/046_first_fs挂载到开发板的mnt目录上了。
现在,在/mnt目录下可以看到046_first_fs目录下的文件内容了。
这种方法是在启动之后手动挂载,还有一种是在系统启动时自动挂载。
自动挂载
自动挂载就是直接从NFS启动,这需要修改命令行参数,重启开发板,进入uboot。
需要修改bootargs参数,我们目前是从Flash启动,所以这个参数为:bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
需要设置为从NFS启动,这就需要设置以下两项:
服务器IP和挂载的目录,否则都不知道要挂到哪里去;
设置自己的IP,这是有一定的格式的。
使用grep指令,搜索一下bootargs参数的格式。
发现在Documentation目录下的nfsroot.txt文件中有设置的格式。
进入Documentation目录,然后查看nfsroot.txt,如下图所示,其中各项参数的意思这个文件也都有说明。
其中用中括号围起来的参数表示这一项可以省略,尖括号则不可省略。
使用set bootargs noinitrd root=/dev/nfs nfsroot=192.168.0.103:/home/book/Desktop/test/046_first_fs ip=192.168.0.110 init=/linuxrc console=ttySAC0指令,设置bootargs参数从nfs启动。
可以看到,服务器IP为192.168.0.103,目录为/home/book/Desktop/test/046_first_fs,开发板IP为192.168.0.110
下图是已经修改好了的bootargs参数。
设置完成后,重启开发板,此时一上电就自动挂载到服务器的046文件夹了。
上一篇:1_5.4.3_根文件系统_构建根文件系统之busybox_P
下一篇:1_5.5.1_字符设备驱动程序之概念介绍_P
推荐阅读最新更新时间:2024-10-12 12:01
设计资源 培训 开发板 精华推荐
- AD8532ARUZ-REEL 高输出电流基准/稳压器的典型应用
- 使用 Analog Devices 的 LTC3783IDHD 的参考设计
- LTC3606B 的典型应用 - 具有平均输入电流限制的 800mA 同步降压型 DC/DC
- 锂电池充电_5V_3.3V电压输出_V1.0_20200312_[验证成功]
- LT1952MPGN-1 18V 至 72V 宽输入、高效率、12V/12A 输出、有源复位正激转换器的典型应用电路
- EVAL-ADMP441Z,用于 ADMP441 I2S MEMS 麦克风的 SDP 子板
- L7812A 电流调节器的典型应用
- 具有 497mA 精密电流限制的 LT3066EMSE-5 3.3V 电源的典型应用电路
- LTC3897IUHF 4A、12V 过压和反向电流保护的典型应用电路
- DC2475A-A,基于 LT4295/LT4321 PoE++(40W,12V/3A)PD 的演示板,具有反激 DC/DC,理想二极管桥