根文件系统

根文件系统的构建,是Linux移植三大组成部分的最后一步,根文件系统构建好后,就构成了一个基础的、可以运行的嵌入式Linux最小系统

1. 根文件系统简介

Linux的根文件系统一般也叫做 rootfs,Linux的根文件系统更像是一个文件夹或者叫做目录,在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文件,这些文件是Linux运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。

根文件系统的“根”字就说明了这个文件系统的重要性,它是其他文件系统的根,没有这个“根” ,其他的文件系统或者软件就别想工作。比如我们常用的 ls、mv、ifconfig 等命令其实就是一个个小软件,只是这些软件没有图形界面,而且需要输入命令来运行。这些小软件就保存在根文件系统中。

在构建根文件系统之前,先来看一下根文件系统里面都有些什么内容,根文件系统的目录名字为‘/’ ,就是一个斜杠。下面以Ubuntu为例,来看看根文件系统里都有些什么内容


一些常用的子目录介绍如下表示

目录 描述
/bin 此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls、mv 等命令
/dev device的缩写,此目录下的文件都是和设备有关的。在Linux下一切皆文件,即使是硬件设备,也是以文件的形式存在的,比如/dev/ttymxc0就表示串口0
/etc 此目录下存放着各种配置文件
/lib lib是library的简称,也就是库的意思,因此此目录下存放着Linux所必须的库文件
/mnt 临时挂载目录,一般是空目录,可以在此目录下创建空的子目录,比如/mnt/sd、/mnt/usb,这样就可以将SD卡或者U盘挂载到/mnt/sd 或者/mnt/usb 目录中
/proc 此目录一般是空的,当Linux系统启动以后会将此目录作为proc文件系统的挂载点,proc是个虚拟文件系统,没有实际的存储设备。proc里面的文件都是临时存在的,一般用来存储系统运行信息文件
/usr usr不是user的缩写,而是Unix Software Resource的缩写,即Unix操作系统软件资源目录。Linux 一般被称为类Unix操作系统。既然是软件资源目录,因此/usr 目录下也存放着很多软件,一般系统安装完成以后此目录占用的空间最多
/var 此目录存放一些可以改变的数据
/sbin 此目录页用户存放一些可执行文件, 但是此目录下的文件或者说命令只有管理员才能使用,主要用于系统管理
/sys 系统启动以后此目录作为 sysfs 文件系统的挂载点,sysfs是一个类似于 proc文件系统的特殊文件系统,sysfs也是基于RAM的文件系统,也就是说它也没有实际的存储设备。此目录是系统设备管理的重要目录
/opt 可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中

2. BusyBox构建根文件系统

2.1 BusyBox简介

BusyBox是一个集成了大量的Linux命令(如ls、mv、ifconfig 等命令)和工具的软件。借助BusyBox,进行配置和编译,就可以方便的构建一个嵌入Linux平台所需要的根文件系统。

可在BusyBox官网 https://busybox.net/ 下载源码,如下图

左侧的“Get BusyBox”栏有一行“Download Source” ,点击“Download Source”即可打开 BusyBox 的下载页

目前最新版本是1.35.0,本文使用1.29.0版本(busybox-1.29.0.tar.bz2)来做讲解

2.2 编译BusyBox构件根文件系统

一般在Linux驱动开发的时候都是通过NFS挂载根文件系统的,当调试好之后再将根文件系统烧写到 EMMC或者NAND中,因此需要先在ubuntu虚拟机中构建NFS服务。在nfs服务器目录中创建名为rootfs的子目录,用来存放我们的根文件系统

将busybox-1.29.0.tar.bz2发送到Ubuntu中的合适位置解压:

tar -vxjf busybox-1.29.0.tar.bz2

解压后的文件如下:

⏩ 修改Makefile添加编译器

#修改Makefile的目的是为了在编译时,可以不用在指定编译器的架构
#从而可以缩短手动输入指令的长度
CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
......
ARCH ?= arm
# CORSS_COMPILE使用了绝对路径!是为了防止编译出错

⏩ busybox中文字符支持:若直接编译busybox,使用串口工具时是不支持中文显示的,会显示为“?” ,可修改源码,取消 busybox对中文显示的限制

打开文件busybox-1.29.0/libbb/printable_string.c,将函数printable_string()中的部分程序注释掉,修改后的函数内容如下:

/********** printable_string.c代码段 **********/
const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
{char *dst;const char *s;s = str;while (1) {......if (c < ' ')break;/* 注释掉下面这个两行代码,禁止字符大于0X7F以后 break *//* if (c >= 0x7f)   break; */s++;}#if ENABLE_UNICODE_SUPPORTdst = unicode_conv_to_printable(stats, str);
#else
{char *d = dst = xstrdup(str);while (1) {unsigned char c = *d;if (c == '\0')break;/* 修改下面代码,禁止字符大于0X7F以后输出‘?’ *//* if (c < ' ' || c >= 0x7f) */if( c < ' ')*d = '?';d++;
}
......
#endifreturn auto_string(dst);
}

接着打开文件busybox-1.29.0/libbb/unicode.c,修改如下内容:

/********** unicode.c代码段 **********/
static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
{char *dst;unsigned dst_len;unsigned uni_count;unsigned uni_width;if (unicode_status != UNICODE_ON) {char *d;if (flags & UNI_FLAG_PAD) {d = dst = xmalloc(width + 1);....../* 修改下面一行代码 *//* *d++ = (c >= ' ' && c < 0x7f) ? c : '?'; */*d++ = (c >= ' ') ? c : '?';src++;}*d = '\0';} else {d = dst = xstrndup(src, width);while (*d) {unsigned char c = *d;/* 修改下面一行代码 *//* if (c < ' ' || c >= 0x7f) */if(c < ' ')*d = '?';d++;}}......return dst;}
......
return dst;
}

⏩ 配置busybox:有以下几种配置选项,一般使用默认配置即可

– defconfig:缺省配置,也就是默认配置选项
– allyesconfi:全选配置,即选中 busybox 的所有功能
– allnoconfig:最小配置

make defconfig   #使用默认配置
make menuconfig     #打开图形化配置界面

设置Settings -> Build static binary (no shared libs),用于选择是静态编译还是动态编译,静态编译不需要库文件,编译出来的库很大;动态编译要求根文件系统中有库文件,编译出来的 busybox 小很多。这里不使用静态编译,保持默认不选

设置Settings -> vi-style line editing commands

配置Linux Module Utilities -> Simplified modutils(不需选中)

配置Linux System Utilities -> mdev (16 kb)(确保全选)

设置Settings -> Support Unicode,使能busybox的unicode编码以支持中文

⏩ 编译busybox:配置好busybox以后就可以编译了,输入如下命令

make
make install CONFIG_PREFIX=/home/andyxi/linux/nfs/rootfs
#CONFIG_PREFIX指定编译结果的存放目录

编译完成以后,busybox的所有工具和文件就会被安装到rootfs目录中,如下图;rootfs目录下有bin、sbin和usr三个目录,以及linuxrc文件。Linux内核linit进程最后会查找用户空间的init程序,找到以后就会运行这个用户空间的init程序,从而切换到用户态。如果bootargs设置init=/linuxrc,那么linuxrc就可作为用户空间的init程序

2.3 向根文件系统添加lib库

busybox编译完成后,此时的根文件系统还不能使用, 还需要一些其他的文件

⏩ 向rootfs/lib中添加库文件:上面的busybox使用的是动态库编译,所以还需要向根文件系统中添加动态库

先在rootfs中创建一个名为“lib”的文件夹。
lib库文件从交叉编译器中获取,笔者的交叉编译器存放在“/usr/local/arm/”目录中,进入交叉编译器的"libc/lib"目录:

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

此目录下有很多的so和.a 文件,这些就是库文件,将此目录下所有的so和.a文件都拷贝到 rootfs/lib 目录中:

cp *so* *.a /home/andyxi/linux/nfs/rootfs/lib/ -d  #-d表示拷贝符号链接### 特殊库文件:ld-linux-armhf.so.3(软连接文件,即快捷方式) 的处理
rm ld-linux-armhf.so.3    #先删除rootfs/lib中的这个软链接
# 然后重新拷贝ld-linux-armhf.so.3
cp /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 .

进入交叉编译器的"lib"目录,将此目录下所有的so和.a 库文件拷贝到 rootfs/lib 目录中

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib
cp *so* *.a /home/andyxi/linux/nfs/rootfs/lib/ -d  #-d表示拷贝符号链接

⏩ 向rootfs/usr/lib中添加库文件

在rootfs/usr目录下创建一个名为lib的目录。
将交叉编译器的"libc/usr/lib"目录中的so和.a 库文件拷贝到rootfs/usr/lib目录中

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib
cp *so* *.a /home/andyxi/linux/nfs/rootfs/usr/lib/ -d

至此,根文件系统的库文件就全部添加好了,可以在rootfs目录下使用“du”命令来查看==/lib和/usr/lib== 这两个目录的大小:

du ./lib ./usr/lib/ -sh

2.4 创建其他文件夹

在根文件系统中创建其他文件夹,如 dev、proc、mnt、sys、tmp 和 root 等,创建完后的效果:

3. 根文件系统初步测试

使用NFS挂载的方式来测试上面创建好的根文件系统rootfs。uboot里面的bootargs环境变量会设置root的值,需要将root的值改为NFS挂载,设置格式如为:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>
  • server-ip:服务器IP,存放根文件系统的Ubuntu的IP地址
  • root-dir:根文件系统的存放路径
  • nfs-options:NFS 的其他可选选项,一般不设置。
  • client-ip>:客户端IP ,开发板的IP地址,内核启动后会使用此IP地址来配置开发板
  • gw-ip:网关地址
  • netmask:子网掩码,255.255.255.0
  • hostname:客户机的名字,一般不设置,此值可以空着
  • device:设备名,也就是网卡名,一般是 eth0,eth1….
  • autoconf:自动配置,一般不使用,设置为 off
  • dns0-ip:DNS0 服务器 IP 地址,不使用
  • dns1-ip:DNS1 服务器 IP 地址,不使用

根据上面的格式bootargs环境变量的root值如下:

root=/dev/nfs nfsroot=192.168.10.100:/home/andyxi/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth1:off

启动开发板,串口连接开发板,进入uboot命令行模式,然后设置bootargs环境变量,命令如下:

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/andyxi/linux/nfs/rootfs,proto=tcp rw ip=192.168.10.50:192.168.10.100:192.168.10.1:255.255.255.0::eth1:off'
saveenv

设置好以后使用“boot”命令启动Linux内核,进入根文件系统,结果如下图示

输入“ls”命令进行测试,发现ls命令正常工作。但是此时rootfs并没有制作成功,注意上图中的错误提示:can’t run ‘/etc/init.d/rcS’ 这个文件,说明rootfs仍然不够完善

篇幅所限,关于 rootfs根文件系统的完善将会在后续文章中介绍!

关注公众号,可获取 busybox相关资料

用 BusyBox 构建根文件系统相关推荐

  1. 【ARM】使用Busybox构建根文件系统

    Busybox构建根文件系统 介绍 下载 配置busybox 配置交叉编译器 取消静态库编译 添加vi命令的支持 取消简化模块 支持mdev 中文支持 编译 完善根文件系统 创建必要文件夹 复制库 启 ...

  2. 2.3【Linux系统移植之三】:使用BusyBox构建根文件系统(rootfs)

    文章目录 一.搭建NFS服务器 二.使用BusyBox构建跟文件系统 2.1 修改顶层Makefile 2.2 busybox中文支持 2.3 配置busybox 2.4 编译busybox 2.5 ...

  3. linux busybox路径,BusyBox构建根文件系统

    BusyBox是一个复合了大量简易版Linux工具的程序,嵌入式系统中使用它可以快速建立一个相对简易的根文件系统. 1.下载busybox 官网 www.busybox.net 目前(2015.8.8 ...

  4. JZ2440:busybox构建根文件系统

    busybox版本是:1.24.2 此文章的链接:http://blog.csdn.net/qqliyunpeng/article/details/52163265 我的nfs的目录是 /source ...

  5. 嵌入式Linux利用busybox制作根文件系统

    本文介绍如何利用busybox制作一个最小根文件系统,系统包含ls.cd.ifconfig等基本指令,文件系统采用动态加载的方式. 1.去busybox官网下载源码   官网地址:busybox官网 ...

  6. 笔记:使用buildroot构建根文件系统

    文章目录 简介 构建过程 buildroot包下载 配置 Target options配置项 Build options配置项 Toolchain配置项 System configuration配置项 ...

  7. 教你用 buildroot 构建根文件系统

    如果想要构建完整的根文件系统,大家一般都是使用buildroot,它不仅包含了 busybox 的功能,而且里面还集成了各种软件,需要什么软件就选择什么软件,不需要我们去移植. 嵌入式系统三大部分:b ...

  8. 使用BusyBox制作根文件系统的操作步骤

    参考博客http://www.cnblogs.com/Charles-Zhang-Blog/p/3419301.html 一.构建根文件系统该有的目录 即在/rootfs/目录下创建该有的空目录: 一 ...

  9. 构建根文件系统(一)

    接着前边内核移植的文章,记录根文件系统的构建. 这里要用到强大的busybox,我选择的版本是busybox-1.18.5.tar.bz2 ,1.17的也可以:之所以选择这个版本是因为基于现在的交叉编 ...

  10. 构建根文件系统的/dev目录

    在嵌入式ARM开发中,用busybox制作根文件系统时,其中必须构建的一个目录就是/dev目录.这个目录对所有的用户都十分重要,因为在这个目录中包含了所有Linux系统中使用到的外部设备,即所有的设备 ...

最新文章

  1. Python实现一元及多元线性回归
  2. python程序的控制结构
  3. .NET设计模式(18):迭代器模式(Iterator Pattern)(转)
  4. 非极大值抑制(Non-maximum suppression)在物体检测领域的应用
  5. js 利用事件委托解决mousedown中的click
  6. 你见过最奇葩的人和事是什么?
  7. java常见的定时任务
  8. 计算机教室配套,中小学标准音乐教室建设及设备配套方案
  9. OpenCore引导配置说明第十四版-基于OpenCore-0.6.7
  10. MiniUtilityFramework(九):CText和TEXT
  11. 电脑键盘部分按键失灵_win10键盘个别按键失灵的原因及解决方法
  12. windows保护无法启动修复服务器,解决使用sfc命令提示“windows 资源保护无法启动修复服务”的方法...
  13. springcloud五大组件永远滴神——成神之路
  14. Android 10 Settings应用二级菜单关于设备-Android版本中基带版本添加点击事件
  15. 人脸检测--libfacedetection
  16. linux ubuntu bionic,在Ubuntu 18.04 Bionic Beaver Linux上安装和设置KVM
  17. includes的用法
  18. 独特的电子邮箱地址-LeetCode练习(Java实现)
  19. python骰子游戏分析_python---骰子游戏
  20. 数字营销重构企业市场关系,中台战略升级制造商业模式

热门文章

  1. html缩小照片尺寸像素不变,怎么修改照片像素,但又不改变照片大小呢?——解决照片因大小无法上传的方案...
  2. 远程如何重装linux系统,独立服务器远程重装Linux系统
  3. Python有限状态机FMS结合测试用例
  4. html 图片导出excel,html静态表格导出到excel
  5. linux redis-trib.rb,redis集群配置 执行 redis-trib.rb 报错解决方法
  6. ## 第一节课第一串代码
  7. 天池风控算法大赛来了!
  8. 稳压电源集成控制器的发展
  9. 365投票抽奖助手V4.5.95版本小程序源码|前端+后端完整源码
  10. MAC笔记本下Android 反编译apk文件最新版本