2020-03-25
关键字:
原来 Android 中的 busybox 与 toolbox 是两套程序。
busybox 是一个嵌入式领域常用的软件。它是一个命令集工具,像传统的PC端的Linux系统上的大多数命令的实现都被封装在 busybox 程序中。在嵌入式平台上就可以将这些命令以参数的形式传递给 busybox 工具集,进而实现相应的功能。
那为什么嵌入式平台不能直接像PC端那样,直接将各个命令所对应的程序预置在板端,而非要包装在一个 busybox 中呢?其最主要的原因还是因为这些命令所对应的程序加起来太过庞大,嵌入式平台的存储资源通常是比较有限的,为了节约存储空间,就将这些命令集合在一个程序中。那集合以后的程序又凭什么能比PC端那种分散开来的形式体积要小呢?一个主要的原因是因为这些命令中,有不少命令的实现都是相同的。busybox 就将这些相同的部分提取出来让多个命令共用。如此一来随着命令数量的增多,就能比较大程度地缩减程序体积了。
Android平台是基于嵌入式Linux的。通过串口或者 adb shell 可以像在嵌入式Linux平台上那样敲击命令以实现某些目的。
Android平台的命令系统一般而言可以认为分为两类:
1、busybox 实现的命令系统
2、toolbox 实现的命令系统
toolbox 命令系统是Android平台默认的命令系统。
例如,我们可以像在PC端的Linux系统shell上那样直接敲击常见Linux命令:
root@rk312x:/ # ll drwxr-xr-x root root 1970-01-01 08:00 acct drwxrwx--- system cache 1970-01-01 16:00 cache -rwxr-x--- root root 264120 1970-01-01 08:00 charger dr-x------ root root 1970-01-01 08:00 config root@rk312x:/ # pwd / root@rk312x:/ # cd root@rk312x:/data # root@rk312x:/data # grep -nr "yes" /system/bin/ Binary file /system/bin/busybox matches Binary file /system/bin/cat matches Binary file /system/bin/chcon matches
这里的每一条命令,其实都对应着一个应用程序,它们位于 /system/bin 目录下:
root@rk312x:/ # ll /system/bin/ lrwxr-xr-x root shell 2020-03-21 18:10 cat -> toolbox lrwxr-xr-x root shell 2020-03-21 18:10 chcon -> toolbox lrwxr-xr-x root shell 2020-03-21 18:10 chmod -> toolbox lrwxr-xr-x root shell 2020-03-21 18:10 chown -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 clear -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 cmp -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 cp -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 date -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 dd -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 df -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 dmesg -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 du -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 getenforce -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 getevent -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 getprop -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 getsebool -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 grep -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 hd -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 id -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ifconfig -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 iftop -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 insmod -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ioctl -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ionice -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 kill -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ln -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 load_policy -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 log -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ls -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 lsmod -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 lsof -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 md5 -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 mkdir -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 mkswap -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 mount -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 mv -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 nandread -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 netstat -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 newfs_msdos -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 notify -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 printenv -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 ps -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 r -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 readlink -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 renice -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 restorecon -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 rm -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 rmdir -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 rmmod -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 route -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 runcon -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 schedtop -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 sendevent -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 setconsole -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 setenforce -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 setprop -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 setsebool -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 sleep -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 smd -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 start -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 stop -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 swapoff -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 swapon -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 sync -> toolbox -rwxr-xr-x root root 139048 2020-03-25 22:18 toolbox lrwxr-xr-x root shell 2020-03-21 18:05 top -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 touch -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 umount -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 uptime -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 vmstat -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 watchprops -> toolbox lrwxr-xr-x root shell 2020-03-21 18:05 wipe -> toolbox
只是每一条命令都只是 /system/bin/toolbox 程序的“影分身”而已。
由此可见,这个 Android 平台的 toolbox 与嵌入式Linux平台下的 busybox 一样,是一个命令工具集。我们在串口控制台或 adb shell 上敲命令的时候其实就是在执行这些程序。而这些程序又由于是 toolbox 的分身,就会将这些程序名称,也即命令内容作为程序启动参数传递给 toolbox 的 main(int argc, char **argv) 函数,随后 toolbox 再根据不同的命令执行不一样的动作。
toolbox 的源码位于Android工程源码的以下目录:
./system/core/toolbox
toolbox 程序的入口函数位于 toolbox.c 中:
这份源码本质上并不复杂,有兴趣的同学可以自行去研究研究。同样的,如果你有特殊需求,也完全可以在这里添加自己的命令程序。
busybox 一般来说都是直接预置可执行程序在Android系统源码中的,并不像 toolbox 那样会有源代码。
不过 busybox 有官方网站,上面刊载了各版本的源码与文档等资料:
下载地址:http://www.busybox.net/
在 Android 中,busybox 并不像 toolbox 那样将各命令都以软链接的形式释放出来。
如果想使用 busybox 的命令系统,则必须将命令以启动参数的形式传递给 busybox 程序:
busybox ls -al busybox pwd busybox find -name "*.apk"
我们也可以通过下面这条命令列出 busybox 支持的所有命令:
busybox --list
busybox 命令系统与 toolbox 命令系统在表现形式上可能是不一样的,例如,同样是 ls -al 命令,二者所列举的信息却是有所不同的:
root@rk312x:/sdcard # ls -al drwxrwxr-x system sdcard_rw 1980-01-01 00:00 .android_secure drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Alarms drwxrwxr-x system sdcard_rw 1980-01-01 00:00 DCIM drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Download drwxrwxr-x system sdcard_rw 1980-01-01 00:00 LOST.DIR drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Movies drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Music drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Notifications drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Pictures drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Podcasts drwxrwxr-x system sdcard_rw 1980-01-01 00:00 Ringtones root@rk312x:/sdcard # root@rk312x:/sdcard # busybox ls -al total 96 drwxrwxr-x 13 system sdcard_r 8192 Jan 1 08:00 . drwxrwxr-x 9 root system 0 Jan 1 08:00 .. drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 .android_secure drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Alarms drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 DCIM drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Download drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 LOST.DIR drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Movies drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Music drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Notifications drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Pictures drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Podcasts drwxrwxr-x 2 system sdcard_r 8192 Jan 1 1980 Ringtones
因此,如果我们发现某个命令不太能符合需求,则可以尝试一下使用另一套命令系统。同时,两套命令系统所包含的命令也会有差异。如,toolbox 就不包含 find 命令,而 busybox 却支持 find 命令。
最后再额外提一点:在Android平台,无论是串口控制台还是adb的shell,其本质都是在一个登录了的shell程序中运行。就像PC端Linux的 shell 机制一样。Android平台上默认的shell程序是 /system/bin/sh 程序。在 init.rc 中可以发现串口控制台其实就是一个 /system/bin/sh 程序的别名:
而 adb 的 shell 就更不用说了。