<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
在init.rc檔案裡,可以看到下面的服務載入並運行:
# adbd is controlled by the persist.service.adb.enable system property
service adbd /sbin/adbd
disabled
adbd服務的代碼在目錄:Android-2.0/system/core/adb
adbd服務使用c語言實現,它不但可以在虛擬機器裡運行,也可以在實際的裝置裡運行。adbd服務是adb調試系統中的一部分,整個adb調試系統包括有三部分:手機啟動並執行adbd服務、PC啟動並執行伺服器、PC啟動並執行用戶端。當android啟動時,就運行adbd服務,建立一個調試連接埠,這樣就可以讓開發機器上的伺服器串連過來,通過這個串連就可以發送調試資訊給伺服器,也可以接收到外面發送過來的調試命令。
先來分析編譯檔案Android.mk,adbd相關內容如下:
# adbd device daemon
# =========================================================
# build adbd in all non-simulator builds
BUILD_ADBD := false
當設定為BUILD_ADBD為true時,就是編譯運行在模擬器裡的調試服務,否則就是運行到真實機器裡的調試服務。
ifneq ($(TARGET_SIMULATOR),true)
BUILD_ADBD := true
endif
如果運行在linux裡模擬器,就需要使用下面的判斷。
# build adbd for the Linux simulator build
# so we can use it to test the adb USB gadget driver on x86
#ifeq ($(HOST_OS),linux)
# BUILD_ADBD := true
#endif
ifeq ($(BUILD_ADBD),true)
include $(CLEAR_VARS)
LOCAL_SRC_FILES :=
adb.c
fdevent.c
transport.c
transport_local.c
transport_usb.c
sockets.c
services.c
file_sync_service.c
jdwp_service.c
framebuffer_service.c
remount_service.c
usb_linux_client.c
log_service.c
utils.c
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
# TODO: This should probably be board specific, whether or not the kernel has
# the gadget driver; rather than relying on the architecture type.
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DANDROID_GADGET=1
endif
LOCAL_MODULE := adbd
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
如果在模擬器裡運行,就需要編譯為線程模式,否則就需要串連靜態庫的方式。
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_STATIC_LIBRARIES := libcutils
LOCAL_LDLIBS += -lpthread
include $(BUILD_HOST_EXECUTABLE)
else
LOCAL_STATIC_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
endif
接著來剖析器入口函數main處理過程,它的代碼如下:
int main(int argc, char **argv)
{
adb_trace_init();
這行代碼主要擷取環境變數,用來判斷到底輸出什麼樣資訊。
下面這段代碼根據編譯選項來決定編譯為PC機裡的服務,還是裝置啟動並執行服務。
#if ADB_HOST
adb_sysdeps_init();
return adb_commandline(argc - 1, argv + 1);
這裡是選擇編譯為PC裡的伺服器。
#else
這段是選擇為裝置裡的服務進程。
if((argc > 1) && (!strcmp(argv[1],"recovery"))) {
adb_device_banner = "recovery";
recovery_mode = 1;
}
上面這段用來判斷是否復原模式。
start_device_log();
這行代碼開始輸出調試LOG。
return adb_main(0);
這行代碼是進入adb服務進程處理。
#endif
}