一、文件系统介绍
文件系统:是操作系统用于明确磁盘或分区上的文件的方法和数据结构,即在磁盘上组织文件的方法。Linux文件系统是一个完整的统一体,组织到一个树形目录结构中。
Linux遵守文件系统科学分类标准(FHS),一个定义许多文件和目录的名字和位置的标准。
主要规则如下:
配置文件放在/etc目录下
设备文件放在/dev目录下
库文件放在目录/lib目录下
存放系统编译后的可执行文件、命令的目录是/bin、/sbin、/usr/bin、/usr/sbin目录
在嵌入式系统中,根目录下的很多目录都可以删除,如下:
为多用户提供可扩展环境的所有目录都应该删除;如(/home,/mnt,/root)
根据引导加载情况,/boot目录可以删除。
其余的目录
/bin,/dev,/etc,/proc,/sbin,/usr,/lib都是不可缺少的。
二、BusyBox介绍
从名字上直接理解,Busybox是一个“繁忙的盒子”,其实,Busybox可以理解为一个Linux的命令集合,我们在进行Linux操作时所需要的 常用命令,都可以在Busybox里找到,但Busybox又不是简单的将所有的命令集合在一起,它采用了一种非常巧妙的方式,即“使用一个程序完成所有 的事”。
平时我们用ls、vi等命令,都要用到glibc的相关调用,所以如果每个命令都静态链接这些调用,每个命令都会很大,因此在通常的发行版中,都会动态链 接glibc,可是glibc的动态库本身就很大,这在PC+Linux平时上还可以接受,但在嵌入式系统中,这就太大了,而且又不是所有的库函数都使 用。
一般采用两种解决办法,一种是裁剪glibc,另一种就是Busybox的办法,即把ls、vi等程序的main函数改一下名,全部链接在一起,然后静态 链接glibc,这样,只有需要的调用才会链接进来,整个Busybox程序可能都比glibc的动态库小。
因此,Busybox的工作原理是根据文件名来决定用户想调用的是那个程序,例如,如果你的busybox程序的文件名是ls,运行的就是ls,是vi,就运行vi。
下面介绍一下ARM-Linux平台的Busybox-1.00交叉编译与使用步骤:
将文件busybox-1.00.tar.gz拷贝到Linux目录,执行如下命令解压文件:
#tar xzvf AT91RM9200-busybox-1.00.tar.gz
当文件解压完成以后,会自动生成busybox-1.00目录,进入该目录,并执行如下命令进行编译:
#make clean ;清除旧的编译文件
#make menuconfig 在这里修改一些必要的选项
#make ARCH=arm CROSS_COMPILE=arm-linux- CONFIG_PREFIX=/root/build_rootfs/rootfs all install
busybox是一个集成了一百多个最常用linux命令和工具的软件,它甚至还集成了一个http服务器和一个telnet服务器,而所有这一切功能却只有区区1M左右的大小.我们平时用的那些linux命令就好比是分力式的电子元件,而busybox就好比是一个集成电路,把常用的工具和命令集成压缩在一个可执行文件里,功能基本不变,而大小却小很多倍,在嵌入式linux应用中,busybox有非常广的应用。
Busybox 提供的程序包括:
具有shell功能,如csh
提供一个迷你的vi编辑器
提供系统不可或缺的/sbin/init程序
其他的系统基本命令,如:ls,mkdir,ifconfig等。
三丶Linux 文件系统构建步骤
3.1.1下载busybox
可以从 http://busybox.net/downloads/下载busybox源码。
3.1.2解压源码
$ tar xvf busybox-1.22.1.tar.bz2
$ cd busybox-1.22.1
3.1.3配置 busybox 源码
$ make menuconfig
Busybox Settings —>
Build Options —>
[*] Build BusyBox as a static binary (no shared libs)
[ ] Force NOMMU build
[ ] Build with Large File Support (for accessing files > 2 GB)
(arm-none-linux-gnueabi-) Cross Compiler prefix
() Additional CFLAGS
3.1.4编译源码
$ make
3.1.5安装根文件系统
busybox 默认安装路径为源码目录下的_install
$ make install
进入安装目录:
$ cd _install
$ ls
bin linuxrc sbin usr
创建其他需要的目录:
$ mkdir dev etc mnt proc var tmp sys root
添加库:
将工具链中的库拷贝到_install 目录下:
$ cp /home/linux/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/ ./_install/ -a
删除静态库和共享库文件中的符号表:
$ sudo rm lib/*.a
# arm-none-linux-gnueabi-strip lib/*.so (超级用户下执行命令)
删除不需要的库,确保所有库大小不超过 4M:
$ du -mh lib/
添加系统启动文件:
在 etc 下添加文件 inittab,文件内容如下:
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh
# stuff to do when restarting the init process
::restart:/sbin/init
# stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
在 etc 下添加文件 fstab ,文件内容如下:
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
这里我们挂载的文件系统有三个 proc、 sysfs 和 tmpfs 。在内核中 proc 和 sysfs 默认都支持,而 tmpfs
是没有支持的,我们需要添加 tmpfs 的支持
修改 Linux 内核配置;
$ cd ~/ kernel/linux-3.14
$ make menuconfig
File systems —>
Pseudo filesystems —>
[] Virtual memory file system support (former shm fs)
[] Tmpfs POSIX Access Control Lists
重新编译内核:
$ make uImage
$ cp arch/arm/boot/uImage /tftpboot
回到创建的文件系统处, 在 etc 下创建 init.d 目录,并在 init.d 下创建 rcS 文件, rcS 文件内容为:
#!/bin/sh
# This is the first script called by init process
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
为 rcS 添加可执行权限:
$ chmod +x init.d/rcS
在 etc 下添加 profile 文件,文件内容为:
#!/bin/sh
export HOSTNAME=Exynos4412
export USER=root
export HOME=/root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
重要:新制作的文件系统尺寸若超出 8M,删除不需要的库文件
3.2NFS 测试
3.2.1将我们新建的根文件系统拷贝到/source/rootfs 目录下
$sudo mkdir /opt/rootfs
$sudo cp _install/* /opt/rootfs –a
3.2.2设置uboot参数
#setenv bootargs noinitrd root=/dev/nfs nfsroot=192.168.13.116:/opt/rootfs init=/linuxrc console=ttySAC2,115200 ip=192.168.13.123
3.2.3实验现象
Nfs根文件系统挂载成功
3.3Ramdisk 文件系统制作实验
3.3.1制作一个大小为 8M 的镜像文件
$ cd ~
$ dd if=/dev/zero of=ramdisk bs=1k count=8192 ( ramdisk 为 8M)
3.3.2格式化这个镜像文件为 ext2
$ mkfs.ext2 -F ramdisk
3.3.3在 mount 下面创建 initrd 目录作为挂载点
$ sudo mkdir /mnt/initrd
3.3.4将这个磁盘镜像文件挂载到/mnt/initrd 下
注意这里的 ramsidk 不能存放在 rootfs 目录中
$ sudo mount -t ext2 -o loop ramdisk /mnt/initrd
3.3.5将我们的文件系统复制到 initrd.img 中
将测试好的文件系统里的内容全部拷贝到 /mnt/initrd 目录下面
$ sudo cp /source/rootfs/* /mnt/initrd –a
3.3.6卸载 initrd
$ sudo umount /mnt/initrd
3.3.7压缩 initrd.img 为 initrd.img.gz 并拷贝到/tftpboot 下
$ gzip --best -c ramdisk > ramdisk.gz
3.3.8格式化为 uboot 识别的格式
$ mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
$ cp ramdisk.img /tftpboot
3.3.9配置内核支持 RAMDISK
制作完 ramdisk.img 后,需要配置内核支持 RAMDISK 作为启动文件系统, 修改内核配置
$ make menuconfig
File systems —>
<> Second extended fs support
Device Drivers
SCSI device support —>
<> SCSI disk support
Block devices —>
<>RAM block device support
(16)Default number of RAM disks
(8192) Default RAM disk size (kbytes) (修改为 8M)
General setup —>
[] Initial RAM filesystem and RAM disk (initramfs/initrd) support
3.3.10重新编译内核
复制到uImage到 /tftpboot目录下
$cp arch/arm/boot/uImage /tftpboot
3.3.11重新设置uboot启动参数:
# setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-etc4412.dtb\; tftp 43000000 ramdisk.img\; bootm 41000000 43000000 42000000
# saveenv
四丶文件系统挂载
pc的设置
安装NFS
apt-get install nfs-kernel-server
配置NFS
# gedit /etc/exports
替换成如下内容:
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/opt/rootfs *(rw,sync,no_root_squash)
重启NFS服务
# /etc/init.d/nfs-kernel-server restart
[ ok ] Starting nfs-kernel-server (via systemctl): nfs-kernel-server.service
测试
# showmount -e
Export list for ubuntu:
/opt/fs/rootfs/rootfs *
开发板的设置
etc4412# setenv bootargs noinitrd root=/dev/nfs nfsroot=192.168.13.79:/opt/rootfs/ rw init=/linuxrc console=ttySAC2,115200 ip=192.168.13.100
etc4412# saveenv
noinitrd:必须配置,否则还是进入内存文件系统。