0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用BusyBox构建根文件系统

CHANBAEK 来源:嵌入式攻城狮 作者:安迪西 2023-04-19 11:20 次阅读

根文件系统

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

1. 根文件系统简介

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

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

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

图片

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

/bin :此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls、mv 等命令

/dev :device的缩写,此目录下的文件都是和设备有关的。 在Linux下一切皆文件,即使是硬件设备,也是以文件的形式存在的,比如/dev/ttymxc0就表示串口0

/etc :此目录下存放着各种配置文件

/lib :library的简称,也就是库,此目录下存放着Linux所必须的库文件

/mnt :临时挂载目录,一般是空目录,可在此目录下创建空的子目录,比如/mnt/sd、/mnt/usb,这样就可以将SD卡或者U盘挂载到/mnt/sd 或者/mnt/usb 目录中

/proc :此目录一般是空的,当Linux系统启动以后会将此目录作为proc文件系统的挂载点,proc是个虚拟文件系统,没有实际的存储设备。 proc里面的文件都是临时存在的,一般用来存储系统运行信息文件

/usr :不是user的缩写,而是Unix Software Resource的缩写,即Unix操作系统软件资源目录。 此目录下也存放着很多软件,一般系统安装完成以后此目录占用的空间最多

/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添加编译器

#为了在编译时,可以不用再指定编译器的架构,从而缩短手动输入指令的长度
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代码段 **********/
constchar* FAST_FUNC printable_string(uni_stat_t*stats,constchar*str)
{
char*dst;
constchar*s;

  s = str;
while(1){
    ......
    if(c <' ')
      break;
    /* 注释掉下面这个两行代码,禁止字符大于0X7F以后 break */
    // if (c >= 0x7f)   
    //   break; 
    s++;
  }

#if ENABLE_UNICODE_SUPPORT
  dst =unicode_conv_to_printable(stats, str);
#else
  {
    char*d = dst =xstrdup(str);
    while(1){
      unsignedchar c =*d;
      if(c =='\\0')
        break;
      /* 修改下面代码,禁止字符大于0X7F以后输出‘?’ */
      // if (c < ' ' || c >= 0x7f) 
      if( c <' ')
        *d ='?';
      d++;
    } ......
  }
#endif
returnauto_string(dst);
}

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

/********** unicode.c代码段 **********/
staticchar* FAST_FUNC unicode_conv_to_printable2(uni_stat_t*stats,constchar*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){
      unsignedchar c =*d;
      /* 修改下面一行代码 */
      // if (c < ' ' || c >= 0x7f) 
      if(c <' ')
        *d ='?';
      d++;
    }
}
......
return dst;
}

配置busybox:有以下几种配置选项

  • defconfig:缺省配置,也就是默认配置选项
  • allyesconfi:全选配置,即选中busybox所有功能
  • allnoconfig:最小配置
make defconfig  	#使用默认配置
make menuconfig		#打开图形化配置界面

图片

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

图片

设置设置 -> vi 样式的行编辑命令

图片

配置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内核 init进程会查找用户空间的 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:服务器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根文件系统的完善将会在后续文章中介绍!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10990

    浏览量

    206735
  • Ubuntu
    +关注

    关注

    5

    文章

    533

    浏览量

    28834
  • busybox
    +关注

    关注

    0

    文章

    21

    浏览量

    11205
  • 根文件系统
    +关注

    关注

    0

    文章

    23

    浏览量

    11778
  • rootfs
    +关注

    关注

    0

    文章

    19

    浏览量

    4634
收藏 人收藏

    评论

    相关推荐

    文件系统的制作

    不可或缺的组件,在嵌入式Lin-ux中,内核在启动期间进行的最后操作之一就是安装文件系统Busybox构建嵌入式Linux
    发表于 04-29 21:32

    【OK210试用体验】构建文件系统

    的/image目录下并命名为kernel.bin,由bootloader从sd卡加载内核启动。 图2-2 bootloader从sd卡启动linux内核3. Busybox构建文件系统
    发表于 01-10 16:01

    【NanoPi NEO2试用体验】构建文件系统

    的boot.img,上电启动。 3. Busybox构建文件系统3.1. Busybox概述对于linux
    发表于 06-29 09:28

    NXP-I.MX6UL开发板inux文件系统定制资料分享(一)

    想使用uClibc的时候,你需要一个编译工具链使用它作为链接库产生目标代码。Buildroot可以为你做到这一点。Buildroot自动使用所用可能用到的工具(比如busybox构建文件系
    发表于 07-26 15:11

    总结构建最小文件系统步骤

    构建文件系统(*.yaffs2)的步骤:一、最小文件系统(first_fs.yaffs2)包括:1、第一个进程init链接到
    发表于 04-11 16:15

    「正点原子Linux连载」第三十八章文件系统构建

    这些子目录以及子目录中的文件。38.2 BusyBox构建文件系统38.2.1 BusyBox
    发表于 03-17 15:42

    嵌入式Linux文件系统怎么制作?

    不可或缺的组件,在嵌入式Lin-ux中,内核在启动期间进行的最后操作之一就是安装文件系统Busybox构建嵌入式Linux
    发表于 04-06 07:39

    飞凌小课堂-busybox软件怎样快速构建一个最小文件系统

    etc/inittab文件文件系统初始的配置文件,每次进入文件系统时读取该文件,执行该文件所规定
    发表于 05-27 14:39

    常用文件系统构建工具有哪些

    11、/mnt目录12、/tmp目录二、常用文件系统构建工具简介1、BusyBox工具2、Buildroot工具3、Yocto工具一、简介 
    发表于 11-05 07:28

    怎样使用buildroot构建文件系统

    使用buildroot构建文件系统一、buildroot介绍使用busybox 构建文件系统的时候,b
    发表于 11-05 08:13

    如何利用busybox制作一个最小文件系统

    本文介绍如何利用busybox制作一个最小文件系统系统包含ls、cd、ifconfig等基本指令,文件系统采用动态加载的方式。1.去
    发表于 12-16 06:49

    使用Buildroot构建文件系统的方法简析

    1、怎么使用Buildroot构建文件系统?  制作文件系统有归多种方法:  使用Busybox
    发表于 11-04 15:41

    Busybox制作嵌入式Linux根文件系统

    文件系统为Linux 的运行提供最基本的工具、库、脚本和一些特殊文件的支持Busybox 是制作嵌入式Linux 文件系统的快捷工具,本文通过配置、编译、安
    发表于 06-12 16:05 19次下载

    嵌入式Linux学习之旅(10)— 使用buildroot构建文件系统

    使用buildroot构建文件系统一、buildroot介绍使用busybox 构建文件系统的时候,busybox 仅仅只是帮我们
    发表于 11-02 14:36 10次下载
    嵌入式Linux学习之旅(10)— 使用buildroot<b class='flag-5'>构建</b>根<b class='flag-5'>文件系统</b>

    如何完善根文件系统

    在用 BusyBox 构建文件系统一文中介绍了根文件系统的制作,rootfs制作完成后测试时,提示无法运行“/etc/init.d/rcS”这个
    的头像 发表于 04-18 15:26 801次阅读
    如何完善根<b class='flag-5'>文件系统</b>