有道云笔记地址:
详情看这里链接,记录太多,就不一一排版了。
一、Linux 文件系统简介
根,可以理解为基础的意思。根文件系统是一种最基础的文件系统。
我们知道在 Windows 系统下,磁盘被划分为 C、 D、 E 等各个盘,
同理, Linux 系统也可以将磁盘或 Flash 等存储设备划分为若干个分区,在不同的分区存放不同类型的 文件,比如我们 A8 开发板的 Nor Flash 中:在某个分区存放 uboot 的可执行文件;在某个分区存放内核映像文件,在另一分区存放根文件系统映像文件等。与 Windows 的 C 盘类似, Linux 也需要在一个分区上存放系统启动的必要文件,
比如内核启动运行后的第一个程序( init进程)、用于挂接文件系统的脚本、给用户提供操作界面的 shell 程序,应用程序所要依赖的库等,这些必要、基本文件的集合称为根文件系统,它们存放在一个分区中。
Linux 系统启动后首先会挂载这个分区,这称为挂载( mount)根文件系统。
其他分区上的所有目录、文件的集合, 称为文件系统。因为其他的文件系统还没用到,所以在我们的 A8 开发板中只有根文件系统。
为什么需要根文件系统? |
(4)shell命令程序在根文件系统上。譬如ls、cd等命令
总结:一套linux体系,只有内核本身是不能工作的,必须要rootfs(上的etc目录下的配置文件、/bin /sbin等目录下的shell命令,还有/lib目录下的库文件等···)相配合才能工作。
在嵌入式Linux应用中,主要的存储设备为 RAM(DRAM, SDRAM)和ROM(常采用FLASH存储器),
常用的基于存储设备的文件系统类型包括:jffs2, yaffs, cramfs, romfs, ramdisk, ramfs/tmpfs等。
二、Linux根文件系统目录结构
从前面的讲解,我们知道文件系统是一个文件与目录的集合,那么根文件系统下的目录又有哪些呢?目录里的文件又有什么作用呢?这节提及的目录都是我们待会移植根文件系统时要用到的目录,为你在移植前先热热身。
(1) /bin 目录 该目录下存放所有用户(包括系统管理员和一般用户)都可以使用的、基本 的命令,里面常用的命令有: ls、 cd、 mkdir、 rm、 kill、 ps、 cp、 mv、 cat、 chmod 等。
(2) /sbin 目录 该目录下存放系统命令,即只有管理员能够使用的命令,系统命令还可以存 放/usr/sbin、/usr/local/sbin 目录下。/sbin 目录中存放的是基本的系统命令, 它们用于启动系统、修复系统等。它里面常用的命令有: shutdown、reboot、fdisk、 fsck 等。不是急迫需要使用的系统命令存放在/usr/sbin 目录下。
(3) /dev 目录 该目录下存放的是设备文件。设备文件是 Linux 中特有的文件类型,在 Linux 系统下,以文件的方式访问各种外设,即通过读写某个设备文件操作某个具体硬件。比如通过“ /dev/ttySAC0”文件可以操作串口 0,通过“ /dev/mtdblock0” 可以访问 MTD 设备( Nand Flash)的第 0 个分区。
设备文件有两种:字符设备文件和块设备文件。在 PC 上用命令:
ls -l /dev/tty0 /dev/hdc |
其中字母“ b”、“ c”表示这是一个块设备文件或字符设备文件;“ 22, 0”、“ 4, 0”表示设备文件的主、次设备号;主设备号用来表示这是哪类设备,次设备号 用来表示这是这类设备中的哪个。
(4) /etc 目录 该目录下存放各种配置文件。对于 PC 机上的 Linux 系统, /etc 里的目录和 文件非常多。这些目录、文件都是可选的,它们依赖于系统中所拥有的应用程序, 依赖于这些程序是否需要配置文件。
(5) /lib 目录 该目录主要存放共享库,共享库用于启动系统、运行根文件系统中的可执行 程序,比如/bin、 /sbin 目录下的程序。
(6) /proc 目录 在内核启动之前,这是一个空目录,常作为 proc 文件系统的挂载点。 proc 文件系统是个虚拟的文件系统,它没有实际的存储设备,在内核启动之后, /proc 目录里面的目录、文件都是由内核临时生成的,用来表示系统的运行状态,也可以操作其中的文件来控制系统。
(7) /tmp 目录 用于存放临时文件,通常是空目录。一些需要生成临时文件的程序要用到 /tmp 目录,所以/tmp 目录必须存在并可以访问。
三、制作ext3格式的根文件系统
(1)mke2fs是一个应用程序,在ubuntu中默认是安装了的。这个应用程序就是用来制作ext2、ext3、ext4等格式的根文件系统的。
(2)一般用来制作各种不同格式的rootfs的应用程序的名字都很相似,类似于mkfs.xxx(譬如用来制作ext2格式的rootfs的工具叫mkfs.ext2、用来制作jffs2格式的rootfs的工具就叫mkfs.jffs2)
(3)ubuntu14.04中的mkfs.ext2等都是mke2fs的符号链接而已。
(1)创建rootfs.ext2文件并且将之挂载到一个目录下方便访问它
参考资料:http://blog.csdn.net/zhengmeifu/article/details/24174513
我们选择的是在这个目录下创建 porting_x210/rootfs,使用如下命令
dd if=/dev/zero of=rootfs.ext2 bs=1024 count=2048 |
losetup /dev/loop1 rootfs.ext2 |
mke2fs -m 0 /dev/loop1 2048 |
mount -t ext2 /dev/loop1 ./rootfs/ (在当前的目录下需要创建一个rootfs文件这句命令才能正确执行) |
消除错误影响:(如果执行上面用的ext3格式,这里想要制作ext2,就用下面这两句命令消除之前的影响)
(2)我们向镜像中写入一个普通文件linuxrc(包括下面的nfs挂载实验,都是一个没有任何作用的linuxrc文件,所以,挂载后肯定提示linuxrc失败。)
这个文件就会成为我们制作的镜像中的/linuxrc。内核挂载了这个镜像后就会尝试去执行/linuxrc。然后执行时必然会失败。我们将来实验看到的现象就应该是:挂载成功,执行/linuxrc失败。
(3)将来真正去做有用的rootfs时,就要在这一步添加真正可以执行的linuxrc程序,然后还要添加别的/lib目录下的库文件,/etc目录下的配置文件等。
当卸载了之后,进入rootfs/就什么都看不到了,因为里面的东西就已经拿走了
将制作的rootfs.ext2文件拷贝到windows共享文件下进行下面的烧录
(遇到的问题:必须使用210的uboot,即重新烧录/bsp/uboot/目录下的uboot到sd卡,因为尝试使用我们移植的uboot,执行下面的刷机过程,都会出现报错:remote: failed to flash partition,即Flash分区失败;使用210的原版uboot,则不会出现这种问题)
(1)烧录过程参考裸机中第三部分的刷机过程。注意bootargs传参设置
> fastboot flash system rootfs.ext2
(2)实验现象,通过tftp烧录zImage,查看内核启动信息
(遇到的问题:这里的内核一定要是/bsp/kernel下的原版zImage,其他版本的zImage下载进去,都会挂载失败。)
在/bsp/kernel下使用命令:cp arch/arm/boot/zImage /tftpboot/ -f
挂载成功,执行/linuxrc失败。很预期一样的现象,说明我们挂载成功。
四、nfs方式启动自制简易文件夹形式的rootfs
(2)nfs的作用。利用nfs协议可以做出很多直接性应用,我们这里使用nfs主要是做rootfs挂载。
开发板中运行kernel做nfs客户端,主机ubuntu中搭建nfs服务器。在主机ubuntu的nfs服务器中导出我们制作的文件夹形式的rootfs目录,则在客户端中就可以去挂载这个文件夹形式的rootfs进而去启动系统。
/root/porting_x210/rootfs/rootfs *(rw,sync,no_root_squash,no_subtree_check) |
chmod -R 777 /root/porting_x210/rootfs/rootfs |
sudo showmount localhost -e //导出本地nfs目录 |
sudo /etc/init.d/nfs-kernel-server restart //重启 nfs 服务 |
mount -t nfs -o nolock 192.168.1.141:/root/porting_x210/rootfs/rootfs /opt |
//这样就把rootfs文件夹 以 NFS的方式挂载到了/opt下。
//注意最好不要挂载在/mnt目录下。最好在opt或者tmp下
在opt目录下创建ab文件,在/root/porting_x210/rootfs/rootfs文件夹下也看见有这个ab,说明挂载成功。
//nfsroot=192.168.1.141:/root/s3c2440/build_rootfs/aston_rootfs
(故我们的主机目录是:/root/porting_x210/rootfs/rootfs)
//ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off
开发板ip: 主机ip : 网关 : 子网掩码:主机网卡:off
setenv bootargs root=/dev/nfs nfsroot=192.168.1.141:/root/porting_x210/rootfs/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200 |
使用tftp烧录zImage后,显示如下,原因是在menuconfig没有开启对NFS的启动支持
从新烧录zimage启动如下:说明挂载rootfs成功,linuxrc失败。
(1)nfs方式启动相当于开发板上的内核远程挂载到主机上的rootfs
(3)nfs方式不适合真正的产品,一般作为产品开发阶段调试使用
五、到底什么是linuxrc
(2)/linuxrc在开发板当前内核系统下是可执行的。因此在ARM SoC的linux系统下,这个应用程序就是用arm-linux-gcc编译链接的;如果是在PC机linux系统下,那么这个程序就是用gcc编译链接的。
(3)/linuxrc如果是静态编译链接的那么直接可以运行;如果是动态编译链接的那么我们还必须给他提供必要的库文件才能运行。
但是因为我们/linuxrc这个程序是由内核直接调用执行的,因此用户没有机会去导出库文件的路径,因此实际上这个/linuxrc没法动态链接,一般都是静态链接的。
(1)操作系统启动后在一系列的自己运行配置之后,最终会给用户一个操作界面(也许是cmdline,也许是GUI),这个用户操作界面就是由/linuxrc带出来的。
(2)用户界面等很多事并不是在/linuxrc程序中负责的,用户界面有自己专门的应用程序,但是用户界面的应用程序是直接或者间接的被/linuxrc调用执行的。用户界面程序和其他的应用程序就是进程2、3、4·····,这就是我们说的进程1(init进程,也就是/linuxrc)是其他所有应用程序进程的祖宗进程。
(1)就好像一个房子建好之后不能直接住,还要装修一样;操作系统启动起来后也不能直接用,要配置下。
(2)操作系统启动后的应用层的配置(一般叫运行时配置,英文简写:etc)是为了让我们的操作系统用起来更方便,更适合我个人的爱好或者实用性。
4、/linuxrc在嵌入式linux中一般就是busybox
(1)busybox是一个C语言写出来的项目,里面包含了很多.c文件和.h文件。这个项目可以被配置编译成各个平台下面可以运行的应用程序。
我们如果用arm-linux-gcc来编译busybox就会得到一个可以在我们开发板linux内核上运行的应用程序。
(2)busybox这个程序开发出来就是为了在嵌入式环境下构建rootfs使用的,也就是说他就是专门开发的init进程应用程序。
(3)busybox为当前系统提供了一整套的shell命令程序集。譬如vi、cd、mkdir、ls等。在桌面版的linux发行版(譬如ubuntu、redhat、centOS等)中vi、cd、ls等都是一个一个的单独的应用程序。
但是在嵌入式linux中,为了省事我们把vi、cd等所有常用的shell命令集合到一起构成了一个shell命令包,起名叫busybox。
六、rootfs中还应该有什么
2、dev目录下的设备文件。在linux中一切皆是文件,因此一个硬件设备也被虚拟化成一个设备文件来访问,在linux系统中/dev/xxx就表示一个硬件设备,我们要操作这个硬件时就是open打开这个设备文件,然后read/write/ioctl操作这个设备,最后close关闭这个设备。
在最小rootfs中/dev目录也是不可少的,这里面有一两个设备文件是rootfs必须的。
3、sys和proc目录。在最小rootfs中也是不可省略的,但是这两个只要创建了空文件夹即可,里面是没东西的,也不用有东西。这两个目录也是和驱动有关的。属于linux中的虚拟文件系统。
4、usr是系统的用户所有的一些文件的存放地,这个东西将来busybox安装时会自动生成。
5、etc目录是很关键很重要的一个,目录中的所有文件全部都是运行时配置文件。/etc目录下的所有配置文件会直接或者间接的被/linuxrc所调用执行,完成操作系统的运行时配置。etc目录是制作rootfs的关键,所以后面下一个课程专门讲这个etc目录。
6、lib目录也是rootfs中很关键的一个,不能省略的一个。lib目录下放的是当前操作系统中的动态和静态链接库文件。我们主要是为了其中的动态链接库。
七、补充:VFS简介
(1)VFS是linux内核的一种设计理念、设计机制。VFS就是vitrual file system,叫虚拟文件系统。
(2)具体的一些文件系统如FAT、NTFS、ext2、ext3、jffs2、yaffs2、ubi等主要设计目的是为了管理块设备(硬盘、Nand···)
(3)VFS是借鉴了文件系统的设计理念(通过文件系统将底层难以管理的物理磁盘扇区式访问,转换成目录+文件名的方式来访问),
所以有了VFS后我们可以通过设备文件(目录+文件名,譬如/dev/mmcblk0p2)的方式来访问系统中的硬件设备。
(4)以上可以初步看出VFS的一些厉害之处,但是VFS不止于此。
(1)上面说过的对硬件设备的访问,将对硬件设备的访问和对普通文件的访问给接口统一化了(linux中一切皆是文件)。
(2)将操作系统上层(应用层)对下层不同文件系统类型的访问细节给屏蔽掉了。
因此如果没有VFS那我们写cp命令(其他命令也一样)的时候就不得不去考虑你cp的这个文件在什么文件系统类型下。
所以cp命令非常复杂,因此要考虑具体的文件系统类型。有了VFS后情况就不同了。VFS成了一个隔离层,隔离了下层的不同文件系统的差异性,对上层应用提供一个统一的接口。
(3)VFS将不同文件系统和下层硬件设备(块设备)驱动之间的细节也给屏蔽了。
不同类型的文件系统在本身设计时是不用考虑各种不同的硬件设备的具体操作差异的,这里有一个类似于VFS的设计理念。
(1)VFS机制和rootfs挂载,和其他文件系统的挂载都是有关联的。
(2)内核中有一些sys proc这种虚拟文件系统,这东西也是和VFS机制有关。
(3)/dev/目录下的设备文件都和VFS有关,所以学习驱动绕不开VFS。