Linux之搭建自己的根文件系统

时间:2021-08-23 02:25:22

  Hi!大家好,我是CrazyCatJack。又和大家见面了。今天给大家带来的是构建Linux下的根文件系统。希望大家看过之后都能构建出符合自己需求的根文件系统^_^

1.内容概述

1.构造过程

  今天给大家展示的根文件系统构造过程如下图所示:

Linux之搭建自己的根文件系统

  正如大家看到的,这是一个环环相扣的过程。因为在这四个方面的内容其实相互包含,有很多交集的地方,所以我用环图给大家展示。在第一部分,我会给大家讲解如何在etc/目录下编写相应的配置文件,包含etc/init.d/rcS和etc/fstab等;在第二部分,将会教大家使用mdev,利用它来添加热插拔功能,自动创建已经存在和即将加入的设备驱动节点;第三部分将给大家详细讲解如何用工具生成两种文件类型的根文件系统,包含yaffs2和jffs2类型;第四部分给大家讲解如何用NFS挂载根文件系统,包含启动后挂载和启动前挂载两种方法。

2.最小根文件系统

  今天我们构建的最小根文件系统启动过程如下:

Linux之搭建自己的根文件系统

  这是我做的最小根文件系统的执行流程图。这其中2.3.4步是busybox的工作。关于busybox请参照我的上一篇博文《Linux根文件系统分析之init和busybox》,里面CCJ给大家详细讲解了2.3.4步的内容^_^ 。今天主要给大家讲解第一步和第五步。

  1) 创建设备console和null:

  首先,我们需要创建一个目录,自己命名。这里博主创建CCJ目录:mkdir CCJ。然后进入自己创建的这个文件夹目录,并创建dev目录:mkdir dev 。进入目录dev:cd dev/ 。然后我们需要查看一下console和null的主次设备号:ls /dev/console /dev/null -l 。这里博主显示的console的主设备号为5,次设备号为1;null的主设备号为1,次设备号为3。现在我们就可以创建设备console和null了:

  mknod console c 5 1

  mknod null c 1 3

  在CCJ目录下创建etc目录:mkdir etc 。创建etc目录下的inittab配置文件:vi etc/inittab 。并在其中添加console::askfirst:-/bin/sh 使这个shell的标准输入,标准输出,标准错误都指向这个console。第一步就这样轻松的完成啦!

  2)配置C库:

  首先我们创建lib目录,这个目录将用来存放C库的文件:mkdir CCJ/lib 。进入你存放C库文件的目录下,将C库文件复制到CCJ/lib目录下:cp *.so* /CCJ/lib -d。这里CCJ将C库中的动态库文件及其链接关系都复制到了CCJ/lib目录下。这样配置C库也完成了。 

2.构造过程

1.编写etc目录下的配置文件和mdev的使用

  由于使用mdev同样要配置etc目录下的配置文件,所以CCJ将这两个过程合并为一个小题目一起给大家讲解^_^ 。

  其实经过上面的过程,我们解决了根文件系统执行的第一步到第五步,现在已经可以生成一个小小的根文件系统了。但如果你生成并烧写到硬件上就会发现,这个小小的根文件系统的确能够正常运行,但它的功能还很有限。为了让它有更加丰富的功能和更方便的使用,现在我们需要添加一些新的配置。

  此刻我们制作的根文件系统中有些程序还没有安装,比如ps程序。有两种方法,一种是在根文件系统启动后我们手动挂载proc:

  mkdir proc

  mount -t proc none /proc

  这里的proc是linux内核提供的虚拟文件系统。它会将linux系统运行时的信息采集,必须将它挂接到/proc目录下。我们才能使用ps程序。那么经过这样的挂载我们就可以正常使用ps了。下面是在烧写了根文件系统的硬件上执行的命令:

  

ps
# ps
PID Uid VSZ Stat Command
S init
SW< [kthreadd]
SWN [ksoftirqd/]
SW< [watchdog/]
SW< [events/]
SW< [khelper]
SW< [kblockd/]
SW< [ksuspend_usbd]
SW< [khubd]
SW< [kseriod]
SW [pdflush]
SW [pdflush]
SW< [kswapd0]
SW< [aio/]
SW< [mtdblockd]
SW< [kmmcd]
S -sh
R ps

  这里我们可以看到有许多进程,其中PID表示的是进程号。ps是用来查看后台进程工作情况的命令。这时,我们进入proc目录,随便打开一个进程查看:

# cd /proc/
# ls
diskstats locks sys
driver meminfo sysrq-trigger
execdomains misc sysvipc
fb modules timer_list
filesystems mounts tty
asound fs mtd uptime
buddyinfo interrupts net version
bus iomem partitions vmstat
cmdline ioports scsi yaffs
cpu irq self zoneinfo
cpuinfo kallsyms slabinfo
crypto kmsg stat
devices loadavg swaps # cd
# ls -l fd
lrwx------ Jan : -> /dev/console
lrwx------ Jan : -> /dev/console
lrwx------ Jan : -> /dev/console

  正如大家看到的,proc/目录下有许多的进程。首列数字与上面的PID号对应,进入PID号,既是进入对应的应用程序。通过" ls -l fd "发现PID为1的进程其标准输入,标准输出,标准错误都指向/dev/console。

  这种挂载虚拟文件系统的方法虽然可用,但是十分麻烦,如果不想自己一个一个手动挂载的话,可以在etc/下编写配置文件,统一处理。这样在根文件系统启动的时候,配置文件会帮我们处理好所有程序的文件系统挂载。我们就能直接使用各种程序了^_^ 。

  在etc/inittab中添加::sysinit:/etc/init.d/rcS 。然后创建rcS这个脚本文件:mkdir etc/init.d    vi etc/init.d/rcS。在其中输入:mount -t proc none /proc。保存后再给它添加可执行权限:chmod +x etc/init.d/rcS 。这样修改后的根文件系统就会在启动时为应用程序自动挂载proc,效果和上面手动挂载的一样。这里我们也可以在rcS文件中添加:mount -a 命令来取代mount -t 命令。mount -a命令是根据etc/fstab来挂载文件的。编写etc/fstab为:proc /proc proc defaults 0 0。其效果和上面相同。

  由于linux下有很多设备驱动,如果手动一个一个添加dev/目录下的内容十分麻烦,所以我们可以用udev自动添加设备节点。这里我们用到的是busybox下的udev的简化版:mdev。那么我们该如何配置才能使用mdev呢?查看busybox目录下的mdev.txt文件,里面有详细的说明:

Mdev has two primary uses: initial population and dynamic updates.  Both
require sysfs support in the kernel and have it mounted at /sys. For dynamic
updates, you also need to have hotplugging enabled in your kernel. Here's a typical code snippet from the init script:
[] mount -t sysfs sysfs /sys
[] echo /bin/mdev > /proc/sys/kernel/hotplug
[] mdev -s Of course, a more "full" setup would entail executing this before the previous
code snippet:
[] mount -t tmpfs mdev /dev
[] mkdir /dev/pts
[] mount -t devpts devpts /dev/pts

  首先,根据 [1]、[4]我们得知,需要sys目录,dev目录。且需要添加sysfs和tempfs文件类型。所以在etc/fstab中添加:

  sysfs /sys sysfs defaults 0 0

  tmpfs /dev tmpfs defaults 0 0

  这里从左至右依次代表:设备名、挂载点、文件系统类型、默认参数等。又根据[2]、[3]、[5]、[6]在etc/init.d/rcS中添加:

  mkdir /dev/pts

  mount -t devpts devpts /dev/pts

  echo /sbin/mdev > /proc/sys/kernel/hotplug

  mdev -s

  这里的hotplug表热拔插,指向mdev。当添加新设备时,会调用它来创建新设备节点。而mdev -s则表示把现有的设备节点创建出来。经过这一番更改,我们重新生成根文件系统,烧写到硬件设备上,通过终端观察实验现象:

  Linux之搭建自己的根文件系统

  大家可以看到dev/目录下有很多设备节点,这都是mdev自动创建出来的。etc目录下配置文件和mdev使用讲解完毕。

2.生成yaffs2和jffs2文件

  下面讲一下如何利用工具生成yaffs2和jffs2文件。因为我们在linux下构建的根文件系统是要烧写到硬件平台上的,所以需要生成一个可烧写的文件。今天将两种可烧写的根文件系统的文件类型:yaffs2和jffs2。

  1>yaffs2:

  首先我们需要从网络或其他途径获取到mkyaffs2image工具,利用它来生成yaffs2文件。进入存有mkyaffs2image工具的目录下。将它解压缩:

  cd document_mkyaffs2/

  tar xjf yaffs_source_util_larger_small_page_nand.tar.bz2

  cd Development_util_ok

  cd yaffs2/

  cd utils/

  进入工具目录后:make 。生成我们需要的mkyaffs2image。将它复制:cp mkyaffs2image /usr/local/bin/。并给它可执行权限:chmod +x /usr/local/bin/mkyaffs2image。再次进入我们的CCJ目录,利用mkyaffs2image生成可烧写的根文件系统:mkyaffs2image CCJ CCJ.yaffs2。

  2>jffs2:

  生成jffs2比yaffs2要稍稍复杂一些。CCJ这里用到的是"mtd-utils-05.07.23.tar.bz2",它是MTD设备的工具包,编译它就会生成制作jffs2的工具。它需要zlib压缩包,所以我们要先安装zlib。大家可以自行下载zlib的源码进行安装,这里举例说明:

  tar xzf zlib-1.2.3.tar.gz

  cd zlib-1.2.3/

  ./configure --shared --prefix=/usr/

  make

  这里的shared是编译动态库,prefix表示将zlib安装在哪里。make生成zlib后,make install进行安装。

  现在有了zlib后,我们可以编译jffs2的生成工具了。

  tar xjf mtd-utils-05.07.23.tar.bz2

  cd mtd-util-05.07.23/util

  make

  make install

  现在我们就安装了解压后的jffs2生成工具。进入CCJ目录,执行:mkfs.jffs2 -n -s 2048 -e 128KiB -d CCJ -o CCJ.jffs2

  这里的-n表示不要在每一个擦除块上加上清楚标志;-s 2048表示一页大小为2048字节;-e 128KiB表示一个擦除块大小为128KB;-d 表根文件系统目录;-o表示输出文件。按理说,执行完这步生成的jffs2烧写到硬件平台上就能够正常运行,但是请大家注意更改自己的bootloader的环境变量,更改为挂载jffs文件类型,而不要默认为yaffs,否则会启动失败。

3.NFS挂载根文件系统

  这里也给大家介绍两种挂载方法:1.是在已经启动的硬件平台上,将服务器根文件系统挂载到硬件平台上。2.是在未启动的硬件平台上,通过修改环境变量,指定挂载地址为服务器地址,系统一启动就挂载服务器的根文件系统。

  1>启动后挂载:

  要想用NFS挂载根文件系统,必须满足两个条件:(1)服务器允许那个目录可被挂接。(2)硬件平台去挂接那个目录。首先是第一个条件,我们需要到etc/exports里去配置被允许挂接的目录:

  cd CCJ

  vi /etc/exports

  在其中添加我们根文件系统所在目录:

Linux之搭建自己的根文件系统

  保存后,重启NFS服务:/etc/init.d/nfs-kernel-server restart。理论上现在就可以挂载了,我们可以先试验一下,用服务器挂载自己的根文件系统看能否成功:

  mount -t nfs 192.168.1.19:/work/nfs_root/CCJ /mnt

  如果系统没有提示出错,而且根文件系统能够正常使用,就说明我们成功了。那么现在来真正的挂载,在已经启动的硬件平台的终端上,我们创建挂载点:mkdir /mnt。然后开始挂载:

  mount -t nfs -o nolock 192.168.1.19:/work/nfs_root/CCJ /mnt

  此时,如果挂载成功,在硬件平台上显示的就是服务器的根文件系统了,里面的文件内容一模一样,在服务器上对文件内容的更改也会显示在硬件平台上^_^ 。

  2>启动前挂载:

  这里,CCJ使用的bootloader是u-boot。只需在系统启动时,进入u-boot。修改u-boot的环境变量,使系统的根文件系统地址指向服务器的地址即可。在u-boot下,NFS挂载的定义格式如下:

  nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]
  ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>

  所以我们只需根据自己实际的IP地址、网关、子网掩码等替换掉其中的参数,然后将这条命令输给u-boot并保存就可以了。这里CCJ的硬件平台IP=192.168.1.13;服务器IP=192.168.1.19;网关=192.168.1.1;子网掩码=255.255.255.0 。在u-boot下,输入print就可以看到当前的环境变量,其中和挂载根文件系统相关的是bootargs:

  bootargs=noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0

  现在根据挂载跟文件系统的格式,我们需要更改:

  set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.19:/work/nfs_root/CCJ ip=192.168.1.13:192.168.1.19:192.168.1.1:255.255.255.0::eth0:off rootfstype=jffs2 init=/linuxrc console=ttySAC0

  将这条环境变量保存,然后启动内核。就可以看到我们的根文件系统和服务器是一样的,也就是说挂载到了服务器的根文件系统上 。

敬告:

本文原创,欢迎转载^_^

转载请在文章醒目处注明:

原创作者ID:    CrazyCatJack

原始博文链接:http://www.cnblogs.com/CrazyCatJack/p/6238385.html

题外话:

  马上就是2017年了,首先祝大家元旦快乐!^_^ 这一年里,CCJ收获了很多。完成了为期一年的项目,做出了满意的机器人;找到了心仪的工作,马上就要到广东去做linux驱动开发了,从来没有到过这么往南的地方呢;相信大家也收获良多吧,祝我们新的一年有更多的成长,世界也会因代码而不一样吧,嘿嘿~

CrazyCatJack

2016-12-31 16:06:18

  

Linux之搭建自己的根文件系统的更多相关文章

  1. Linux学习 :Uboot&comma; Kernel&comma; 根文件系统初步分析

    1.U-Boot启动内核的过程可以分为两个阶段: 1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段代码到RAM空间 设置好栈 跳转到第二阶段代码入口 2)第二阶段的功能 初始化本阶段使用的 ...

  2. 根文件系统的构建与分析(三)之根文件目录及最简&sol;dev目录

    根文件系统的构建与分析(三) 转载请注明 http://blog.csdn.net/jianchi88   Author:Lotte   邮箱:baihaowen08@126.com 一.FHS(Fi ...

  3. u-boot-2011&period;06在基于s3c2440开发板的移植之引导内核与加载根文件系统

    http://www.linuxidc.com/Linux/2012-09/70510.htm  来源:Linux社区  作者:赵春江 uboot最主要的功能就是能够引导内核启动.本文就介绍如何实现该 ...

  4. Qemu搭建ARM vexpress开发环境&lpar;三&rpar;----NFS网络根文件系统

    Qemu搭建ARM vexpress开发环境(三)----NFS网络根文件系统 标签(空格分隔): Qemu ARM Linux 经过上一篇<Qemu搭建ARM vexpress开发环境(二)- ...

  5. linux基础知识3&lowbar;根文件系统详解

    文件系统: rootfs:根文件系统 /boot:系统启动相关的文件,如内核.initrd以及grub /dev:设备文件 块设备:随机访问 字符设备:线性访问,按字符为单位 设备号:主设备号(maj ...

  6. 2-2 Linux 根文件系统详解

    根据马哥Linux初级视频2-3 1. 根文件下的一级目录 #ls / 1. / boot 系统启动相关的文件.如内核.initrd   (initialization run directory) ...

  7. linux根文件系统制作

    在嵌入式中移植的内核下载到开发板上,是没有办法真正的启动Linux操作系统的,会出现无法加载文件系统的错误. 那么根文件系统在系统启动中到底是什么时候挂载的呢?先将/dev/ram0挂载,而后执行/l ...

  8. Linux根文件系统的制作

    转载:http://www.cnblogs.com/hnrainll/archive/2011/06/09/2076655.html 1. 根文件系统 文件系统是包括在一个磁盘(包括光盘.软盘.闪盘及 ...

  9. Linux 根文件系统的制作

    一.建立根文件系统目录与文件 1. 创建目录 #mkdir rootfs #cd rootfs #mkdir bin dev etc lib proc sbin sys usr mnt tmp var ...

随机推荐

  1. java多线程详解&lpar;1&rpar;-多线程入门

    一.多线程的概念 线程概念 线程就是程序中单独顺序的流控制. 线程本身不能运行,它只能用于程序中. 说明:线程是程序内的顺序控制流,只能使用分配给程序的资源和环境. 进程:操作系统中执行的程序 程序是 ...

  2. 使用样式&OpenCurlyDoubleQuote;clear”和&OpenCurlyDoubleQuote;overflow”消除浮动元素对环绕行框的影响

    为元素设置“float”样式之后,元素会脱离标准文档流,不再占据原来的空间.后续元素会向前移动,占据这个新的空间.后续的文本会围绕着浮动元素分布,形成一种环绕布局的现象. 示例代码: <!DOC ...

  3. TCP&sol;IP、Http的区别

    TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据.关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍:“我们在传输数据时,可以只 ...

  4. Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享

    Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com ...

  5. FileResult,JavaScriptResult,JsonResult

    FileResult:可以响应任意文档的属性,包括二进制格式的数据,eg:图档,pdf,excel,zip,可以传入byte[],文档路径,Stream等不同的属性,让mvc将属性回传给客户端,除此之 ...

  6. 使用Visual Studio创建简单的自己定义Web Part 部件属性

    使用Visual Studio创建简单的自己定义Web Part 部件属性 自己定义属性使用额外的选项和设置拓展你的Web part部件.本文主要解说怎样使用Visual Studio创建简单的自己定 ...

  7. Codeforces Round &num;227 &lpar;Div&period; 2&rpar; E&period; George and Cards 线段树&plus;set

    题目链接: 题目 E. George and Cards time limit per test:2 seconds memory limit per test:256 megabytes 问题描述 ...

  8. uva 147 Dollars&lpar;完全背包)

    题目连接:147 - Dollars 题目大意:有11种硬币, 现在输入一个金额, 输出有多少种组成方案. 解题思路:uva 674 的升级版,思路完全一样, 只要处理一下数值就可以了. #inclu ...

  9. VUE错误码Attribute &&num;39&semi;&colon;sizeOpts&&num;39&semi; must be hyphenated

    Attribute ':sizeOpts' must be hyphenated 因为属性有大写,需要添加 - 来取代 例如 tampData  换成 tamp-data 就可以了

  10. &lbrack;转&rsqb; mongoDB与mongoose

    mongoDB简介 mongoDB与一些关系型数据库相比,它更显得轻巧.灵活,非常适合在数据规模很大.事务性不强的场合下使用.同时它也是一个对象数据库,没有表.行等概念,也没有固定的模式和结构,所有的 ...