热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Busybox】Busybox源码分析03|终篇

导读命令是linux操作系统独特的艺术,虽然Windows操作系统也有命令,但相比之下,linux的命令更加强大且具有魅力。大多数桌面和




导读

命令是linux操作系统独特的艺术,虽然Windows操作系统也有命令,但相比之下,linux的命令更加强大且具有魅力。大多数桌面和嵌入式linux发行版都包含了很多功能完备的命令行工具,然而busybox短小精悍,可以替代这些工具,在资源有限的嵌入式linux系统中更具有优势。


busybox的使用

站在使用的角度,busybox的使用非常简单,如果配置和编译过linux内核,将会发现使用思路是一样的:


  • (1)获取busybox源码。

  • (2)在终端执行一个配置工具(可以使用make menuconfig编译出宿主机上的配置图形界面进行配置),如下图:

在工具中可以指定交叉编译器路径想要的命令busybox的支持特性安装路径等配置。

对于busybox的配置有以下几种:1、defconfig,缺省配置,也是默认配置选项。2、allyesconfig,全选配置,也就是选中busybox的所有功能。3、allnoconfig,最小配置。在实际使用中,图形化配置方式是一种较常使用的方法。


  • (3)在终端运行make命令来构建busybox源码。

  • (4)将编译出的二进制工具和一系列的符号链接安装到我们的目标系统中。(还需要将相关的动态链接库安装到对应的路径下,确保busybox下的程序能正常启动运行)。

通过以上步骤,就可以使用busybox了。


busybox的启动方式

在linux内核启动后期,会尝试执行/sbin//etc/bin三个目录中的init。在busybox下的init运行后,首先则会提示busybox找到不/etc/init.d/rcS文件(编译构建出的busybox本身是没有这个路径下的rcS文件的),这是busybox搜索的默认初始化脚本文件,我们则可以创建该文件,至于文件中写些什么内容,后文会描述到。

在busybox完成初始化后,会显示一条提示信息,要求我们按下回车键,以激活一个控制台。当busybox检测到回车键被按下后,则会执行一个ash(busybox的内置shell)会话,然后我们就可以在其中输入命令了,busybox会根据我们输入的命令执行对应的命令操作。

一般情况下,一个基于busybox构建的根文件系统,我们能够使用大约100多个工具,包括:核心工具、文件处理工具、网络工具和一个shell程序,基于这些工具,我们则可以构建自己的系统应用程序了。


rcS初始化脚本

在初始化一个基于busybox的嵌入式系统时,rcS初始化脚本是首选的方式。由于不同应用场景和需求,rcS启动脚本中的内容都会不一样:有的会创建目录、循环执行子目录中脚本文件(这种方式可以划分多个脚本文件,清晰明了,便于管理)、挂载文件系统、启动linux服务,启动相应的应用程序等,这里描述一个最简单的rcS脚本文件:

#!/bin/sh
mount -t proc /proc/proc
syslogd
klogd
ifconfig lo 127.0.0.1
xinetd
busybox sh
/bin/my_app

上述脚本中依次执行的操作是:

(1)挂载/proc文件系统,挂载点是/proc目录。

(2)开启系统的日志程序,便于捕捉系统启动中出现的问题。

(3)开启系统日志守护程序。

(4)配置系统的本地回环接口。

(5)启动英特网超级服务器xinetd

(6)启动shell。

(7)启动运行我们自己设计的应用程序my_app


busybox重要文件

在busybox安装目录/etc下,存在几个必须的基本文件和目录:


(1)inittab文件

/etc/inittab文件中不同action类型有着先后顺序:



SYSINIT > WAIT > ONCE > RESPAWN | ASKFIRST


在busybox源码中,定义如下:

#define SYSINIT 0x01 //最先开始启动,并且执行完毕后才会进入WAIT。
#define WAIT 0x02 //在SYSINIT之后启动,并且执行完毕后才会启动ONCE。
#define ONCE 0x04 //在WAIT之后启动,但是后面的并不需要等待执行完毕。
#define RESPAWN 0x08 //在ONCE之后启动,退出后会重新启动。
#define ASKFIRST 0x10 //类似RESPAWN,但是需要确认。
#define CTRLALTDEL 0x20 //收到SIGINIT后执行,并且执行完毕后开始执行RESPAWN和ASKFIRST。
#define SHUTDOWN 0x40 //在kill所有进程之后启动SHUTDOWN。这是为RESTART或者底层halt/reboot/poweroff做准备。
#define RESTART 0x80 //收到SIGQUIT后执行RESTART。

在busybox的init程序中,会读取/etc/inittab文件,该文件中的内容由若干条指令组成,每条指令的结构都是一样的,以“:”分隔的4个字段组成,格式如下:



:::



  • id:每个指令的标识符,不能重复。但是对于 busybox 的 init 来说,
    有着特殊意义。对于busybox而言用于指定启动进程的控制tty,一般我们将串口或者LCD屏幕设置为控制tty。
  • runlevels:对 busybox 来说此项完全没用,所以空着。
  • action:表示动作,用于指定可能用到的动作。busybox 支持的动作如下图所示:


  • process:表示具体的动作操作,比如程序、脚本或命令等。

例如下图所示的配置选择:


(2)fstab文件

fstab文件用于指定在linux启动以后自动配置哪些需要自动挂载的分区,文件中内容格式如下:





  • file system:要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
  • mount point:挂载点。
  • type:文件系统类型,例如ext2ext3procromfstmpfs等等。
  • options:挂载选项,在ubuntu中输入man mount命令可以查看具体的选项。一般使用defaults,也就是默认选项,defaults 包含了 rw、suid、 dev、 exec、 auto、 nouser 和 async。
  • dump:该参数值设置为1,表示允许备份,设置为0表示不备份,在实际应用中我们一般不备份,因此该参数值设置为0。
  • pass:磁盘检查设置,参数值设置为0表示不检查。根目录‘/’设置为 1,其他的都不能设置为1,其他的分区从2开始。一般不在fstab中挂载根目录,因此这里一般设置为0。

例如下列的配置选择:


(3)profile文件

该文件不是必须的,该文件是shell读取的配置文件。profile脚本文件是传递给ash程序的,在ash程序中会读取profile文件中的内容,作为环境变量的参数配置。
例如下列配置选择:

上述配置脚本中,首先设置PATHPS1环境变量,PS1变量表示:我们在使用命令行时的命令提示符的格式,每一次按下回车后系统都会调用PS1变量,产生新的命令提示符等待输入。然后设置了PAGEREDITOR环境变量。接着,循环执行/etc/profile.d/目录下的所有的shell脚本。


(4)passwd文件

passwd文件由多条记录组成,例如如下的内容:

root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/false
bin:x:2:2:bin:/bin:/bin/false
sys:x:3:3:sys:/dev:/bin/false
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/false
www-data:x:33:33:www-data:/var/www:/bin/false
operator:x:37:37:Operator:/var:/bin/false
nobody:x:65534:65534:nobody:/home:/bin/false
dbus:x:1000:1000:DBus messagebus user:/var/run/dbus:/bin/false
systemd-bus-proxy:x:1001:1005:Proxy D-Bus messages to/from a bus:/:/bin/false
systemd-journal-gateway:x:1002:1006:Journal Gateway:/var/log/journal:/bin/false
systemd-journal-remote:x:1003:1007:Journal Remote:/var/log/journal/remote:/bin/false
systemd-journal-upload:x:1004:1008:Journal Upload:/:/bin/false
systemd-network:x:1005:1009:Network Manager:/:/bin/false
systemd-resolve:x:1006:1010:Network Name Resolution Manager:/:/bin/false
systemd-timesync:x:1007:1011:Network Time Synchronization:/:/bin/false

(注:不同linux系统环境,在文件中的内容可能会不一样。)

每条记录占一行,记录了一个账号的所有相关信息,单条记录由7个字段组成,每个字段之间用“:”隔开,其格式如下:



username:password:UID:GID:connection:home dictionary:shell


『字段含义』


  • username:用户名

    它唯一地标识了一个用户帐号,用户在登录时使用的就是它。

  • password:该账户的口令

    passwd文件中存放的密码是经过加密处理的。Linux的加密算法很严密,其中的口令几乎是不可能被破解的。

  • User ID用户识别码,简称UID

    Linux系统内部使用UID来标识用户,而不是用户名。UID是一个整数,用户的UID互不相同。 0是系统管理员账号,1-499是系统保留账号,500+即一般账号。

  • Group ID用户组识别码,简称GID

    不同的用户可以属于同一个用户组,享有该用户组共有的权限。与UID类似,GID唯一地标识了一个用户组。 用usermod -g 设置。

  • comment 这是给用户帐号做的注解

    它一般是用户真实姓名、电话号码、住址等,当然也可以是空的。

  • home directory 主目录

    这个目录属于该帐号,当用户登录后,它就会被置于此目录中,就像回到家一样。一般来说,root帐号的主目录是/root,其他帐号的家目录都在/home目录下,并且和用户名同名。 用usermod -d设置。

  • login command 用户登录后执行的命令

    一般来说,这个命令将启动一个shell程序。例如,用bbs帐号登录后,会直接进入bbs系统,这是因为bbs帐号的login command指向的是bbs程序,等系统登录到bbs时就自动运行这些命令。


总结

本文是小生分析busybox源码的最后一篇,描述了经busybox构建完成后的最小根文件系统中需要添加哪些文件以及文件的解析过程。

从使用者的角度来看,能够编译构建busybox,能够填充最小的根文件系统满足实际的应用需求,就已经差不多了。

从设计的角度来看,busybox的源码和linux内核、u-boot源码一样,具有出色的设计思维和优秀的构建思想在里面。



👉 站在巨人的肩膀上,『敬畏』、『热情』、『分享』








推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • 本文介绍了在Web应用系统中,数据库性能是导致系统性能瓶颈最主要的原因之一,尤其是在大规模系统中,数据库集群已经成为必备的配置之一。文章详细介绍了主从数据库架构的好处和实验环境的搭建方法,包括主数据库的配置文件修改和设置需要同步的数据库等内容。MySQL的主从复制功能在国内外大型网站架构体系中被广泛采用,本文总结了作者在实际的Web项目中的实践经验。 ... [详细]
author-avatar
love28119_529_700
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有