根文件系统定制
1、 创建一个全新的根文件系统
你可以用mkinitrd来创建,这里介绍另外一种方式,用dd命令:
# mkdir
-p /mnt/initrd 创建一个设备点,用于临时挂载根文件系统。
# cd /tmp 在tmp下创建根文件系统
# dd
if=/dev/zero of=/tmp/initrd bs=512 count=40960
创建一个名为initrd的根文件
系统,系统每个块的大小为
512字节,共40960块。
# mke2fs -F -m 0
initrd
格式化根文件系统,其中-F表示强制执行;
-m 0表示不为系统预留空间。
# mount -o loop
/tmp/initrd
/mnt/initrd 挂载根文件系统,记住这里要使用
-o loop选项,否则挂载会失败。
# cd
/mnt/initrd
2、 创建基本的目录结构
# mkdir dev proc etc etc/rc.d sbin bin lib mnt
tmp var usr
# chmod 755 dev etc etc/rc.d sbin bin lib mnt tmp var usr
#
chmod 555
proc
3、 添加设备
你可以使用mknod创建,也可以从现有的系统中拷贝过来,拷贝的时候一定要注意,最好使用-dfR,这样有两个好处:1、拷贝路径下的所有文件,如果有文件夹,则嵌套拷贝整个文件夹下的内容;2、保持文件(设备)的属性不变。
这里采用mknod创建的方式,以下设备是必须的console、kmem、mem、null、ram0、tty等。
建立一般终端机设备
# mknod tty c 5 0
# mkdir console c 5 1
# chmod 666 tty console
建立 VGA Display 虚拟终端机设备
# mknod tty1 c 4 0
# chmod 666 tty0
建立 RAM
disk 设备
# mknod ram0 b 1 0
# chmod 600 ram0
建立 null 设备
# mknod
null c 1 3
# chmod 666 null
4、
创建配置文件
到这里我们就有了一个初步的小型根文件系统,但是还需要配置一些有关的 shell
script来完善它。
在etc下创建最基本的配置文件fstab、inittab、rc.d/rc.sysinit,其中每个配置文件中至少应该包含以下
对应的内容:
fstab应包括:
/proc /proc proc defaults 0
0
inittab应包括:
::sysinit:/etc/rc.d/rc.sysinit
::sysinit:/bin/sh
(注意,这里如果用getty或minigetty代替sh,那么shell就会等待用户登录,
而不会直接进入shell。)
rc.d/rc.sysinit应包括:
/bin/mount
–a
5、 添加bin、sbin、usr/bin、usr/sbin下的可执行文件
系统至少应该包含工具sh, ls, cp,
mv,init。我们可以将/bin /sbin /usr/bin /usr/sbin
下的对应工具拷贝过来,拷贝的时候采用cp
–dfR。系统中的可执行文件一般都比较大,
在内存或磁盘空间紧张的情况下不适合,我们可以用BusyBox来解决这个问题。BusyBox
包含了
七十多种 Linux 上标准的工具程序,仅需要几百 k
磁盘空间,在嵌入式系统上常用到它。下载了
BusyBox的源代码包后可以按照如下的步骤操作:
DOSTATIC=true
然后修改
BusyBox 中的 init.c,设定系统要执行的第一个程序为: /etc/rc.d/rc.sysinit
#define
INIT_SRCIPT
"/etc/rc.d/rc.sysinit"
开始编译BusyBox
#make
#make
install
到这一步我们就得到了可执行命令busybox
将busybox 复制到/mnt/initrd/bin目录下
# cp
busybox
/mnt/initrd/bin
然后创建常用命令的link,具体的工作原理请参阅busybox的官方说明。
我们可以使用
./busybox
--help 来查看busybox中都有哪些工具。常用的工具及busybox
的用法如下:
# ln -s
busybox ls
# ln
-s busybox cp
# ln -s busybox mount
# ln -s
busybox umount
# ln -s
busybox more
# ln -s busybox ps
# ln -s
busybox sh
现在我们就有了所需的常用命令。
6、
添加库到lib下
该目录中包含有你的启动盘启动过程中所需要的共享函数库,如果缺少必须的函数库,
系统会停止启动或出现一大堆错误信息,所以一定要注意。
几乎所有的程序都需要libc库,列一下目录/lib中的libc:
ls -l /lib/libc*
-rwxr-xr-x 1 root root 4016683 Apr 16 18:48
libc-2.1.1.so*
lrwxrwxrwx 1 root root 13 Apr 10 12:25 libc.so.6 ->
libc-2.1.1.so*
libc.so.6的6表示版本号,它指向的文件才是你真正需要的。
查看/bin /sbin
/usr/bin
/sur/sbin下每一个程序使用的函数库,用命令ldd,
如:
ldd
/sbin/mke2fs
libext2fs.so.2
=> /lib/libext2fs.so.2
(0x40014000)
libcom_err.so.2 =>
/lib/libcom_err.so.2
(0x40026000)
libuuid.so.1 => /lib/libuuid.so.1
(0x40028000)
libc.so.6 => /lib/libc.so.6
(0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2
(0x40000000)
输出右边的库都是必须的,有的可能是链接文件。
在/lib目录下你还必须有函数库装载器,这个装载器或是ld.so
(对
a.out 库) 或是
ld-linux.so (对 ELF 库)。新版本的ldd一般会告诉你所需库的装载器。
7、
加载模块
如果你有一个模块化的内核,你还得考虑需要加载的模块,它们都位于/lib/modules 下
cp –dfR
/lib/modules/x.y.z /mnt/initrd/lib/modules
8、 打包
# cd /tmp
#
umount
/mnt/initrd
# gzip -9
initrd
最终产生的文件initrd.gz就是压缩过的根文件系统
9、
修改已经存在的根文件系统
# gunzip
initrd.zip
# mount -o loop /tmp/initrd
/mnt/initrd
# 用户修改根文件系统
#
umount /mnt/initrd
# gzip -9
initrd
..................................
补:
文件系统中存放是的操作系统需要的应用程序!在操作系统内核加载到内存中时,内核会选择调用文件系统的应用程序开启整个操作系统。因此应用程序工作在内核之上。内核负责根文件系统的安装,这样才能实现文件系统中的应用程序的调用。
内核是所有Linux系统软件组成的核心,文件系统时按目录组织的,一个文件系统下有多个顶层目录,每个目录有其特殊的用法和目的。根目录下包含很多顶层目录
bin
必要的用户命令(二进制文件)
boot bootloader使用的静态文件
dev 设备文件和其他特殊文件
etc
系统配置文件,包括启动文件
home 用户主目录
lib 必要的链接库
mnt mount点,用于暂时安装文件系统
opt
附加的软件套件
proc 提供内核与进程信息的虚拟文件系统
root root用户主目录
sbin
必要的系统管理员命令(二进制文件)
tmp 临时文件
usr 在第二层中包含大量的用户应用程序和文件
var
监控程序和工具程序所存放的可变数据
建立根文件系统(1)
设置根文件系统的目录骨架:
建立根目录和顶层目录,命令:
mkdir
rootfs
cd
rootfs
mkdir bin dev etc lib proc sbin tmp usr
var
chmod 1777 tmp
//为tmp目录的使用权打开sticky位,确保/tmp下建立的文件只有建立它 的用户有权
//删除
建立/usr的目录结构
mkdir usr/bin usr/lib
usr/sbin
建立/var的目录结构
mkdir
var/lib var/lock var/log var/run
var/tmp
chmod 1777 var/tmp
根文件系统上的内容包括:
链接库
//用于在程序开发式提供链接
内核模块
内核映像
//用于启动的内核映像一般放在/boot目录下
设备文件
///dev
系统应用程序
//bin
……
准备内核模块和内核映像
为目标系统准备内核模块
如果已经建立好内核模块,就将它们复制到目标板的/lib目录里
为目标系统准备内核映像
这与引导加载程序的能力和配置有关
如果设置成从根文件系统启动内核,就要将内核映像复制到目标板的根文件系统的/boot目录下
为目标系统建立设备文件
在Linux根文件系统中,所有的设备文件都放在/dev目录里
下面列出了一些基本的/dev条目
文件名
说明 类型 主编号 次编号 权限位
mem 物理内存存取 字符 1 1 600
null null设备 字符 1 3
666
zero 以0值字节为数据来源 字符 1 5 666
random 真随机数产生器 字符 1 8 644
tty0
当前的虚拟控制台 字符 4 0 600
tty1 第一个虚拟控制台 字符 4 1 600
ttyS0 第一个UART串行端口 字符 4 64
600
tty 当前的tty设备 字符 5 0 666
console 系统控制台 字符 5 1
600
可以使用如下的命令建立上表中的几个条目(需要root权限)
mknod
–m 600 mem c 1 1
mknod –m
666 null c 1
3
……
此外,/dev目录下还包含若干必要的符号链接,如
fd?/proc/self/fd
stdin->fd/0
stdout->fd/1
stderr->fd/2
可以看一下,用过的romfs的dev目录
主要的应用程序,3个有用的套件
BusyBox
TinyLogin
Embutils
BusyBox目前由Erik
Andersen来维护
它把许多常见应用程序缩微版本组合到一个单独的小巧的可执行程序中,一般含有比较少的选项,更小的体积,不
过所包含的这些 选项能够提供用户所需要的大部分功能。能够为任何一个小型或嵌入式系统提供一个相当完整的 环境
提供相当程度的模块化功能,很容易为目标板定制
TinyLogin
TinyLogin将许多登录工具放在单个二进制文件中,通常会与BusyBox并用,两者由相同的开发者维护
TinyLogin中的大多数命令要使用root权限执行
Embutils
这是针对主流Unix命令提供的一组经过简化和优化的替代品。目前支持ARM、i386、PPC和MIPS
其维护者与diet
libc相同,只能静态链接diet libc
定制应用程序
自己的应用程序也要放在根文件系统的某个目录下,这取决于应用程序所拥有的组件数量和类型
如果二进制文件较少,可以考虑放到/bin目录下
如果二进制文件多且复杂并且包含一些数据文件,最好在根文件系统中增加一个单独的目录,例如/project
第二种情况下,通常需要设置PATH环境变量,以便能够找到可执行文件(如果不设置的话,一种替代方案就是在命 令行下输入绝对路径以指明命令所在的目录)
选择根文件系统的依据
描绘一个嵌入式文件系统的特性通常包括:
可被写入:这个文件系统可被写入么?
具有永久性:重引导后,这个文件系统可以保存修改过的内容么?
具有断电可靠性:经变动的文件系统可以在断电之后恢复过来么?
经过压缩:经安装的文件系统,其内容经过压缩么?
存在RAM中:文件系统的内容在被安装之前会先从存储设备取出并放到RAM中么?
文件系统 可被写入 具有永久性
具有断电可靠性
经过压缩 存在于RAM中
CRAMFS 否 不适用 不适用 是 否
JFFS2 是 是 是 是 否
JFFS 是 是 是 否 否
NFTL上的Ext2
是 是 否 否 否
NFTL上的Ext3 是 是 是 否 否
RAM
disk上的Ext2
是 否 否 否 是
CRAMFS 这是Linux
Torvalds编写的只具备最基本特性的文件系统,它非常简单、经过压缩并且只读,主要用于嵌入式系统,具有以下限制:
每个文件最大不超过16MB
不提供当前目录“.”和上级目录“..”
文件的UID字段只有16位,GID字段只有8位
所有文件的时间戳为Unix
epoch(00:00:00 GMT, January 1,
1970)
内存分页大小必须是4096
文件链接计数器永远是1
要为根文件系统建立CRAMFS映像,首先要建立并安装CRAMFS工具:cramfsck和mkcramfs
可以在内核源代码树的scripts/cramfs目录里找到他们的程序代码,在该目录下使用make就可以建立这两个工具
使用mkcramfs命令建立CRAMFS映像:
Mkcramfs
根文件系统的根目录 映像名
RAMdisk
RAMdisk存在于RAM中,其存取功能类似块设备
内核可以在同一时间支持多个活动的RAMdisk
在RAMdisk上可以使用任何磁盘文件系统
RAMdisk通常会从经压缩的磁盘文件系统(例如ext2)加载其内容,因此内核必须具备从存储设备取出initrd(initial
RAM
disk)映像作为它的根文件系统的能力。
启动时,内核会确认引导选项是否指示有initrd的存在,如果有就会从所选定的存储设备取出文件系统映像放入RAM
disk,并且将它安装成根文件系统
建立供RAM disk使用的文件系统映像
1、为根文件系统建立一个空的文件系统映像
//相当于在windows下作格式化一个盘,用来存放满足这种格式的文件
mkdir tmp/initrd
dd
if=/dev/zero
of=images/initrd.img bs=1k
count=8192
//以dd命令建立一个8192KB的文件系统映像,并以/dev/zero对它进行初始化
对建立好的文件系统映像建立文件系统并且安装(需要root权限)
/sbin/mke2fs
–F –v –m0
images/initrd.img
-F选项指定对mke3fs在文件上运行而不是块设备
-v选项以verbose模式运行
-m0指出不必为超级用户保留任何区块
mount
–o loop images/initrd.img tmp/initrd
复制根文件系统到RAM disk并且卸载
cp –av
根文件系统目录/*
tmp/initrd //这里的根文件系统由系统的建设者生成,实质是创建了一些顶层目录并将对
//应目录中(按照系统要求)必须的文件放入其中
umount
tmp/initrd
现在images/initrd.img文件中已经包含了目标板的整个根文件系统
最后形成经压缩的RAM
disk
gzip
-9 images/initrd.bin
-9表示最高级的压缩算法
阅读(2753) | 评论(0) | 转发(0) |