根文件系统的构建终极总结

1、根文件系统背景

根文件系统首先是内核启动时所 mount( 挂载 ) 的第一个文件系统,内核代码映像文件保存在
根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和
服务等加载到内存中去运行。  比如 rcS,inittab 等。 根文件系统 Linux 内核  是 分开的,单独 的 Linux 内核 是没法正常工作的,必须要搭配  根文件系统
一般我们在 Linux 驱动开发的时候都是通过 nfs 挂载根文件系统的 ,当产品最终上市开卖
的时候 才会将根文件系统烧写到 EMMC 或者 NAND 中 mkdir rootfs  创建根文件系统。

2、根文件系统目录 

1、 /bin 目录
看到 “bin”   大家应该能想到   bin   文件,  bin 文件就是可执行文件 。 所以  此目录下存放着系统
需要的可执行文件 ,一般都是一些命令,比如   ls、mv 等命令 。此目录下的命令所有的客户都可
以使用
2、 /dev 目录
dev device 的缩写,所以此目录下的文件都是和设备有关的,此目录下的文件都是设备
文件。 在 Linux 下一切皆文件,即使是硬件设备,也是以文件的形式存在的, 比如
/dev/ttymxc0(I.MX6ULL 根目录会有此文件 ) 就表示 I.MX6ULL 的串口 0 ,我们要想通过串口 0
发送或者接收数据就要操作文件 /dev/ttymxc0 ,通过对文件 /dev/ttymxc0 的读写操作来实现串口
0 的数据收发
3、 /etc 目录
 此目录下存放着各种配置文件,大家可以进入 Ubuntu 的 etc 目录看一下 ,里面的配置文件
非常多!但是在嵌入式 Linux 下此目录会 很简洁。
4、 /lib 目录
 lib 是 library 的简称,也就是库的意思,因此此目录下存放着 Linux 所必须的库文件 。这些
库文件是 共享库,命令和用户编写的应用程序 要使用这些库文件。
5、 /mnt 目录
临时挂载目录,一般是空目录,可以在此目录下创建空的子目录,比如 /mnt/sd、/mnt/usb,
这样就可以将 SD 卡或者 U 盘挂载到/mnt/sd 或者/mnt/usb 目录中
6 /proc 目录
此目录一般是空的,当 Linux 系统启动以后会将此目录作为 proc 文件系统的挂载点,proc
是个虚拟文件系统,没有实际的存储设备。proc 里面的文件都是临时存在的,一般用来存储系
统运行信息文件。
7/usr 目录
要注意, usr 不是 user 的缩写,而是 Unix Software Resource 的缩写,也就是 Unix 操作系统
软件资源目录。这里有个小知识点,那就是 Linux 一般被称为类 Unix 操作系统,苹果的 MacOS
也是类 Unix 操作系统。关于 Linux Unix 操作系统的渊源大家可以直接在网上找 Linux 的发
展历史来看。既然是软件资源目录, 因此/usr 目录下也存放着很多软件,一般系统安装完成以
后此目录占用的空间最多。
9、/sbin 目录
  此目录页用户存放一些可执行文件 ,但是此目录下的 文件或者说命令 只有管理员才能使用,
主要用户系统管理。
10 /sys 目录
系统启动以后此目录作为 sysfs 文件系统的挂载点, sysfs 是一个类似于 proc 文件系统的特
殊文件系统, sysfs 也是基于 ram 的文件系统,也就是说它也没有实际的存储设备。此目录是系
统设备管理的重要目录,此目录通过一定的组织结构向用户提供详细的内核数据结构信息。
11 /opt
可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中。
关于 Linux 的根目录就介绍到这里,接下来的构建根文件系统就是研究如何创建上面这些子目
录以及子目录中的文件。
根文件系统里面就是一堆 可执行的文件 和 其他库文件组成的。

3、Busybox 制作根文件系统雏形 

 

Busybox 集成了大量的 linux 命令 和 工具的软件 ls mv ifconfig BusyBox 就是一个大的工具箱  集成了很多 linux 的许多工具和命令。

3.1  获取 busybox 源码  编译 安装获取 根文件系统雏形
tar xvf  busybox-1.29.0.tar.bz2
3.2  vim  Makefile  修改编译器  和  架构
CROSS_COMPILE ?= arm-linux-gnueabihf-
ARCH ?= arm
3.3 busybox 中文字符支持
vim  busybox-1.29.0/libbb/ printable_string.c
func  printable_string 
/* if (c >= 0x7f)  break; */ 
/* if (c < ' ' || c >= 0x7f) *d = '?';*/  
if( c < ' ') d = '?'
vim unicode.c 
*d++ = (c >= ' ' && c < 0x7f) ? c : '?';  改为   * d ++ = ( c >= ' ' ) ? c : '?' ;
/* if (c < ' ' || c >= 0x7f) */   改为  if( c < ' ' )
3.4 busybox 配置 
根我们编译   Uboot、Linux kernel 一样,我们要先对 busybox 进行默认的配置,有以下几种
配置选项:
①、defconfig,缺省配置,也就是默认配置选项
②、allyesconfig,全选配置,也就是选中 busybox 的所有功能。
③、allnoconfig,最小配置。
我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下 busybox:
make defconfig
busybox 也支持图形化配置,通过图形化配置我们可以进一步选择自己想要的功能,输入
如下命令打开图形化配置界面:
make menuconfig
3.4   编译busybox 
配置好 busybox 以后就可以编译了,我们可以指定编译结果的存放目录,我们肯定要将编
译结果存放到前面创建的 rootfs 目录中
make
make install CONFIG_PREFIX=/home/zhengyang/linux/nfs/rootfs

4、完善根文件系统 

rootfs 目录下有 bin sbin usr 这三个目录,以及 linuxrc 这个文 件。
Linux 内核 init 进程最后会查找用户空间的 init 程序
找到以后就会运行这个用 户空间的 init 程序 ,从而 切换到用户态 。如果 bootargs 设置 init=/linuxrc l
inuxrc 就是可以 作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的
既然我不知道那就简单粗暴的把所有的库文件都放到我们的根文件系统中。这样做出来的根文件系统肯定很大,但是我 们现在是学习阶段,还做不了裁剪。
4.1 向根文件系统添加 lib
 向 rootfs 的 “/lib” 目录添加库文件  拷贝编译器的 通用库的 so a 到根文件系统中
进到编译工具的 libc/lib 目录 lib 目录
cp *.so* *.a /home/zhengyang/linux/nfs/rootfs/lib/ -d
替换 libc/lib 目录 ld-linux-armhf.so.3  快捷方式:
rm ld-linux-armhf.so.3
cp ld-linux-armhf.so.3  /home/zhengyang/linux/nfs/rootfs/lib/
4.2 向根文件系统添加  usr/lib  应用程序库  
编译器/libc/ usr/lib
将此目录下的 so .a 库文件都拷贝到 rootfs/usr/lib 目录中
cp *.so* *.a /home/zhengyang/linux/nfs/rootfs/usr/lib/  -d
4.3 在根文件系统中创建其他文件夹,如 dev、proc、mnt、sys、tmp 和 root
mkdir dev proc mnt sys tmp root
4.4 增加 rcS文件 
rcS 是个 shell 脚本 Linux 内核启动以后需要  启动一些服务 ,而 rcS 就是规定启动哪些文件
的脚本文件。vim   /etc/init.d/rcS  文件, 然后在 rcS 中输入如下所示内容:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
创建好文件  /etc/init.d/rcS 以后一定要给其可执行权限! ​​​​​​​ chmod 777 rcS
解释:
1 行,表示这是一个 shell 脚本。
3 行, PATH 环境变量保存着可执行文件可能存在的目录,这样我们在执行一些命令或
者可执行文件的时候就不会提示找不到文件这样的错误。
4 行, LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
5 行,使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
7 行,使用 mount 命令来挂载所有的文件系统,这些文件系统由文件 /etc/fstab 来指定,
所以我们一会还要创建 /etc/fstab 文件。
8 9 行,创建目录 /dev/pts ,然后将 devpts 挂载到 /dev/pts 目录中。
4.5  增加/fstab
在 rootfs 中创建/etc/fstab 文件,fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区
vim /etc/fastab  
#<file system>  <mount point>      <type>       <options>    <dump>    <pass>
     proc                   /proc                proc         defaults           0              0
     tmpfs                 /tmp                 tmpfs       defaults           0              0
     sysfs                  /sys                  sysfs       defaults           0              0
4.6  增加inittab
vim /etc/inittab 
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
解释:
第 2 行,系统启动以后运行/etc/init.d/rcS 这个脚本文件。
第 3 行,将 console 作为控制台终端,也就是 ttymxc0。
第 4 行,重启的话运行/sbin/init。
第 5 行,按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重
启系统。
第 6 行,关机的时候执行/bin/umount,也就是卸载各个文件系统。
第 7 行,关机的时候执行/sbin/swapoff,也就是关闭交换分区。

5、根文件系统验证

设置 kernel 启动参数 bootargs  nfs 网络挂载启动 进行验证。
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.250:
/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:
255.255.255.0::eth0:off'
//设置 bootargs
saveenv
//保存环境变量

网络挂载启动文件系统后:

在  ubuntu  下使用 vim  编辑器新建一个  hello.c  文件 ​​​​​​​​​​​​​​
hello  这个可执行程序推送到  本地  运行正常,说明我们的 根文件系统中 的移植的库是没问题的
#include < stdio . h >
 i nt main ( void )
{
   while ( 1 ) {
  printf ( "hello world!\r\n" );
  sleep ( 2 );
   }
   return 0 ;
}
tar -czvf rootfs.tar.gz rootfs
 
 
​​​​​​​

你可能感兴趣的:(linux_board,linux)