最近发现用到的很多功能都是busybox,或是kernel自带的一些功能。但没有认真去分析下,这里记录一些查到的资料。
一、busybox的运行与调试
我们能看到的所有功能程序,包括date,udhcpc...很多的这些进程他都是和最后连接到busybox的bin文件下。
我们调试新编的busybox时,可以不用去直接替换文件系统里面的bin文件,可以直接使用 busybox date这样就可以在后台打印出我们直接输入date产看到的时间信息
二、busybox的源码框架
(如何去读源码)
若是要更好的理解Busybox的实现,那么咱们应该将它划分为两个部分:
(1)各个命令(applets)的实现,其实你们也发现了,不少目录都属于这部分,只不过它们按照功能细分了,例如网络命令(networking目录)、编辑命令(editors目录)等,这部分也能够理解为是Busybox(各个命令)的启动代码部分
(2)libbb目录下的内容,也就是Busybox(各个命令)的共享代码部分。
1)applets的实现:
目录”applets”包含了Busybox的启动代码(applets.c和Busybox.c),以及几个包含独立命令的子目录。
Busybox从applets/busybox.c文件中的main()函数开始执行,该main函数将变量applet_name赋值为argv[0],而后调用applets/applets.c文件中的run_applet_and_exit()函数继续执行。run_applet_and_exit()函数使用applets[]数组(定义在include/busybox.h中,在include/applets.h中填充内容)将程序的控制权传递给APPLET_main()函数(例如:cat_main()或sed_main())。独立的applet命令从这里开始接管执行。
这就是为何Busybox下的不一样名称的命令调用不一样的功能:main()函数使用argv[0]做为参数在applets[]数组中查找合适的指向APPLET_main()函数的函数指针。
Busybox中的applets一样能够经过复用器”busybox”applet(查看libbb/appletlib.c文件中的函数Busybox_main())调用,以及经过单独的shell(在shell/*.c中使用grep命令查找SH_STANDALONE)。关于使用这两种机制调用命令更多的信息能够查看官网信息,其实它们只是经过不一样的路径调用APPLET_main()函数。
命令(applet)子目录(archival,console-tools, coreutils, debianutils, e2fsprogs, editors, findutils, init, loginutils,miscutils, modutils, networking, procps, shell, sysklogd, and util-linux)对应着menuconfig中的子菜单的配置项。每个子目录都包含实现相应子菜单命令的代码,每个子目录下有一个Config.src文件,用于产生menuconfig菜单,有一个Kbuild.src文件用于生产相似Makefile功能的文件。
运行时的—help信息是保存在usage_message[]数组中的,该数组经过从usage.h中获取帮助信息,在applets/applets.c中初始化该数组。在编译的过程当中,这些帮助信息一样被用于在docs目录下产生Busybox的文档(html,txt和man页面格式)
2)libbb目录
在libbb的共同主题包括分配功能测试失败和停止程序的错误消息,以便调用者不用测试返回值(xmalloc(),xstrdup()等),通过封装的open(),close(),read(),write(),这些通过封装的函数能够测试本身的失败和/或自动重试,也包含链表管理功能的函数(llist.c),命令行参数的解析(getopt32.c),和一大堆其它的内容。