文章目录
1,根文件系统基本概念
1.1,什么是根文件系统?
- 根文件系统(root filesystem)是存放运行、维护系统所必须的各种工具软件、库文件、脚本、配置文件和其他特殊文件的地方,也可以安装各种软件包。
- 整个系统起来之后运行的第一个文件系统
- 根文件系统下还可以搭建其他的文件系统
1.2,根文件系统主要目录结构
1.3,程序文件的放置
程序文件目录
/bin: 普通用户和root用户都能执行的基本程序
ping, mknod, mount, tar, grep, gzip, etc
/sbin: root用户能执行的基本程序
int, insmod, route, mkfs, rmmod, ifconfig
/usr/bin: 更多非必须的用户程序
autorun, bibtex, latex, biff, ftp, wc, whereis, whoami
/usr/sbin: 更多非必须的root工具程序
automount, httpd, in.telnetd, in.talkd, sendmail
1.4,定制应用程序
- 配置基本的linux命令(嵌入式linux通过busybox制作)
cat, chmod, chown, cp, chroot, copi, date, dd, df, dmesg, dos2unix, du, echo, env, expr, find, grep, gunzip, gzip, halt, id, ifconfig, init, insmod等等
- 配置用户自己的应用
桌面管理器等等
1.5,库文件的放置
/lib: 系统和运行基本命令时需要的动态库文件
/usr/lib:所有的其他库
/usr/lib/xxx: 一些工具包的私有库
如:/usr/lib/perl5
2,Linux 设备文件
- Linux 系统中所有的对象(包括设备)都是以文件的形式体现的
- Linux系统中,所有的设备文件(如:设备节点),通常放到
/dev
下 - 嵌入式系统中只需要创建必须的设备节点即可
2.1,举例
2.1.1,字符设备举例
ls –l /dev/
“c” 指明该设备节点是字符设备
crw-rw---- 1 root uucp 4, 64 Feb 23 2004 /dev/ttyS0 //4表示主设备号,64表示次设备号
crw--w---- 1 jdoe tty 136, 1 Feb 23 2004 /dev/pts/1
crw-------- 1 root root 13, 32 Feb 23 2004 /dev/input/mouse0
crw-rw-rw 1 root root 1, 3 Feb 23 2004 /dev/null
典型设备
keyboards, mice, parallel port, IrDA, Bluetooth port, consoles, terminals, sound, video...
2.1.2,块设备举例
“b” 指明该设备节点是块设备 (ls -l)
brw-rw--- 1 root disk 3, 1 Feb 23 2004 hda1
brw-rw--- 1 jdoe floppy 2, 0 Feb 23 2004 fd0
brw-rw--- 1 root disk 7, 0 Feb 23 2004 loop0
brw-rw--- 1 root disk 1, 1 Feb 23 2004 ram1
brw------- 1 root root 8, 1 Feb 23 2004 sda1
典型块设备
磁盘, ramdisk,SD,U盘等等
2.2,设备的主设备号次设备号
- Linux系统是通过主设备号和次设备号来区分设备的
- 主设备号: (major)
内核用来区分哪类设备 - 次设备号: (minor)
区分某类设备中的哪个设备 - 内核中的相关文档 Documentation/devices.txt
2.3,创建设备节点
- 设备文件不能在加载驱动程序时自动创建,要通过指令创建
- 创建设备文件的一般语法:
$ mknod /dev/<device> [c|b] <major> <minor>
- 例如:
$ mknod /dev/ttySAC0 c 4 64
$ mknod /dev/hda1 b 3 1
2.3.1,基本的设备节点
2.4,Linux系统的引导过程
3,制作根文件系统
3.1,文件系统制作步骤
- 制作根文件系统的内容
采用Busybox创建基本命令
创建基本的目录/lib /etc /var /tmp /dev /sys /proc
等
添加glibc基本动态库
创建基本的设备节点
添加启动配置和脚本程序/etc/inittab /etc/fstab /etc/init.d/rcS
- 测试rootfs内容正确性
- 制作需要的rootfs类型的格式
3.1.1,BusyBox项目构建系统命令
- BusyBox 项目是由Bruce Perens in 在1996创建的
http://www.busybox.net/
BusyBox 是在 GNU GPL 许可协议下发行的开源软件 - 享有“嵌入式Linux的瑞士军刀”美誉,Erik Andersen先生维护;
- Busybox是一个UNIX系统工具集,它将很多普通的UNIX工具集成到一个很小的可执行文件中,为普通用户提供大多数常用的命令;
- BusyBox常用于制作linux命令 主要指令包括
cat, chmod, chown, cp, chroot, copi, date, dd, df, dmesg, dos2unix, du, echo, env, expr, find, grep, gunzip, gzip, halt, id, ifconfig, init, insmod, etc
3.1.2,BusyBox工具安装
linux@linux:~$ cp /mnt/hgfs/Linuxsharexiaomei/busybox-1.22.1.tar.bz2 .
linux@linux:~$ tar -vxf busybox-1.22.1.tar.bz2
linux@linux:~$ cd busybox-1.22.1/
3.2,制作根文件系统的内容
$ make menuconfig
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
(arm-none-linux-gnueabi-) Cross Compiler prefix 注意 一定要指定交叉编译工具
$ make
$ file busybox 确认编译生成的是 ARM 平台的(显示为ELF 32-bit LSB executable, ARM)
$ make install 安装(默认安装路径为_install)
$ cd _install
$ ls
bin linuxrc sbin usr
$ mkdir dev etc mnt proc var tmp sys root 创建需要的目录
$ cp ~/store/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/ . -a 注意是lib/
$ du -mh lib 查看lib库的大小
$ rm lib/*.a 裁剪,删除掉静态库文件
$ arm-none-linux-gnueabi-strip lib 裁剪掉调试信息 not recognized 有些库是不能strip的 忽略掉
$ sudo rm lib/libstdc++* 删除不需要的库,确保所有库大小不超过4M
$ du -mh lib 查看lib库的大小 可能 显示3.4M lib (这里确保小于 8M)
$ cp /nfs/rootfs/etc -rf . 拷入成熟的参考配置
$sudo mknod dev/console c 5 1 必须要有 console设备节点
3.2.1,测试
看新的根文件系统能否正常挂载到开发板
linux@linux:~/busybox-1.22.1$ mv /nfs/rootfs /nfs/rootfs.ok 把原有的根文件系统备份一下
linux@linux:~/busybox-1.22.1$ sudo cp -rf _install /nfs/rootfs 把新的根文件系统拷贝过去(改名rootfs)
挂载成功
3.3,配置文件一
3.3.1,文件 /etc/inittab
#this is run first except when booting in single-user mode.
:: sysinit:/etc/init.d/rcS 指定系统初始化脚本是rcS 也可指定别的名字,但习惯用rcS
# /bin/sh invocations on selected ttys
# start an "askfirst" shell on the console (whatever that may be)
::askfirst:-/bin/sh 指定初始的控制台(启动后进入# 状态)
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
3.3.2,文件 /etc/init.d/rcS(启动脚本)
#!/bin/sh
# This is the first script called by init process
/bin/mount -a mount all stuff from /etc/fstab
/etc/init.d/rc.local 扩展子脚本
echo /sbin/mdev > /proc/sys/kernel/hotplug 设置系统的hotplug程序为mdev
/sbin/mdev -s
./app.exe //让脚本自动运行你的程序
3.4,配置文件二
3.4.1,文件 /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
3.4.2,文件 /etc/profile
#!/bin/sh
export HOSTNAME=farsight
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
3.5,测试rootfs内容正确性
$ cd /nfs
$ mkdir rootfs
$ cp _install/* rootfs –a
$ chmod 777 /nfs/rootfs/
NFS能挂载成功表示根文件系统 内容基本正确
3.6,制作需要的rootfs类型的格式
- 根文件系统是存储数据的仓库,应用程序和第三方库都在根文件系统中,根文件系统最终要做成镜像,放在设备上面
- 不同设备有不同特点,比如有的设备只有内存,有的有flash,有的有硬盘,不同的硬件机械特性不一样
- 针对不统计硬件,为了提升其访问效率,就制定了不同的根文件系统
- Nand flash存取数据是按块设备访问的(存储空加大,便宜)
Nor flash存取数据是按字节访问的,BootLoader可以直接在Nor flash上运行(存储空间小,贵)
3.6.1,不同根文件系统详解
3.6.1.1,nfs rootfs
是网络文件文件系统,通过网线远程挂载一个文件系统,文件系统在远程的电脑上。最大的好处是同步,主要用于开发调试
3.6.1.2,CRAMFS
只读,不能写。安全性高,某些区域的数据不能改,就可以定义为CRAMFS。
3.6.1.3,JFFS2和YAFFS2
可读,可写,针对都是flash。JFFS2在小型应用系统用的比较多。JFFS2有一个特点:是一个日志文件系统,用的过程中可以随时掉电。YAFFS2只能针对Nand flash,手机中用的最多的是Nand flash,文件系统就是YAFFS2
3.6.1.4,EXT2 over RAM disk
把一块内存虚拟成为一个磁盘。内存只能按地址空间像一个buffer一样访问,当应用产品内存比较大而flash比较小时,就可以按这种格式把一块内存虚拟成为一个磁盘
3.6.2,制做EXT2 over RAM disk文件系统
3.6.2.1,制作一个大小为8M的镜像
linux@linux:~$ dd if=/dev/zero of=ramdisk bs=1k count=8192
if
:(input file)输入文件/dev/zero
:是一个虚拟的设备,从这个设备中读到的数据全是0of
:(output file)输出文件bs=1k count=8192
: 单元大小是1k,数量是8k,就是8M大小
3.6.2.2,格式化这个镜像为EXT2
linux@linux:~$ mkfs.ext2 -F ramdisk
3.6.2.3,在mount下面创建initrd目录作为挂载点
linux@linux:~$ sudo mkdir /mnt/initrd
3.6.2.4,将这个磁盘镜像文件挂载到/mnt/initrd下
注意这里的ramdisk不能存放在rootfs目录中
linux@linux:~$ sudo mount -t ext2 ramdisk /mnt/initrd
3.6.2.5,将我们的文件系统复制到ramdisk中
将测试好的文件系统里的内容全部拷贝到/mnt/initrd
目录下面
linux@linux:~$ sudo cp /nfs/rootfs/* /mnt/initrd/ -a
3.6.2.6,卸载initrd
linux@linux:~$ sudo umount /mnt/initrd
3.6.2.7,压缩ramdisk为ramdisk.gz并拷贝到/tftpboot下
linux@linux:~$ gzip --best -c ramdisk > ramdisk.gz
3.6.2.8,格式化为uboot识别的格式,并拷贝到/tftpboot下
linux@linux:~$ mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
linux@linux:~$ cp ramdisk.img /tftpboot/
3.6.2.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
重新编译内核,复制到/tftpboot
3.6.2.10,在U-BOOT命令行重新设置启动参数
3.6.2.11,开发板上电重启,看是否成功