采用busybox 代替android 自带的shell

折腾了几天,被Android那点儿少得可怜的shell命令折磨的死去活来,终于下定了革命的决心。看一下怎么把渺小的toolbox替换成伟大的busybox吧。先大致描述一下Android系统中的shell程序部分。

shell实现分为两部分:

一、shell解释器和内置命令

源码位于system/core/sh目录下,主要完成shell命令的解释查找,对于builtins.c中包含的内置命令,直接执行,对于toolbox的扩展命令,间接调用toolbox程序完成。

二、toolbox扩展命令

主要完成扩展命令的执行,每一个扩展命令对应一个name_main函数,如ls命令,对应ls_main函数。同时,每一个扩展命令都由一个system/core/toolbox/目录下面的.c文件实现。toolbox.c会根据这个目录下面的.c文件生成tools.h头文件,并在system/core/toolbox/Android.mk文件中为每个命令生成指向toolbox的连接。toolbox的实现结构使它扩展一个命令很容易。

假设现在我们自己想手工添加一个shell命令mycommand,只要在system/core/toolbox/目录下面新建一个mycommand.c文件,并在里面实现一个mycommand_main函数,然后在system/core/toolbox/Android.mk中添加mycommand.c即可。Android.mk会自动把它编译进toolbox程序,并在编译生成的Android系统/system/bin目录下为这个命令生成一个指向toolbox的连接。

 

接下来翻译一下网上的一篇文章,借助它,可以把Android自带的toolbox替换成busybox。 

Installing Busybox command line tools

英文原文地址:

https://gforge.ti.com/gf/project/omapandroid/wiki/?pagename=Installing+Busybox+command+line+tools

在Android系统中安装busybox命令行工具 

本文简单地介绍了怎么把busybox安装到Android的文件系统中去。

如果你想直接安装,可以从下面的地址下载我已经预编译好并在Android2.1系统上试验成功的busybox,然后直接跳过下面的安装步骤。

http://download.csdn.net/source/3093680 

一、编译busybox

1、下载busybox的最新版本,本文写作时最新版本是1.13.3。

下载地址:http://www.busybox.net/

2、解压源码:

tar jxf busybox-1.13.3.tar.bz2

3、运行menuconfig对busybox进行配置

cd busybox-1.13.3/

make menuconfig

4、在menuconfig中设置以下选项

Busybox Settings --> Build Options --> Build Busybox as a static binary (no shared libs)  -  Enable this option by pressing \"Y\"

Busybox Settings --> Build Options --> Cross compiler prefix  -  Set this option equal to \"arm-none-linux-gnueabi-\"

Busybox Settings --> Installation Options --> Don\'t use /usr  -  Enable this option by pressing \"Y\"

5、把交叉编译器的地址导入到环境变量:

export PATH=/opt/arm/arm-2007q3/bin:$PATH

6、编译busybox

make

 

二、安装busybox

把busybox安装到Android系统中去,做这几步:

1、在Android系统根目录下创建一个/bin目录。

mkdir //bin

2、把编译出来的busybox复制到/bin目录下

cp busybox //bin

3、把busybox安装到Android机器中

cd /bin

./busybox --install

 

三、把busybox作为默认shell

需要像下面这样编辑一下init.rc

1、编辑console服务,让它默认运行busybox

service console /system/bin/sh  ->  
service console /bin/sh

 

2、把busybox路径加入到环境变量中

 

export PATH      /sbin:/system/sbin:/system/bin:/system/xbin  -->  
export PATH /bin:/sbin:/system/sbin:/system/bin:/system/xbin

 

 

注: 

我使用busybox时,只是想简单地增加一些命令,把toolbox一些功能不是很全的命令替换掉,所以操作上没有上面说的那么复杂。

下面是我的替代方案,可以试一下:

1、把busybox复制到/system/bin目录下。

adb push busybox /system/bin

 

2、把要添加的命令通过ln建立到busybox的连接。

比如,Android自带的toolbox是没有test这个命令的。我们要添加test命令就可以:

cd /system/bin

ln -s busybox test

 

这样,用户通过机器上的shell执行test命令时,就会调用busybox中实现test功能的applet。

 

对于一些原有的命令,如ls、chown等,如果不想用toolbox,也可以把它们的连接目标指向toolbox,拿chown来举例。

cd /system/bin

rm chown

ln -s busybox chown

 

 

这样做,最大的好处就是保证对系统的改动最少,又可以最大限度的扩展shell功能。

 

 

为Android加入busybox工具(三篇)

 

  2. 在启动emulator后,通过命令adb shell进入。

2.下载busybox以及交叉编译工具

1. 首先去busybox主页 下载最新版本的busybox源代码.

2. 下载交叉编译工具: GNU Toolchain for ARM Processors 

    下载地址:http://www.codesourcery.com/gnu_toolchains/arm/download.html

    其中第一项选择ARM EABI或ARM GNU/Linux,第二项选择IA32 GNU/Linux TAR即可。

    最后得到一个arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2文件

    将压缩包解压到linux下某个目录, 并设置好环境变量, 使之能找到前缀为"arm-none-linux-gnueabi-"的交叉编译工具.

3.对busybox进行相应配置

3. 进入busybox源码目录.

     先执行make menuconfig命令对编译过程进行配置.  过程如下:

     Busybox Settings -> Build Options ->

     [*] Build BusyBox as a static binary (no shared libs) 这个要选上,因上这样子编译出来的busyBox才是可以独立运行的。
(/home/jo/tool/arm-2008q3/bin/arm-none-linux-gnueabi-) Cross Compiler prefex 这是交叉编译器的"路径+前缀",要根据具体的情况来设置。
Busybox Settings -> Installation Options->
[*] Don’t use /usr        这样子编译出来的busybox才不会安装到你主机的/usr目录下。一定要选上。

4 执行make编译源码.  如果编译过程中产生无法找到头文件的错误, 可指定交叉编译器用到的头文件所在路径. 如

   $make -I ./home/jo/tool/arm-2008q3/arm-none-linux-gnueabi/libc/usr/include/

5 编译成功后将得到一个名为busybox的可执行文件.

4.把busybox移植入android

6 在Android的console下建立目录/data/busybox, 并使用下面的命令将文件busybox复制该目录中:

   adb push busybox /data/busybox

7 从Android的console进入/data/busybox目录, 为可执行文件busybox加上可执行属性: chmod 775 busybox

8 这时我们就可以使用busybox工具了, 如果希望在任何目录下都可以直接使用bosybox,则需要将路径/data/busybox export到path环境变量中:

   export PATH=$PATH:/data/busybox

9 设置环境变量之后, 在命令行输入busybox, 即可看到其用法, 如:

   在当前目录及其子目录中查找名为init.rc的文件可使用以下命令:

   $busybox find . -name init.rc 

10 安装busybox

   通过执行./busybox --install -s 我们会看到出现一些错误, 原因是因为Android系统的根目录和/sbin目录是只读的.  因此我们无法把一些常用命令安装到/bin目录下, 也不能修改/init.rc文件来设置PATH环境变量. 

   对于如何执行命令busybox --install -s 的默认安装路径, 这里我还不太清楚, 或许跟Makefile和编译busybox的相关设置有关. 

   尽管我们不可以在Android里面通过执行busybox --install -s 命令来安装常用命令, 我们却可以通过另外一个方法来把常用命令安装到Android里面.  

   方法很简单, 可以先在外面的linux系统中执行make install命令把相关的命令提取出来. 然后再通过命令adb push ./_install/bin /data/busybox/bin 把这些常用命令复制进Android系统中. 注意: make install安装命令的所在路径可通过执行make menuconfig进行设置, 默认为./_install目录下面.

   这样,我们就不用每次使用busybox提供的一个命令时, 都要在前面加上busybox了.

11 修改/init.rc文件设置环境变量.

     要提醒的是, 修改PATH环境变量的时候, 应该把busybox常用命令的路径"/data/busybox/bin"放在Android的常用命令路径"/system/bin"的前面, 否则, 先查找得到的将不是busybox的命令,  可以这样设置:

     export PATH /data/busybox/bin:/sbin:/system/sbin:/system/bin:/system/xbin

大家是否有过这样的经历,在命令行里输入adb shell,然后使用命令操作你的手机或模拟器,但是那些命令都是常见Linux命令的阉割缩水版,用起来很不爽。是否想过在Android上使用较完整的shell呢?用BusyBox吧。不论使用adb连接设备使用命令行还是在手机上直接用terminal emulator都可以。

一、什么是BusyBox ?

BusyBox 是标准 Linux 工具的一个单个可执行实现。BusyBox 包含了一些简单的工具,例如 cat 和 echo,还包含了一些更大、更复杂的工具,例如 grep、find、mount 以及 telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀.简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令。(摘自百度百科)

二、在Android上安装BusyBox

准备:

0. 先要把手机给Root了,具体教程这里就不提供了,网上有很多。

1. 下载BusyBox的binary,打开这个地址 http://www.busybox.net/downloads/binaries ,选择最新版本,然后下载对应你的设备架构的版本,这里我下载了busybox-armv6l,下面将以这个文件名为示例。

2. 需要有一个命令行的环境,在电脑上使用adb或在手机上使用terminal emulator。

3. 连接手机和电脑,手机的USB Mode设置成None(仅充电),并且开启USB调试模式。

安装:

1. 将busybox-armv6l重命名为busybox

2. 将busybox传入手机的SD卡,可以使用下面的命令或自己想其他办法。

打开terminal(Linux,Mac)或cmd(Windows)

adb push ~/Desktop/busybox /mnt/sdcard

其中的~/Desktop请根据自己的情况替换成正确的路径

3. 输入以下命令,为了在/system目录写入文件

mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system

使用 ls 检查一下 /system 里是否有 xbin 目录,没有的话输入 mkdir xbin 创建,因为本示例是要把busybox安装到 /system/xbin 。

4. 复制 busybox 文件到 /system/xbin,并为其分配“可执行”的权限

cp /mnt/sdcard/busybox /system/xbin

5. 这时就可以使用 busybox 的命令了,例如以前没有清屏的clear命令,现在只需输入 busybox clear 就可以实现清屏功能,使用完整版的 ls 只需输入 busybox ls 。

但是每次前面都加上个busybox太麻烦了,所以我们还要继续完成安装。

在 /system/xbin 下输入

如果想安装到别的目录,则把点替换成别的路径。

至此就安装完成了,比较一下原来的 ls 命令和 busybox 里的 ls 命令。

常见错误:

1. 如果安装时出现这样的错误,

busybox: /bin/zcat: No such file or directory

busybox: /sbin/zcip: Invalid cross-device link

说明没有输入安装路径,正确的示例 busybox --install /system/xbin

2. 如果出现这样的错误,

cp: /system/xbin/busybox: Read-only file system

说明没有正确输入上面第三步的mount命令。

小技巧:

1. busybox 里有 ash 和 hush 还有 sh 这几种 shell,在命令行输入 ash 或 hush,可以像在 bash 里那样,通过按上下键选择刚才输入的命令。

2. android系统本身就有ls命令,busybox里也有ls,输入ls时调用的是android的ls,那么想用busybox的ls就要每次都在前面加个busybox吗?不用,使用alias命令可以搞定。

同样的,cp、mv等二者都有的命令都可以这样搞定。也可以通过修改 /init.rc 来解决。

英文文档

To build busybox

Download the latest version of busybox from the following website. At the time of writing the latest version was v.1.13.3.

http://www.busybox.netExtract the busybox source:

tar jxf busybox-1.13.3.tar.bz2Configure busybox by running menuconfig

cd busybox-1.13.3/
make menuconfigIn menuconfig set the following options

Busybox Settings --> Build Options --> Build Busybox as a static binary (no shared libs)  -  Enable this option by pressing "Y"
Busybox Settings --> Build Options --> Cross compiler prefix  -  Set this option equal to "arm-none-linux-gnueabi-"
Busybox Settings --> Installation Options --> Don't use /usr  -  Enable this option by pressing "Y"Export path to where the cross-compiler is located on the host, for example:

export PATH=/opt/arm/arm-2007q3/bin:$PATH
Build busybox

make

Installing Busybox


--------------------------------------------------------------------------------

To install busybox in the target file-system

Create a /bin directory in the target file-system. For example:

mkdir /<path-to-Android-fs>/binCopy the busybox binary to the /bin directory in the target file-system

cp busybox /<path-to-Android-fs>/bin Install the busybox command line tools on the target by executing the following commands:

cd /bin
./busybox --install

Make the Busybox shell the default shell

--------------------------------------------------------------------------------

To make the busybox shell the default shell, edit the file "init.rc" in the target file-system as follows:

Edit the console service so that it runs the busybox shell and not the default shell by replacing:

service console /system/bin/shWith:

service console /bin/shAdd the path of the busybox command line tools to the system path variable by replacing:

export PATH /sbin:/system/sbin:/system/bin:/system/xbinWith

export PATH /bin:/sbin:/system/sbin:/system/bin:/system/xbin

 

给android添加busybox

默认情况下,android使用的是精简的toolbox工具,相对习惯了busybox的朋友来说,使用toolbox
简直无法忍受。网上介绍了一些移植busybox到android平台的文章,但是用起来总感觉有些不顺手,比如有
网友将busybox放在了/data目录,这可是ram目录啊,掉电后busybox也会根着消失。还有些网友直接将
toolbox给替换了,要知道toolbox有一些命令是android所特有的,如果直接干掉toolbox,会有很大的
隐患,比如setprop,am等将无法使用了。下面给出多种移植方法,并给出各自的优缺点比较。

方法一:使用adb工具

第一步:下载 busybox 源码,编译生成 busybox 工具

这里使用 busybox-1.13.3。
解压 busybox-1.13.3-mini6410.tar.gz,在 busybox-1.13.3 目录下修改 makefile 文件,修
改的内容如下:
ARCH ?= arm
CROSS_COMPILE ?= arm-fsl-linux-gnueabi-
注意,这里交叉编译工具使用的和内核相同的工具,arm-fsl-linux-gnueabi-所在路径需
在 bashrc 中声明。
执行 make menuconfig 配置 busybox:
在 Busybox Settings -> Build Options 中:
在 Busybox Settings -> Busybox Library Tuning 中,确保选中 Tab completion 选项,支持
Tab 扩展键:
在 Busybox Settings ---> Installation Options 中:
然后执行 make,make install,这时将会在 busybox-1.13.3 目录生成 busybox 工具,同
时在_install\bin 目录会生成很多指令工具。

第二步:将busybox以及指令工具拷贝到开发板上

启动开发板,进入android文件系统,通过USB电缆连接开发板和PC机,在PC端打
开MS-DOS工具,使用 adb devices 查询 PC 机是否与开发板通信正常。
在开发板的 android 终端新建/data/busybox 目录:
mkdir -p /data/busybox
使用 adb push 指令将上一步生成的文件拷贝到开发板的/data/busybox 目录:
adb push \\192.168.254.128\share\tools\busybox-1.13.3\_install\bin /data/busybox/bin
由于文件比较大,这一步需要拷贝几分钟。
由于 mx53 开发板的文件系统全放在 SD 卡上,因此拷贝完后,一定要使用 sync 指令
同步文件系统,确保数据全写到 SD 卡上。

第三步:其它参数的设置

在开发板 android 终端进入/data/busybox/bin 目录,将包括 busybox 在内的所有文件的
权限全改为 777
cd /data/busybox/bin
chmod 777 *
到这一步,执行 busybox 时,仍然会提示找不到 busybox,必须做如下声明:
export PATH=$PATH:/data/busybox/bin
这时,已经可以使用 busybox 的各种指令,包括 find,cp 了,但是仍然无法使用 TAB
命令。执行如下指令:
busybox sh
再试试 TAB 命令,已经正常工作了。注意,TAB 键正常工作的先决条件是在 busybox
中添加了 Tab completion 支持。
我们不妨使用 ls 命令列出当前目录存在的文件,发现它的排列仍然是一长条,看起来
很不习惯,远不像我们使用的 busybox 那样整齐。事实上这时候 ls 仍然为 android 默认的
toolbox 带的 ls。解决方法很简单,使用 busybox 强大的 find 功能找到 toolbox 的 ls 所在:
cd /
find . –name ls
我们发现它在/system/bin 目录下,直接进入该目录,将 ls 删除即可。还有很多其他的
指令,像 rm 等,都可以一并删除。但是我们发现它并不能轻而易举的被删掉,提示如下
信息:
rm failed for rm, Read-only file system
原来/system 目录是只读的。在开发板的 andrid 终端使用下面的命令将它强行切换为可
读写目录:
mount -o remount,rw -t ext4 /dev/block/mmcblk0p2 /system
注意,mx53 开发板的文件系统存在 SD 卡的第二分区,即 mmcblk0p2,且该分区已被
格式化为 ext4。如果使用其他分区或是使用其他格式,需修改相应的参数。
这时我们就可以删除/system/bin 下的文件了,如下图:
再执行 ls 指令,这次排列已经相当整齐了。
值得注意的是,将数据保存在/data 目录下,断电后数据就丢失了,因为/data 保存在
ram 中。它的优点就是不用重新制作系统映像。

方法二:直接替换toolbox

android 源码编译完成后,会在源码的根目录生成 out 目录,在里面找到 mx53_loco 目
录,找到/system/bin 目录,删除里面的 toolbox 文件,然后将前面生成的 busybox 下的
_install/bin 目录下的所有文件全部拷贝到/system/bin 目录,然后重新编译 android 源码,注
意千万不要将 out 下的文件删除了,否则编译源码需要好几个小时。重新编译只用几分钟
时间。将新生成的 system.img 映像文件下载到 SD 卡中,重启开发板,就能正常的使用
busybox 了。
由于这样直接替换了toolbox的大部分命令,会破坏toolbox的完整性,部分功能将不能正常使用了,如
am等。它的优点是移植简单。

方法三:在toolbox的基础上增加busybox

方法二将busybox的各种链接都覆盖到/system/bin目录了,事实上,我们可以只将busybox这个文件
拷贝到/system/bin目录,如果需要用到busybox,只需在前面添加busybox就可以了,比如列出当前
目录的文件:
busybox ls
这种方法移植简单,但是使用起来每次都需要在前面添加一个busybox,比较繁琐,而且不具备指令补全功能,
一旦敲错了,意味着要重敲一遍命令。优点就是不会破坏android的功能,如am等都能正常使用。

方法四:在toolbox的基础上新增busybox脚本,支持两个脚本切换

该方法基本上能够弥补上面的一些方法的不足,推荐大家使用。移植起来也不复杂。

第一步:交叉编译busybox,生成需要的文件

第二步:在android的生成目录/out/target/product/imx53_loco/system下新建目录busybox,并将
第一步生成的busybox以及所有链接文件全拷贝到该目录;

第三步:修改/out/target/product/imx53_loco/root/init.rc文件,
export PATH /sbin:/system/sbin:/system/bin:/system/xbin:/system/busybox
上面添加了busybox的声明路径。

第四步:重新编译生成映像文件,更新uramdisk.img,system.img两个文件,注意init.rc文件存放在uramdisk.img
中,因此必须更新!

第五步:重启开发板,这时应该能使用busybox了,只不过需要在前面添加busybox指令。如:
busybox cp
但是使用ls命令时,仍然排列很不规范,明显是toolbox的杰作。使用busybox ls就没有问题了,但是每次都需要
加busybox,很不方便,直接将/system/bin下的ls删掉,再使用ls指令,就不会有问题了。类似其他的指令也可以
使用相同的方法。注意造成不要破坏toolbox。

第六步:尽管这时已能使用busybox,但是命令行的提示符仍然只有一个#号,而且命令不具备补全功能,因为这时我们使用
的仍然是android的脚本。执行以下命令:
busybox sh
再试试,功能补全功能已经正常,而且提示符前面不再单单一个#号,而是所在路径了。不过,这时am指令已经无法使用了,
要知道am指令在android上起着非常大的作用。当需要使用am指令时,我们只需要执行下/system/bin的sh即可,执行完
之后,再使用busybox sh命令切换到busybox的shell,二者互不影响。

 

posted @ 2015-05-19 13:03  IAmAProgrammer  阅读(2676)  评论(0编辑  收藏  举报