busybox的实现原理分析(C语言实现简易版的busybox)

news2024/11/20 1:43:31

1、linux中实现命令的两种方式

1.1、命令都是单独的可执行程序

aston:~$ ls -l /bin/ls
-rwxr-xr-x 1 root root 138208  28  2022 /bin/ls
aston:~$ 
aston:~$ ls -l /bin/mkdir 
-rwxr-xr-x 1 root root 68096  28  2022 /bin/mkdir
aston:~$ 
aston:~$ file /bin/ls
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=897f49cafa98c11d63e619e7e40352f855249c13, for GNU/Linux 3.2.0, stripped

(1)在linux的根文件系统中,系统自带的命令放在"/bin、/sbin"目录中,用户的命令放在"/usr/bin、/usr/sbin"目录中;
(2)用"ls -l"可知每个命令都是二进制文件,用"file"命令查看可知每个命令都是可执行文件;
(3)命令都是单独的可执行程序,这种方式一般都是Ubuntu、Centos、服务器的linux系统采用,部署在硬件资源比较充足的设备里;

1.2、命令是指向busybox的符号链接在这里插入图片描述

(1)用"ls -l"可知每个命令都是符号链接,指向busybox;
(2)这种方式一般是嵌入式设备采用;

1.3、两种实现方式的对比

(1)每个命令都是单独的可执行程序:这种方式要求的资源更多,但是命令支持的功能也更丰富;
(2)用符号链接和busybox实现命令:busybox占用的空间明显小于所有单独命令可执行程序占用空间之和,节省更多的资源,但是busybox的命令都是裁剪过的,只支持命令中常用的选项;
(3)busybox适合嵌入式设备,支持必要的命令,而且占用的空间小,嵌入式设备flash和内存一般都不富裕;
(4)命令是单独可执行程序的方式:更适合在电脑、服务器上运行的linux系统,flash和内存等硬件资源都比较充裕,更注重性能和命令的完整;

2、busybox介绍

2.1、为什么需要busybox

(1)busybox集成了常用的所有命令,可以很方便的构建文件系统。假设现在要构建文件系统,如果没有busybox,则需要去下载"ls、cd、mkdir······"每个命令的源码再编译,工作量很大且很繁琐;
(2)busybox高度可裁剪,需要支持什么命令就配置busybox编译哪些命令的源码,有效减小busybox的体积,节省空间;

2.2、busybox的源码获取

官网地址:www.busybox.net

2.3、busybox的两种使用方式

(1)符号链接:建立符号链接指向busybox,为每个命令建立一个符号链接;
(2)直接调用busybox,比如:"busybox ls"的效果和直接执行"ls"命令是相同的;

3、C语言实现简易版busybox

3.1、源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//计算数组的成员个数
#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))

//实现ls命令功能
int my_ls_main(int argc, char * argv[])
{
	char bufCmd[256] = {0};

	sprintf(bufCmd, "ls %s", argv[1]);

	system(bufCmd);

	return 0;
}

//实现mkdir命令功能
int my_mkdir_main(int argc, char * argv[])
{
	char bufCmd[256] = {0};

	sprintf(bufCmd, "mkdir %s", argv[1]);

	system(bufCmd);

	return 0;
}

//busybox的说明函数
int my_help_main(int argc, char * argv[])
{
	printf("busybox only support commond:ls and mkdir\n");
	return 0;
}

//支持的命令列表
const char *applet_names[] = 
{
"my_ls",
"my_mkdir",
"--help", 
"-h"
};

//每个命令对应的实现函数,顺序要和applet_names数组的顺序一一对应
int (*const applet_main[])(int argc, char * argv[]) = 
{
	my_ls_main,	
	my_mkdir_main,
	my_help_main,
	my_help_main,
};

int main(int argc, char * argv[])
{
	int i = 0;
	char *cmdBuf = malloc(256);
	int start_index = 0;

	memset(cmdBuf, 0, sizeof(cmdBuf));


	//打印接收到的命令
#if 0
	while(i < argc)
	{
		printf("argv[%d] = %s \n", i, argv[i]);
		i++;
	}
#endif

	//如果是直接调用的busybox需要特殊处理
	if(strcmp(argv[0], "my_busybox") == 0)
	{
		start_index = 1;
	}

	//在支持的命令列表里查找是否支持该命令
	for(i = 0; i < ARRAY_SIZE(applet_names); i++)
	{
		if (strcmp(argv[start_index], applet_names[i]) == 0)
		{
			applet_main[i](argc, argv);
			break;
		}
	}

	//查找不到输入的命令则不支持该命令
	if(i == ARRAY_SIZE(applet_names))
	{
		printf("command not found\n");
		return -1;
	}

	return 0;
}

3.2、代码的编译和使用

[root#]$ ls -l
total 16
-rwxr-xr-x 1 310793 domain_users 8352 Nov 15 16:25 my_busybox
lrwxrwxrwx 1 310793 domain_users   10 Nov 15 16:25 my_ls -> my_busybox
lrwxrwxrwx 1 310793 domain_users   10 Nov 15 16:26 my_mkdir -> my_busybox
-rwxrw---- 1 310793 domain_users 1857 Nov 15 16:31 test.c

(1)为了避免与系统中的busybox冲突,将可执行程序命名为my_busybox;
(2)本简易版busybox仅支持ls和mkdir命令,所以创建my_ls和my_mkdir命令执行my_busybox;
(3)将代码所在目录导出到环境变量PATH中,可以自动查找到刚才构建的命令(export PATH=命令所在路径:$PATH);

3.3、代码执行效果

[310793@yanfa204_ubuntu18-jk128:weops 222]$ gcc test.c -o my_busybox 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_mkdir 112233
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
112233  my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox my_ls ./
112233  my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox -h
busybox only support commond:ls and mkdir
[310793@yanfa204_ubuntu18-jk128:weops 222]$ 
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox --help
busybox only support commond:ls and mkdir

4、busybox实现框架分析

(1)busybox是个可执行程序,程序入口是main函数,在appletlib.c文件中;
(2)在main中只是实现逻辑控制,并不执行具体的功能,会把输入的指令进行解析,查找指令对应的函数去执行;
(3)在代码中有两个重要的数组,applet_main是函数指针数组,里面是每个命令对应的函数的函数指针,applet_names是保存的命令的字符串,两个数组的元素是一一对应的;
(4)将传递进来的命令先和applet_names数组进行比对,如果匹配上就拿数组下标去applet_main数组取的命令对应的函数并执行;
(5)每个命令都有对应的函数,比如:ls对应"ls_main"函数,cd命令对应"cd_main"函数;

推荐

再难的项目都是基础知识的复杂运用,基础是最重要的。给大家推荐一个学校嵌入式知识的网站,博主在大学时候学习嵌入式知识、找工作的时候都在用这个网站,网站里有C语言、Linux等等的笔试题、面试常问问题等等知识,无论是学习基础知识、面试刷题、交流工作经验都是不错的选择。大家一起进步,欢迎留言交流。
链接:学习神器跳转
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

元数据性能大比拼:HDFS vs S3 vs JuiceFS

元数据是存储系统的核心大脑&#xff0c;元数据性能对整个大数据平台的性能和扩展能力至关重要。尤其在处理海量文件的时候。在平台任务创建、运行和结束提交阶段&#xff0c;会存在大量的元数据 create&#xff0c;open&#xff0c;rename 和 delete 操作。因此&#xff0c;在…

Sass 使用说明

CSS 样式表越来越大、 越来越复杂、越来越难以维护。这就是预处理可以提供帮助的地方。 Sass 为你提供了 CSS 中还不存在的特性&#xff0c;例如变量、 嵌套、混合、继承和其它实用的功能&#xff0c;让编写 CSS 代码变得有意思。 最直接的方式就是在命令行中调用 sass 命令。安…

java和vue的狱警管理系统监狱系统狱务管理系统

简介 狱警管理系统监狱系统狱务管理系统&#xff0c;主要是管理罪犯教育改造、劳动改造、案件管理&#xff0c;罪犯信息管理等 演示视频 https://www.bilibili.com/video/BV1VG411P7YL/?zw&vd_sourcefa4ffd66538a5ca679a754398a6fdb5f 技术&#xff1a;springbootvueel…

git的下载与安装

1. 下载地址 根据自己的电脑配置信息&#xff0c;选用合适的版本进行下载即可&#xff0c;我的电脑上64位win11&#xff0c;所以我选择了64位的widnows版本&#xff0c;下面其他内容也以此版本展开。 windows&#xff1a;Git - Downloading Package macOS&#xff1a;Git - …

Linux-进程管理

基本介绍 在Linux中&#xff0c;每个执行的程序都称为一个进程&#xff0c;每一个进程都分配一个ID号&#xff08;pid) 程序运行起来就产生了进程 ps ps命令用来查看在目前系统中&#xff0c;有哪些正在执行的进程&#xff0c;以及他们执行的状况&#xff0c;可以不加任何参…

K_A05_004 基于 STM32等单片机驱动2X2块(8X8)点阵模块(MAX7219)显示0-9与中文

目录 一、资源说明 二、基本参数 1、参数 2、引脚说明 三、通信协议说明 工作时序 对应程序: 四、部分代码说明 1、接线说明 1.1、STC89C52RC2X2块(8X8)点阵模块&#xff08;MAX7219&#xff09; 1.2、STM32F103C8T62X2块(8X8)点阵模块&#xff08;MAX7219&#xff09; 2、亮…

年产10000吨餐厨垃圾制备氨基酸有机肥工厂设计

目录 摘 要 I Abstract II 第1章 餐厨垃圾概况 1 1.1餐厨垃圾性质 1 1.2餐厨垃圾无害化处理的必要性 1 1.3餐厨垃圾资源化处理工艺 1 1.3.1加工有机肥 2 1.3.2好氧堆肥 3 1.3.3厌氧消化 3 第2章 项目概述 4 2.1氨基酸有机肥的介绍 4 2…2 氨基酸有机肥的性质 4 2.3 氨基酸有机肥…

重温Python基础,都是最基础的知识点

前言 最近有很多朋友刚接触python学的还是有点模糊 还有的朋友就是想重温一下基础内容&#xff0c;毕竟基础不牢地动山摇 行吧&#xff0c;就总结了以下的一些知识点&#xff0c;可以都看看哈 一、开发环境搭建 更多学习资料.点击领取即可 1.1 Python解释器的安装 Python解…

三个最常见OSPF故障的实操检测步骤

大家好&#xff0c;我是小咖老师。 OSPF排错咱们已经讲过几期了&#xff0c;有同学反馈说看不懂&#xff0c;内容太多也不好记&#xff0c;今天咱就挑最常见的三个&#xff0c;给大家分析讲解一下。 1、OSPF邻居建立不成功 2、OSPF不能发现其他区域的路由 3、CPU过高问题 O…

-1- threejs 场景常见的方法和属性

场景常见的方法和属性场景的作用场景的坐标系常用的属性常用的方法场景的作用 场景(THREE.Scene)用于存储物体、光源、摄像机及其渲染所需要的其他的对象集合。THREE.Scene 对象又是被称为场景图&#xff0c;它不仅仅是一个对象数组&#xff0c;还包含了整个场景图树形结构中的…

Android API—序列化与反序列化学习+案例

概述 序列化是指将对象的状态信息转换为可以存储或传输形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后可以通过从存储区中读取或者反序列化对象的状态,重新创建该对象. 序列化:利用ObjectOutputStream,把对象的信息,按照固定的格式转成一串字节值输…

论文笔记: 数据驱动的地震波形反演--健壮性与泛化性研究

摘要: 分享对论文的理解, 原文见 Zhongping Zhang and Youzuo Lin, Data-driven seismic waveform inversion: A study on the robustness and generalization. 1. 论文贡献 提供实时预测的 VelocityGAN与其他基于编码器-解码器的数据驱动地震波形反演方法不同, VelocityGAN …

c++ - 第11节 - stack和queue类

1.标准库中的stack类 1.1.stack类 stack类的文档介绍&#xff1a;https://cplusplus.com/reference/stack/stack/?kwstack 注&#xff1a; 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提…

深度学习项目:男女性别识别【附完整源码】

性别分类对于人机交互应用和计算机辅助生理或心理分析等商业领域的许多应用至关重要&#xff0c;因为它包含有关男女特征差异的广泛信息。 本次案例收集了接近二十万的男女数据集图片。 文章目录性别分类简介使用 Python 进行性别分类的机器学习项目导入相关库和数据模型搭建…

Chapter3 Pytorch与机器学习有关函数(一)

3.1 Tensor中统计学有关的函数 3.1.1 平均值、总和 、累积 1.测试结果1 import torcha torch.rand(2, 2)print(a) print(torch.mean(a,)) print(torch.sum(a)) print(torch.prod(a)) 2.测试结果2&#xff1a;数组对第1维操作 import torcha torch.tensor([[1.0,2.0,3.0],[4.…

【毕业设计】酒店评价情感倾向分析系统 - python 深度学习

文章目录0 前言1 概述2 项目所需模块3 数据3.1 数据说明3.1.1 字段说明3.2 数据处理3.2.1 分词处理3.2.3 停用词处理3.2.4 样本均衡3.2.5 建立多层感知机分类模型3.2.6 训练模型3.2.7 网络检测率以及检测结果4 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里…

回归模型介绍

Datawhale开源学习&#xff0c;机器学习课程&#xff0c;项目地址&#xff1a;https://github.com/datawhalechina/leeml-notes 首先讲机器学习中的&#xff1a;回归&#xff0c;回归Regression可以做哪些东西呢&#xff1f; 股票预测 输入为以往股票走势&#xff0c;预测未来…

HTML标签(下)

一、表格标签 1. 表格的主要作用 表格主要用于显示、展示数据。可以让数据规整、有可读性、有条理。 2. 表格的基本语法 <table><tr><td>单元格内的文字</td>...</tr>... </table><table> </table>是用于定义表格的标签 …

nodejs+vue+elementui零食食品o2o商城系统

目 录 摘 要 1 Abstract 1 1 系统概述 4 1.1 概述 4 1.2课题意义 4 1.3 主要内容 4 2 系统开发环境 5 3 需求分析 7 3.1技术可行性&#xff1a;技术背景 7 3.2经济可行性 7 3.3操作可行性&#xff1a; 8 3.4系统设计规则 8 3.5…

对pure pursuit算法的理解和改进

算法实现 purepursuit的核心其实是一个曲率半径的几何计算。 (x, y)是转换到机器人坐标系上的路径点。L是lookahead distance。r是形成的圆弧半径。D是r和x之间的差值。 根据上面的图形&#xff0c;可以发现有下面的几何关系&#xff1a; 同时通过 y2D2r2y^2 D^2 r^2 y2D2r…