Busybox简介

busybox是一个开源项目,集合了Linux的常用命令,且体积非常小,一般被用于嵌入式Linux上。

busybox在编写初期的思想就是简洁,小巧,强悍,并且设计时从系统资源考虑,节省内存,动态编译busybox工具包总大小才几百kb,如果是静态编译则才1MB左右,非常适合用于嵌入式开发,与发行版不同,发行版使用的不是busybox,一些流行发行版一般使用的都是GNU fileutils、shellutils,这些工具链里包含了对文件,还有一些shell支持的命令,就是我们常用的ls之类的命令,都属于GNU的开源项目。

下载Busybox

你可以在它的官网下载到有关Busybox的所有开源版本的源代码:

https://busybox.net/downloads/

将Busybox制作成根文件系统

前几篇文章讲了如何使用Initramf作为根文件系统,但是效果并不能达到我们的要求,这篇文章使用busybox做一个完整的根文件系统,并且不将它作为临时根文件系统,而是把它当作一个实际根文件系统,供Linux内核使用。

根文件系统简述

在Linux中,根文件系统就是Linux下“/”目录,Linux把文件系统挂载到这个目录下,这个目录下一般拥有Linux运行时需要的一些设备文件,如块设备,tty,字符设备文件等。

编译Busybox

这里我下载的是1.27.0版本的

wget https://busybox.net/downloads/busybox-1.27.0.tar.bz2

这里跟大家说一个tar解压命令的小技巧,原本这种解压我们需要使用对应的选项,二次解压后才能得到原文件,这里我们不需要指定这些,tar命令会自动帮我们分析

tar -xf busybox-1.27.0.tar.bz2

-x是解压的意思,-f是文件的意思,我们不需要指定解压格式,tar会自动帮我们分析

busybox目录结构说明:

applets

主要是实现applets框架的文件

applets_sh

一些有用的脚本,例如:dos2unix、unix2dos等

archival

与压缩有关的命令源文件,例如:bzip2、gzip等

configs

自带的一些默认配置文件

console-tools

与控制台相关的一些命令,例如:setconsole

coreutils

常用的核心命令,例如:cat、rm等

editors

常用的编辑命令,例如:vi、diff等

findutils

用于查找的命令,例如:find、grep等

init

init进程的实现源文件

networking

与网络相关的命令,例如:telnetl、arp等

shell

与shell相关的实现,例如:ash、msh等

util-linux

Linux下常用的命令,主要是与文件系统相关的,例如:mkfs_ext2等

配置busybox

和Linux一样,busybox使用menuconfig配置,可以在里面去裁剪一些不需要的模块,这里我们使用这个命令然后选择静态编译,因为在我们编译的Linux内核里,并不自带GLIBC库

sudo make menuconfig

选择“Busybox Setting"

选择”Build BusyBox as a static binary(no shared libs)” 按下“Y”

然后保存退出,使用make install编译

sudo make install

编译完成后会生成很多目录,其中_install目录里就是我们需要的bin文件,除了bin文件还包含了一些根文件系统所具备的一些设备文件

使用ls命令查看一下:

包含了一些基本的文件目录,如usr,bin这些Linux内核运行时的一些目录,当然,只有这些目录是不能算上一个完整的根文件系统目录的,还需要/dev /tty等目录。

创建文件系统

busybox编译完成了,上面也说了_install文件夹下的所有文件,要被拿来制作成文件系统,那么怎么制作呢?

很简单,在Linux上如果要对软盘或者U盘进行操作,那么就需要挂载,这里我们可以使用dd命令先创建一个软盘,作为我们的根文件系统的镜像文件,然后将它挂载到一个目录下,最后我们把busybox下_install目录copy到镜像文件挂载的目录下,这样镜像文件里就有了一个基础根文件系统所需要的设备文件目录,然后在卸载挂载,这样一个文件系统的镜像就已经制作完成了。

实践:

1.创建镜像文件

dd if=/dev/zero of=rootfs.img bs=4096 count=1024

这里我们创建一个4MB大小的镜像文件

然后使用ext3格式格式化这个镜像文件,前几篇文章说过,Linux子系统VFS负责与文件系统进行交互,但是VFS只认特定的格式,如NFS,EXT等,所以这里我们格式化一下,注意如果你的Linux内核不支持ext3,需要在make menuconfig时,选择file system里把这一选项按下Y,否则VFS会报内核恐慌

mkfs.ext3 rootfs.img

创建一个目录作为挂载点:

mkdir rootfs

挂载:

sudo mount -o loop rootfs.img rootfs/

将busybox下的_install文件夹下的所有文件copy过来

sudo cp -a ../busybox-1.27.0/_install/* rootfs/.

ls看一下:

除了这些文件以外,我们还需要三个设备文件dev proc sys

这里介绍一些这三个文件的作用:

/sys/ 用于管理存储文件,文件相关管理 的,sys是运行在内存中的
/proc 用于管理进程,是对进程管理,运行的进程参数管理的
/dev 存放各种设备节点,除了设备节点还会存储socket,管道文件

这些是Linux内核运行时需要的三个设备节点,这里我们创建出来,具体这些文件的作用,我后面在写文件系统组成时会详细讲解,目前各位只需要知道这些文件在运行时,会被Linux内核里的一些文件管理系统挂载到上面去

注意这些文件需要创建在rootfs文件夹下哦

cd rootfs
sudo  mkdir dev proc sys
cd ..

基本一个文件系统的基础已经搭好了,那么这样我们就可以卸载挂载了,然后把这个挂载目录删除或者不删除都可以

sudo umount rootfs

那么到这一步,基本上一个简单的根文件系统已经搭好了,可以用作嵌入式,或者amd都可以。

运行

使用qemu指定我们的硬盘路径,然后模拟运行:

qemu-system-x86_64 -kernel /usr/src/linux-4.10.15/arch/x86/boot/bzImage\-hda rootfs.img \-append "root=/dev/sda init=/bin/ash"

这里来解释一下选项:

-hda 是指定硬盘文件

-append 这个选项不用多说了,第一篇文章有说过,这里说一下里面的运行

root=/dev/sda 这个是指定根文件系统挂载点,大家有没有发现其实我们刚刚创建时,只是创建了一个dev目录,但是并没有创建sda这个目录,这个不用担心,因为Linux内核运行时会在自动创建设备文件,并将文件系统挂载到这些文件上,这个sda就是文件系统挂载目录,这个设备文件必须指定为sda,经过测试结果是这样,查的资料是这个设备文件是指整个硬盘,还有sda1,sda2这些是指硬盘下的分区,至于更详细的资料,还在查阅读内核代码中。

最后面,的init可以不用指定,这个就是在根文件目录下的bin下找一个可执行文件,如果不指定的话Linux内核会自动寻找几个常用的init

这几行代码是位于Linux内核init/main.c文件下的kernel_init函数下,它会去依次使用try_to_run_init_process函数来调用不同的初始化函数,如果你的根文件系统下有对应的文件就ok,如果没有则会引起内核恐慌,找不到init程序。

与Linux2.6内核不同的是Linux2.6使用的是init_post,这个函数会发生两次调用,第一次是进入到init_post,完成相关初始化后在去依次创建这些进程。

但是到了我们所使用的内核时,只会发生一次函数调用,初始化前面就已经被完成了,就只会发生调用创建进程的函数,可以说得上是运行速度和资源上的提升了。

因为在内核里,一切都最好按照一个整体来设计,这样就可以省去不必要的接口调用,等函数调用时发生的堆栈保护等问题。

所以这也是为什么可以在Linux内核里看到大量的内联函数的原因。

运行结果:

注意运行后要按两下回车,因为运行时init已经打印出数据来了,但是Linux内核的一些工作是后续完成的,也会打印出来,会导致你可能看不到“#”这个输入交互字符,建议按两下回车,刷一下缓冲流,有的时候这会让人觉得是不是运行没有成功,哈哈我就是。

添加自己的调试程序

这里教大家一个小技巧,比如我写了一个调试程序,那么我想调试它怎么办?

我们可以先挂载镜像文件,然后把我们的文件打包到bin目录下就可以了,不过打包的文件要静态编译,这一点在第一章已经说过了,这里就不多说啦。

先随便写一个文件:

vim test.c
#include <stdio.h>int main(){printf("test!");return 0;
}

gcc静态编译:

gcc -static -o test test.c

然后挂载一下镜像文件,在把test copy进去

sudo mount -o -loop rootfs.img rootfs
sudo cp test rootfs/bin/

然后运行,Linux内核时到bin目录下执行即可

记得把镜像文件分配大一点哦,不然会出现 No space left on device的错误。

Linux内核开发_3_busybox相关推荐

  1. Linux 内核开发特点

    Linux 内核 开发的特点 无 libc 库抑或无标准头文件库 GUN C 没有内存保护机制 不要再内核中轻易使用浮点数 容积小而且固定的栈 同步和并发 可移植性的重要性 参考文献 开发的特点 相对 ...

  2. Linux内核开发工作方向

    Linux内核开发工作方向

  3. 嵌入式系统Linux内核开发工程师必须掌握的三十道题

    嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师,试试看! 1) Linux中主要有哪几种内核 ...

  4. linux 内核开发_25年Linux内核开发中的9课

    linux 内核开发 由于Linux内核社区在2016年庆祝了25年的开发历史,因此许多人向我们询问了该项目的长寿和成功秘诀. 我通常会开玩笑,说我们真的不知道如何到达这里. 在此过程中,该项目面临许 ...

  5. Linux学习总结(68)——Linux 30年专访:Linus Torvalds谈Linux内核开发与Git

    三十年前,当Linus Torvalds(林纳斯·托瓦兹,下文统称Linus)首次发布Linux内核时,他还是赫尔辛基大学(University of Helsinki)的一名21岁的学生,他宣布说: ...

  6. Linux 30年专访:Linus Torvalds谈Linux内核开发与Git

    作者 | Jeremy Andrews 译者 | 火火酱,责编 | Carol 出品 | CSDN(ID:CSDNnews) 三十年前,当Linus Torvalds(林纳斯·托瓦兹,下文统称Linu ...

  7. 嵌入式Linux内核开发工程师必须掌握的三十道题

    如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师. 1. Linux中主要有哪几种内核锁?(进程同步与互斥) (1)自旋锁:非睡眠锁 (2)信号量: ...

  8. 如何进行linux内核开发,2. 开发流程如何工作 — The Linux Kernel documentation

    2.1.总览¶ 内核开发人员使用一个松散的基于时间的发布过程,每两到三个月发布一次新的主要 内核版本.最近的发布历史记录如下: 4.11 四月 30, 2017 4.12 七月 2, 2017 4.1 ...

  9. 何为 Linux 内核开发,怎么学好 Linux 内核?

    此文包含 Linux 系统的学习路径和书籍推荐. 我觉得学习 Linux 系统,内核驱动时,最开始只需要 'Know what, not know how '. 不用去探究细节,只需要知道整体的框架, ...

最新文章

  1. 2017年深度学习重大研究进展全解读
  2. 排序算法 —— 归并排序
  3. Shortcut setting in Webclient UI
  4. 怎么用vc采集ni卡数据_8bit,200MS/s 低成本模拟输入高速采集卡FCFR-PCI9850
  5. python数字排列组合去重_排列组合-生成集合的所有子集
  6. 【C语言】逗号运算符的使用举例
  7. 动手学深度学习(PyTorch实现)(十一)--GoogLeNet模型
  8. 遵循Java EE标准规范的开源GIS服务平台之三:数据发布与访问
  9. Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression
  10. Vs2010创建WebService
  11. 用决策树模型求解回归问题(regression tree)
  12. 地图比例尺与空间分辨率之间的关系_宝马如何查看自己的车机系统是不是idrive几的?宝马主机与idrive系统和导航地图之间的对应关系!...
  13. Atiitt 可视化 报表 图表之道 attilax著 Atitit.可视化与报表原理与概论 1.  信息可视化 1 2. Gui可视化 2 2.1. atitit 知识的可视化.docx 2
  14. AFNetworking请求服务器错误
  15. 人人网是明文传输,所以只要抓包就能知道用户名和密码
  16. 一元三次方程重根判别式_一元三次方程的求根公式
  17. “码头工人”的Docker进阶之路:从轻装上路到网络、存储和安全
  18. HTML 超文本标记语言
  19. C程序-超简单的猜数字-游戏
  20. Linux登入Oracle数据库修改密码

热门文章

  1. JSR-303校验-转载
  2. 已在页面完全加载前强制排版_公众号写作排版指南v2.0(适配Dark Mode)
  3. java exception 包_什么是Java中的异常包装?
  4. 在el-table中使用el-popover,没法点击确定或取消来关闭添加 多个按钮
  5. python怎么读_锋哥告诉你Python怎么读
  6. 巅峰抢购助手pc_豌豆荚、91助手宣布暂停部分服务!第三方应用商店为何式微?...
  7. 饮食与癌细胞代谢的分子联系
  8. mysql -a_a|MySQL基础命令
  9. 怎么用debug看jdbc查询的resultset中查出的数据_用了这个 ORM 工具,我只用一天就把项目数据库给换了
  10. 加州理工学院公开课:机器学习与数据挖掘_神经网络