Android Recovery 移植 Busybox

这里说的是源码的编译环境下, 如何完整的移植一份Busybox。

如果在Recovery下开发新功能, 没有Busybox的话, 调试起来很麻烦(不能执行 adb shell)。

这里在推荐一个小技巧: 可以通过 adb pull /tmp/recovery.log ./  来看当前运行的Log。


移植的方案有很多(我自己就看到过不止3中), 我这里说一个比较简单的, 而且移植的效率比较高。

这个是CM的Busybox移植方案, 分四步:

1:   Busybox的移植

这个可以直接去下载一份CM的Busybox的源码, 方法就百度下吧。 放到 external 目录下

2:adbd的修改

adb shell 默认执行的 shell 是 system/bin 下的shell, 这里可以修改这个shell的默认路径为 /sbin/sh。 

diff --git a/adb/services.c b/adb/services.c
index 21b08dc..fc5cb03 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -301,8 +301,10 @@ static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg
 
 #if ADB_HOST
 #define SHELL_COMMAND "/bin/sh"
+#define ALTERNATE_SHELL_COMMAND ""
 #else
-#define SHELL_COMMAND "/system/bin/sh"
+#define SHELL_COMMAND "/system/bin/sh123"
+#define ALTERNATE_SHELL_COMMAND "/sbin/sh"
 #endif
 
 #if !ADB_HOST
@@ -344,6 +346,9 @@ static int create_subproc_thread(const char *name, const subproc_mode mode)
     int ret_fd;
     pid_t pid = -1;
 
+    const char* shell_command;
+    struct stat st;
+
     const char *arg0, *arg1;
     if (name == 0 || *name == 0) {
         arg0 = "-"; arg1 = 0;
@@ -351,12 +356,19 @@ static int create_subproc_thread(const char *name, const subproc_mode mode)
         arg0 = "-c"; arg1 = name;
     }
 
+    if (stat(ALTERNATE_SHELL_COMMAND, &st) == 0) {
+        shell_command = ALTERNATE_SHELL_COMMAND;
+    }
+    else {
+        shell_command = SHELL_COMMAND;
+    }
+
     switch (mode) {
     case SUBPROC_PTY:
-        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
+        ret_fd = create_subproc_pty(shell_command, arg0, arg1, &pid);
         break;
     case SUBPROC_RAW:
-        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
+        ret_fd = create_subproc_raw(shell_command, arg0, arg1, &pid);
         break;
     default:
         fprintf(stderr, "invalid subproc_mode %d\n", mode);


3: build脚本的修改

由于recovery.img每次生成的时候, 都会清除recovery的目录, 所以生成的 busybox 如果不处理的话, 会在这一步被清除。

diff --git a/core/Makefile b/core/Makefile
index 15c7f02..9409838 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -843,7 +843,6 @@ $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \
                $(recovery_fstab) \
                $(RECOVERY_INSTALL_OTA_KEYS)
        @echo ----- Making recovery image ------
-       $(hide) rm -rf $(TARGET_RECOVERY_OUT)
        $(hide) mkdir -p $(TARGET_RECOVERY_OUT)
        $(hide) mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc $(TARGET_RECOVERY_ROOT_OUT)/tmp
        @echo Copying baseline ramdisk...

4: recovery的修改 

这里涉及到两部分, 代码和Make脚本的修改。
先说下, busybox是通过编译成静态链接库供recovery使用的, 然后生成busybox的软连接, 最后再生成相应的命令(例如: ls, ps等)链接到busybox
这种方式是我认为修改比较小(不涉及 init.rc), 而且命令使用起来很简单的方式。

Make脚本:
diff --git a/Android.mk b/Android.mk
index 1a91f00..0103fb8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -62,6 +62,7 @@ LOCAL_STATIC_LIBRARIES := \
     libmtdutils \
     libmincrypt \
     libminadbd \
+    libbusybox \
     libfusesideload \
     libminui \
     libpng \
@@ -91,11 +92,47 @@ else
   LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
 endif
 
+# Busybox linkage is a non-fatal error
+#LOCAL_LDFLAGS += -Wl,--no-fatal-warnings
+
 LOCAL_C_INCLUDES += system/extras/ext4_utils
 LOCAL_C_INCLUDES += external/openssl/include
 
+# Symlinks
+RECOVERY_LINKS := busybox reboot setup_adbd
+
+RECOVERY_SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(RECOVERY_LINKS))
+
+BUSYBOX_LINKS := $(shell cat external/busybox/busybox-minimal.links)
+exclude := tune2fs mke2fs
+RECOVERY_BUSYBOX_SYMLINKS := $(addprefix $(TARGET_RECOVERY_ROOT_OUT)/sbin/,$(filter-out $(exclude),$(notdir $(BUSYBOX_LINKS))))
+
+#LOCAL_ADDITIONAL_DEPENDENCIES += \
+    minivold \
+    recovery_e2fsck \
+    recovery_mke2fs \
+    recovery_tune2fs \
+    mount.exfat_static
+
+LOCAL_ADDITIONAL_DEPENDENCIES += $(RECOVERY_SYMLINKS) $(RECOVERY_BUSYBOX_SYMLINKS)
+
 include $(BUILD_EXECUTABLE)
 
+$(RECOVERY_SYMLINKS): RECOVERY_BINARY := $(LOCAL_MODULE)
+$(RECOVERY_SYMLINKS):
+       @echo "Symlink: $@ -> $(RECOVERY_BINARY)"
+       @mkdir -p $(dir $@)
+       @rm -rf $@
+       $(hide) ln -sf $(RECOVERY_BINARY) $@
+
+# Now let's do recovery symlinks
+$(RECOVERY_BUSYBOX_SYMLINKS): BUSYBOX_BINARY := busybox
+$(RECOVERY_BUSYBOX_SYMLINKS):
+       @echo "Symlink: $@ -> $(BUSYBOX_BINARY)"
+       @mkdir -p $(dir $@)
+       @rm -rf $@
+       $(hide) ln -sf $(BUSYBOX_BINARY) $@
+
 # All the APIs for testing
 include $(CLEAR_VARS)
 LOCAL_MODULE := libverifier

recovery代码
diff --git a/recovery.cpp b/recovery.cpp
index 6deeaaa..8ce62e5 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -979,11 +1012,14 @@ ui_print(const char* format, ...) {
     }
 }
 
+
+extern "C" int busybox_driver(int argc, char **argv);
+
 int
 main(int argc, char **argv) {
     time_t start = time(NULL);
 
-    <span style="color:#ff0000;">redirect_stdio(TEMPORARY_LOG_FILE); //如果不放到后面, 就把busybox的默认输出导入到 log 文件里了</span>
+    
 
     // If this binary is started with the single argument "--adbd",
     // instead of being the normal recovery binary, it turns into kind
@@ -997,6 +1033,23 @@ main(int argc, char **argv) {
         return 0;
     }
 
+    // Handle alternative invocations
+    char* command = argv[0];
+    char* stripped = strrchr(argv[0], '/');
+    if (stripped)
+        command = stripped + 1;
+
+    if (strcmp(command, "recovery") != 0) {
+        return busybox_driver(argc, argv);
+    }
+
+    redirect_stdio(TEMPORARY_LOG_FILE);
+
     printf("Starting recovery (pid %d) on %s", getpid(), ctime(&start));
 
     load_volume_table();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值