使用BusyBox构建根文件系统

根文件系统
根文件系统的构建,是 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 = 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 = 0x7f) if( c = ' ' && c =' ')? c :'?'; src++; } *d ='\\0';}else{ d = dst =xstrndup(src, width); while(*d){ unsignedchar c =*d; /* 修改下面一行代码 */ // if (c = 0x7f) if(c 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以后就可以编译了,输入如下命令
makemake 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.3cp /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/libcp *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/libcp *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.0hostname:客户机的名字,一般不设置device:设备名,也就是网卡名,一般是 eth0,eth1….autoconf:自动配置,一般不使用,设置为 offdns0-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根文件系统的完善将会在后续文章中介绍!

WAF 防护核心WEB应用的解析
无铅含铜锡条纯锡条的区别,哪个好?
西门子S7-1200 PLC定位控制教程
新思科技最新提出SysMoore理念协助本土客户实现颠覆性创新
萨科微 碳化硅专家
使用BusyBox构建根文件系统
关于通讯模组开发板,知道的越多不知道的越多(MINIPCIE篇)
华为突破EUV光刻机核心技术!
燃料电池的工作原理及常见种类
以美团为例的数据治理技术案例分析
未来几季英伟达GPU将供不应求?
Ubuntu衍生版新星:支持Flatpak、不支持Snap
紫米发布带HDMI接口的移动电源可连屏幕、传输4K视频
5G研发待解决的三大难题,5G将是通用平台?
确定最佳PCB铜厚的关键元素:热量上升和铜的厚度
AI芯片领域好戏才刚开始
盘点无人车创业市场新格局
对比iPhone 6、6S, iPhone7新手机是否值得买?
HKZ-60开关状态智能显示操控装置
基于ULN2003A达林顿管的步进电机驱动设计