Linux内核开发_3_busybox
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相关推荐
- Linux 内核开发特点
Linux 内核 开发的特点 无 libc 库抑或无标准头文件库 GUN C 没有内存保护机制 不要再内核中轻易使用浮点数 容积小而且固定的栈 同步和并发 可移植性的重要性 参考文献 开发的特点 相对 ...
- Linux内核开发工作方向
Linux内核开发工作方向
- 嵌入式系统Linux内核开发工程师必须掌握的三十道题
嵌入式系统Linux内核开发工程师必须掌握的三十道题 如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师,试试看! 1) Linux中主要有哪几种内核 ...
- linux 内核开发_25年Linux内核开发中的9课
linux 内核开发 由于Linux内核社区在2016年庆祝了25年的开发历史,因此许多人向我们询问了该项目的长寿和成功秘诀. 我通常会开玩笑,说我们真的不知道如何到达这里. 在此过程中,该项目面临许 ...
- Linux学习总结(68)——Linux 30年专访:Linus Torvalds谈Linux内核开发与Git
三十年前,当Linus Torvalds(林纳斯·托瓦兹,下文统称Linus)首次发布Linux内核时,他还是赫尔辛基大学(University of Helsinki)的一名21岁的学生,他宣布说: ...
- Linux 30年专访:Linus Torvalds谈Linux内核开发与Git
作者 | Jeremy Andrews 译者 | 火火酱,责编 | Carol 出品 | CSDN(ID:CSDNnews) 三十年前,当Linus Torvalds(林纳斯·托瓦兹,下文统称Linu ...
- 嵌入式Linux内核开发工程师必须掌握的三十道题
如果你能正确回答以下问题并理解相关知识点原理,那么你就可以算得上是基本合格的Linux内核开发工程师. 1. Linux中主要有哪几种内核锁?(进程同步与互斥) (1)自旋锁:非睡眠锁 (2)信号量: ...
- 如何进行linux内核开发,2. 开发流程如何工作 — The Linux Kernel documentation
2.1.总览¶ 内核开发人员使用一个松散的基于时间的发布过程,每两到三个月发布一次新的主要 内核版本.最近的发布历史记录如下: 4.11 四月 30, 2017 4.12 七月 2, 2017 4.1 ...
- 何为 Linux 内核开发,怎么学好 Linux 内核?
此文包含 Linux 系统的学习路径和书籍推荐. 我觉得学习 Linux 系统,内核驱动时,最开始只需要 'Know what, not know how '. 不用去探究细节,只需要知道整体的框架, ...
最新文章
- 2017年深度学习重大研究进展全解读
- 排序算法 —— 归并排序
- Shortcut setting in Webclient UI
- 怎么用vc采集ni卡数据_8bit,200MS/s 低成本模拟输入高速采集卡FCFR-PCI9850
- python数字排列组合去重_排列组合-生成集合的所有子集
- 【C语言】逗号运算符的使用举例
- 动手学深度学习(PyTorch实现)(十一)--GoogLeNet模型
- 遵循Java EE标准规范的开源GIS服务平台之三:数据发布与访问
- Python实现鸢尾花数据集分类问题——基于skearn的LogisticRegression
- Vs2010创建WebService
- 用决策树模型求解回归问题(regression tree)
- 地图比例尺与空间分辨率之间的关系_宝马如何查看自己的车机系统是不是idrive几的?宝马主机与idrive系统和导航地图之间的对应关系!...
- Atiitt 可视化 报表 图表之道 attilax著 Atitit.可视化与报表原理与概论 1. 信息可视化	1 2. Gui可视化	2 2.1. atitit 知识的可视化.docx	2
- AFNetworking请求服务器错误
- 人人网是明文传输,所以只要抓包就能知道用户名和密码
- 一元三次方程重根判别式_一元三次方程的求根公式
- “码头工人”的Docker进阶之路:从轻装上路到网络、存储和安全
- HTML 超文本标记语言
- C程序-超简单的猜数字-游戏
- Linux登入Oracle数据库修改密码
热门文章
- JSR-303校验-转载
- 已在页面完全加载前强制排版_公众号写作排版指南v2.0(适配Dark Mode)
- java exception 包_什么是Java中的异常包装?
- 在el-table中使用el-popover,没法点击确定或取消来关闭添加 多个按钮
- python怎么读_锋哥告诉你Python怎么读
- 巅峰抢购助手pc_豌豆荚、91助手宣布暂停部分服务!第三方应用商店为何式微?...
- 饮食与癌细胞代谢的分子联系
- mysql -a_a|MySQL基础命令
- 怎么用debug看jdbc查询的resultset中查出的数据_用了这个 ORM 工具,我只用一天就把项目数据库给换了
- 加州理工学院公开课:机器学习与数据挖掘_神经网络