从零到一:为嵌入式Linux设备交叉编译Android adb/adbd工具链
1. 为什么要在嵌入式Linux上移植adb/adbd在嵌入式开发中我们经常需要在PC和开发板之间传输文件。传统的FTP、SCP等方式虽然能用但操作起来总是不够直观方便。Android的adb工具链就完美解决了这个问题 - 它不仅能实现文件传输还支持shell访问、端口转发等高级功能。我最近在一个ARM架构的工控板项目上就遇到了这个需求。客户要求通过USB线直接管理设备文件adb的push/pull功能正好符合要求。但问题是这个板子跑的是标准Linux系统不是Android。经过一番折腾我成功交叉编译了adb/adbd工具链现在分享下完整过程。2. 环境准备与依赖库编译2.1 搭建交叉编译环境我用的宿主机是Ubuntu 20.04目标板是Cortex-A53架构。首先需要安装合适的交叉编译器sudo apt install gcc-arm-linux-gnueabihf验证编译器是否正常工作arm-linux-gnueabihf-gcc -v如果显示类似Target: arm-linux-gnueabihf的输出说明环境就绪。对于其他架构的开发板可能需要从芯片厂商获取专用工具链。2.2 交叉编译zlib库adb依赖zlib进行数据压缩我们先编译它wget https://zlib.net/zlib-1.2.11.tar.gz tar xvf zlib-1.2.11.tar.gz cd zlib-1.2.11 CCarm-linux-gnueabihf-gcc ./configure --prefix$PWD/../zlib-arm make -j$(nproc) make install这里有几个关键点CC指定交叉编译器--prefix设置安装目录编译完成后会在上级目录生成zlib-arm文件夹2.3 交叉编译OpenSSLadb的加密通信需要OpenSSL支持wget https://www.openssl.org/source/openssl-1.1.1.tar.gz tar xvf openssl-1.1.1.tar.gz cd openssl-1.1.1 ./Configure linux-armv4 shared --cross-compile-prefixarm-linux-gnueabihf- --prefix$PWD/../openssl-arm make -j$(nproc) make install注意参数说明linux-armv4指定目标平台shared生成动态库--cross-compile-prefix设置工具链前缀同样会在上级目录生成openssl-arm文件夹3. 修改Android-tools源码3.1 获取源码并准备编译环境我使用的是android-tools-4.2.2版本git clone https://github.com/android/platform_system_core.git cd platform_system_core/adb需要将debian目录下的mk文件复制到对应位置cp debian/makefiles/adbd.mk Makefile3.2 关键Makefile修改主要修改点包括替换交叉编译器路径添加依赖库的头文件和库路径调整编译选项修改后的Makefile关键部分CC : arm-linux-gnueabihf-gcc CPPFLAGS -I/path/to/zlib-arm/include CPPFLAGS -I/path/to/openssl-arm/include LDFLAGS -L/path/to/zlib-arm/lib LDFLAGS -L/path/to/openssl-arm/lib LIBS -lz -lcrypto特别要注意的是需要添加-DADBD_NON_ANDROID宏定义告诉代码这是运行在非Android环境。4. 编译与部署4.1 执行编译在adb目录下直接运行make clean make -j$(nproc)如果一切顺利会生成adbd可执行文件。可以用file命令验证file adbd # 应该显示adbd: ELF 32-bit LSB executable, ARM...4.2 部署到开发板将生成的文件和依赖库拷贝到开发板scp adbd root192.168.1.100:/usr/bin scp /path/to/zlib-arm/lib/libz.so.* root192.168.1.100:/usr/lib scp /path/to/openssl-arm/lib/libcrypto.so.* root192.168.1.100:/usr/lib在开发板上设置环境变量并启动服务export LD_LIBRARY_PATH/usr/lib adbd 4.3 PC端连接测试在PC上安装adb工具后adb connect 192.168.1.100 adb devices # 应该能看到设备列表 adb shell # 可以进入交互式shell5. 常见问题排查5.1 设备无法识别如果adb devices看不到设备可以尝试检查USB连接是否正常开发板是否开启了USB调试模式在PC上添加udev规则sudo tee /etc/udev/rules.d/51-android.rules EOF SUBSYSTEMusb, ATTR{idVendor}18d1, MODE0666 EOF sudo udevadm control --reload5.2 库文件缺失错误如果运行时提示缺少so文件可以用ldd检查依赖ldd adbd将缺失的库文件拷贝到开发板的/lib或/usr/lib目录。5.3 版本兼容性问题不同版本的adb/adbd可能存在协议不兼容。建议保持PC端adb工具和开发板adbd版本一致。可以通过编译参数指定协议版本CPPFLAGS -DADB_VERSION1.0.326. 进阶配置与优化6.1 设置adbd为系统服务为了让adbd开机自启可以创建systemd服务cat /etc/systemd/system/adbd.service EOF [Unit] DescriptionADB Daemon Afternetwork.target [Service] ExecStart/usr/bin/adbd Restartalways [Install] WantedBymulti-user.target EOF systemctl enable adbd systemctl start adbd6.2 启用加密连接默认情况下adb通信是不加密的。要启用TLS加密在开发板生成密钥openssl genrsa -out adbkey 2048 openssl rsa -in adbkey -pubout -out adbkey.pub将公钥拷贝到PC的~/.android/adbkey.pub重新编译adbd时添加加密支持CPPFLAGS -DALLOW_ADBD_AUTH16.3 性能优化建议对于资源受限的设备可以调整以下参数减小缓冲区大小CPPFLAGS -DADB_BUFFER_SIZE4096禁用不必要功能CPPFLAGS -DNO_SERVICES1使用静态链接减少依赖LDFLAGS -static7. 实际应用案例在我最近的一个智能家居网关项目中就成功应用了这套方案。网关采用Rockchip RK3308芯片运行Buildroot构建的Linux系统。通过移植adbd实现了开发阶段快速部署应用生产环境远程日志收集现场问题诊断与修复一个特别实用的技巧是结合adb over WiFi先用USB线连接并执行adb tcpip 5555拔掉USB线后仍可通过网络连接adb connect 192.168.1.100:5555这大大提高了现场调试的效率。整个移植过程最耗时的部分是解决库依赖问题特别是不同版本OpenSSL的兼容性。建议在项目初期就确定好各组件版本避免后期调整带来的额外工作量。