这里说的是源码的编译环境下, 如何完整的移植一份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();