什么时候要重新制作Linux的根文件系统?谢谢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么时候要重新制作Linux的根文件系统?谢谢相关的知识,希望对你有一定的参考价值。
请问在什么时候要重新制作Linux的根文件系统?对Linux的根文件系统做了哪些修改,
就必须重新制作和下载根文件系统?
是否可以通过NFS来添加一些应用程序或者直接更改根文件系统,
而不至于要重新制作和下载根文件系统呢?
谢谢。
1. 根文件系统
文件系统是包括在一个磁盘(包括光盘、软盘、闪盘及其它存储设备)或分区的目录结构;一个可应用的磁盘设备可以包含一个或多个文件系统;如果您想进入一个文件系统,首先您要做的是挂载(mount)文件系统;为了挂载(mount)文件系统,您必须指定一个挂载点。
注:对于我们应用开发来说,购买开发板的时候,厂家会提供好现成的根文件系统和BootLoader等,如果需要,我们可以改变其中的命令而无需从头开始制作一个新的根文件系统。不过这儿的制作过程可以让我们更深一点理解Linux的文件系统。
2.主要的根文件系统
* Linux 中,rootfs 是必不可少的。PC 上主要实现有 ramdisk 和直接挂载 HD(Harddisk,硬盘) 上的根文件系统;嵌入式中一般不从 HD 启动,而是从 Flash 启动,最简单的方法是将 rootfs load 到 RAM 的 RAMDisk,稍复杂的就是 直接从Flash 读取的 Cramfs,更复杂的是在 Flash 上分区,并构建 JFFS2 等文件系统。
* RAMDisk 将制作好的 rootfs 压缩后写入 Flash,启动的时候由 Bootloader load 到RAM,解压缩,然后挂载到 /。这种方法操作简单,但是在 RAM 中的文件系统不是压缩的,因此需要占用许多嵌入式系统中稀有资源 RAM。
ramdisk 就是用内存空间来模拟出硬盘分区,ramdisk通常使用磁盘文件系统的压缩存放在flash中,在系统初始化时,解压缩到SDRAM并挂载根文件系统, 在linux系统中,ramdisk有二种,一种就是可以格式化并加载,在linux内核2.0/2.2就已经支持,其不足之处是大小固定;另一种是 2.4的内核才支持,通过,ramfs来实现,他不能被格式化,但用起来方便,其大小随所需要的空间增加或减少,是目前linux常用的ramdisk技术.
* initrd 是 RAMDisk 的格式,kernel 2.4 之前都是 image-initrd,Kernel 2.5 引入了 cpio-initrd,大大简化了 Linux 的启动过程,附合 Linux 的基本哲学:Keep it simple, stupid(KISS). 不过cpio-initrd 作为新的格式,还没有经过广泛测试,嵌入式 Linux 中主要采用的还是 image-initrd。
* Cramfs 是 Linus 写的很简单的文件系统,有很好的压缩绿,也可以直接从 Flash 上运行,不须 load 到 RAM 中,因此节约了 RAM。但是 Cramfs 是只读的,对于需要运行时修改的目录(如: /etc, /var, /tmp)多有不便,因此,一般将这些目录做成ramfs 等可写的 fs。
* SquashFS 是对 Cramfs 的增强。突破了 Cramfs 的一些限制,在 Flash 和 RAM 的使用量方面也具有优势。不过,据开发者介绍,在性能上可能不如 Cramfs。这也是一种新方法,在嵌入式系统采用之前,需要经过更多的测试。
3.Ramdisk制作
RAMDisk的制作方法如下:
(1) 在PC机的Linux操作系统环境下,生成可以虚拟成块设备的文件,假设文件名为init.img。
$ dd if=/dev/zero of=init.img bs=4096 count=1024
其中bs*count为块设备大小(单位:字节),生成init.img文件以后,还必须对该文件进行格式化。
$ mke2fs –m0 –F init.img
(2) 新建一个文件夹ram,并将init.img挂接到ram目录。
$ mkdir ram
$ mount init.img ram/ -o loop
这时,读写ram目录,等效于读写init.img文件。用户可以将根文系统所需的文件写入到ram目录中。往ram目录写完文件以后,还需要使用umount ram命令卸载init.img,才能将已写入的文件保存到init.img中。
(3)添加完毕,需要umount ram
4. Cramfs制作
CramFS(Compressed Rom File System)是Linux Torvalds在Transmeta任职时,所参与开发的文件系统。它是针对Linux内核2.4之后的版本所设计的一种新型只读文件系统,采用了 zlib 压缩,压缩比一般可以达到1:2,但仍可以作到高效的随机读取,Linux系统中,通常把不需要经常修改的目录压缩存放,并在系统引导的时候再将压缩文件解开。因为Cramfs不会影响系统的读取文件的速度,而且是一个高度压缩的文件系统。因此非常广泛应用于嵌入式系统中。
在嵌入式的环境之下,内存和外存资源都需要节约使用。如果使用RAMDISK方式来使用文件系统,那么在系统运行之后,首先要把Flash上的映像文件解压缩到内存中,构造起RAMDISK环境,才可以开始运行程序。但是它也有很致命的弱点。在正常情况下,同样的代码不仅在Flash中占据了空间(以压缩后的形式存在),而且还在内存中占用了更大的空间(以解压缩之后的形式存在),这违背了嵌入式环境下尽量节省资源的要求。
使用CramFS文件系统就是一种解决这个问题的方式。CramFS是一个压缩格式的文件系统,它并不需要一次性地将文件系统中的所有内容都解压缩到内存之中,而只是在系统需要访问某个位置的数据的时候,马上计算出该数据在CramFS中的位置,将它实时地解压缩到内存之中,然后通过对内存的访问来获取文件系统中需要读取的数据。CramFS中的解压缩以及解压缩之后的内存中数据存放位置都是由CramFS文件系统本身进行维护的,用户并不需要了解具体的实现过程,因此这种方式增强了透明度,对开发人员来说,既方便,又节省了存储空间。
但是Cramfs也有其缺点:延迟、小于16MB、不支持写,只支持PAGE_CREATE_SIZE=4096的内核。
制作的命令:(root文件夹中存放着文件系统)
#mkcramfs root cramfs.img
5. 其他根文件系统的制作
制作yaffs文件系统: mkyaffsimage myroots myroots.img
制作squashfs: mksquashfs $(FS_DIR) $(FS_NAME) -noappend -be -lzma -no-fragments –noI
6. BusyBox编译以及移植(根文件系统内命令的制作移植)
建立目标板空根目录文件夹及根目录下的文件夹:
[root@190 friendly-arm]# mkdir myroots
[root@190 friendly-arm]#pwd
/friendly-arm/myroots
[root@190 friendly-arm]#cd myroots
[root@190 myroots]# mkdir bin sbin usr lib dev mnt opt root etc home proc tmp var
[root@190 myroots]# mkdir etc/init.d
进入etc/init.d目录下,建立一个脚本文件,并命名为rcS,用gedit打开,添加如下内容:
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
创建 dev 中的节点
如果使用“linux 2.6.xx”的内核,应该事先创建节点“console”、“null”。否则在系统启动时内容会提示以下错误:
Warning: unable to open an initial console.Kernel panic - not syncing: Attempted to kill init!
创建节点的命令如下:
# mknod dev/console c 5 1# mknod dev/null c 1 3
移植Busybox:
进入到压缩文件存放的目录下,并解压。然后进入解压后的busybox目录文件夹,随后配置busybox 。
[root@190 busybox-1.2.0]# make menuconfig
由于每个版本的配置选项组织有所不同。不管怎样,我们注意以下选项就行了:
1) Support for devfs
2) Build BusyBox as a static binary ( no shared libs ) //将busybox编译成静态链接
3) Do you want to build busybox with a Cross Compile?
(/usr/local/arm/3.3.2/bin/arm-linux-) Cross Compile prefix //指定交叉编译器
4) init
5) Support reading an inittab file //支持init读取/etc/inittab 配置文件
6) (X) ash选中ash //建立的rcS脚本才能执行
7)ash
8)cp cat ls mkdir mv //可执行命令工具的选择,自己看着办吧,需要用到的就选上
9) mount
10) umount
11) Support loopback mounts
12) Support for the old /etc/mtab file
13) insmod
14) Support version 2.2.x to 2.4.x Linux kernels
15) Support version 2.6.x Linux kernels
16) vi
17)don’t use user
以上内容必须选上,其他可按默认值;如果要支持其他功能,如网络支持等,可按需选择,英语不是很烂的话,这些都没有问题。
配置好之后,保存退出。然后对其编译和安装到刚才建立的根文件系统目录下:
[root@190 busybox-1.2.0] make TARGET_ARCH=arm CROSS=arm-linux- \ PREFIX=/friendly-arm/myroots/ all install
安装好之后,将相应的二进制文件拷贝到根文件系统相应的目录下:
* 拷贝一些管理员控制程序到/sbin目录下,最重要的就是要包含一个init命令;
* 拷贝应用程序运行时所需要的库到/lib,库文件可以从PC机上的交叉编译工具安装目录下拷贝,如libc-2.2.2.so、libcryt- 2.2.2.so、libm-2.2.2.so、libutil-2.2.2.so等,为部分相应库建立快捷方式,提供一些应用程序按快捷方式名称调用。 参考技术A 1,当需要添加一些常用的应用程序,如ftp, telnet等,单独编译这些通用应用程序比较麻烦,不如直接使用busybox添加这些模块,重新制作文件系统。
2,需要添加一些动态库,配置文件,图片,视频等大文件时,已制作好的文件系统不包含这些文件。
在bootloader配置正确的NFS参数就可以启动网络文件系统,设备启动后直接映射到网络上,在被映射的开发机上添加删除文件都不影响嵌入式设备的使用,便于开发调试。本回答被提问者采纳 参考技术B 自己只做过软盘的,确实做过光盘的,都是用现成的。
但帮你找了一篇文章,你可以研究一下。
另外,虚机团上产品团购,超级便宜
Linux之搭建自己的根文件系统
Hi!大家好,我是CrazyCatJack。又和大家见面了。今天给大家带来的是构建Linux下的根文件系统。希望大家看过之后都能构建出符合自己需求的根文件系统^_^
1.内容概述
1.构造过程
今天给大家展示的根文件系统构造过程如下图所示:
正如大家看到的,这是一个环环相扣的过程。因为在这四个方面的内容其实相互包含,有很多交集的地方,所以我用环图给大家展示。在第一部分,我会给大家讲解如何在etc/目录下编写相应的配置文件,包含etc/init.d/rcS和etc/fstab等;在第二部分,将会教大家使用mdev,利用它来添加热插拔功能,自动创建已经存在和即将加入的设备驱动节点;第三部分将给大家详细讲解如何用工具生成两种文件类型的根文件系统,包含yaffs2和jffs2类型;第四部分给大家讲解如何用NFS挂载根文件系统,包含启动后挂载和启动前挂载两种方法。
2.最小根文件系统
今天我们构建的最小根文件系统启动过程如下:
这是我做的最小根文件系统的执行流程图。这其中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 1 0 3088 S init 2 0 SW< [kthreadd] 3 0 SWN [ksoftirqd/0] 4 0 SW< [watchdog/0] 5 0 SW< [events/0] 6 0 SW< [khelper] 55 0 SW< [kblockd/0] 56 0 SW< [ksuspend_usbd] 59 0 SW< [khubd] 61 0 SW< [kseriod] 73 0 SW [pdflush] 74 0 SW [pdflush] 75 0 SW< [kswapd0] 76 0 SW< [aio/0] 710 0 SW< [mtdblockd] 745 0 SW< [kmmcd] 763 0 3092 S -sh 770 0 3092 R ps
这里我们可以看到有许多进程,其中PID表示的是进程号。ps是用来查看后台进程工作情况的命令。这时,我们进入proc目录,随便打开一个进程查看:
# cd /proc/ # ls 1 745 diskstats locks sys 2 75 driver meminfo sysrq-trigger 3 76 execdomains misc sysvipc 4 763 fb modules timer_list 5 771 filesystems mounts tty 55 asound fs mtd uptime 56 buddyinfo interrupts net version 59 bus iomem partitions vmstat 6 cmdline ioports scsi yaffs 61 cpu irq self zoneinfo 710 cpuinfo kallsyms slabinfo 73 crypto kmsg stat 74 devices loadavg swaps # cd 1 # ls -l fd lrwx------ 1 0 0 64 Jan 1 00:10 0 -> /dev/console lrwx------ 1 0 0 64 Jan 1 00:10 1 -> /dev/console lrwx------ 1 0 0 64 Jan 1 00:10 2 -> /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: [1] mount -t sysfs sysfs /sys [2] echo /bin/mdev > /proc/sys/kernel/hotplug [3] mdev -s Of course, a more "full" setup would entail executing this before the previous code snippet: [4] mount -t tmpfs mdev /dev [5] mkdir /dev/pts [6] 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则表示把现有的设备节点创建出来。经过这一番更改,我们重新生成根文件系统,烧写到硬件设备上,通过终端观察实验现象:
大家可以看到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
在其中添加我们根文件系统所在目录:
保存后,重启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 |
题外话:
马上就是2017年了,首先祝大家元旦快乐!^_^ 这一年里,CCJ收获了很多。完成了为期一年的项目,做出了满意的机器人;找到了心仪的工作,马上就要到广东去做linux驱动开发了,从来没有到过这么往南的地方呢;相信大家也收获良多吧,祝我们新的一年有更多的成长,世界也会因代码而不一样吧,嘿嘿~
CrazyCatJack
2016-12-31 16:06:18
以上是关于什么时候要重新制作Linux的根文件系统?谢谢的主要内容,如果未能解决你的问题,请参考以下文章