Android嵌入式开发:手把手教你用NDK交叉编译mmc-utils工具(附常见编译错误修复)
Android嵌入式开发实战NDK交叉编译mmc-utils全流程与疑难解析在嵌入式Android开发中直接操作eMMC存储芯片是底层调试的常见需求。mmc-utils作为开源工具集提供了EXT_CSD读写、RPMB分区管理、FFU固件更新等关键功能但官方版本往往无法直接在Android环境运行。本文将深入解析如何通过NDK工具链完成交叉编译并解决Android特有环境下的各类兼容性问题。1. 环境准备与源码获取1.1 搭建NDK编译环境首先需要配置Android NDK工具链推荐使用NDK r21版本以获得更好的兼容性。通过SDK Manager下载后设置环境变量export ANDROID_NDK_HOME/path/to/android-ndk-r21e export PATH$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin验证工具链是否可用aarch64-linux-android21-clang --version1.2 获取与准备源码从官方仓库克隆mmc-utils源码git clone https://github.com/mhei/mmc-utils.git cd mmc-utils关键文件结构说明mmc-utils/ ├── mmc.c # 主命令逻辑 ├── mmc_cmds.c # eMMC操作实现 ├── Makefile # 编译规则 └── mmc.h # 头文件定义提示建议基于最新release版本进行修改避免git master分支的不稳定变更2. Android特有代码适配2.1 解决Bionic Libc兼容问题Android的C库实现与标准Linux存在差异需要针对性修改问题1字节序转换函数缺失在mmc_cmds.c中添加#include endian.h #ifndef htobe32 #define htobe32(x) __bswap_32(x) #endif问题2结构体初始化不完整修改mmc.c中的commands数组定义补全所有字段static struct Command commands[] { { do_read_extcsd, -1, extcsd read, device\nPrint extcsd data from device., NULL, NULL, 0 // 新增字段初始化 }, // 其他命令结构体同步修改... };2.2 系统头文件路径调整创建本地适配头文件android_compat.h#pragma once /* 解决clock_gettime链接问题 */ #include time.h #define CLOCK_MONOTONIC 1 /* 重定义缺失的POSIX函数 */ int posix_memalign(void **memptr, size_t alignment, size_t size);在需要处包含此头文件#include android_compat.h3. 编译配置与优化3.1 编写Android.mk构建脚本创建适用于NDK的构建规则LOCAL_PATH : $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE : mmc_utils LOCAL_SRC_FILES : mmc.c mmc_cmds.c LOCAL_CFLAGS : -Wall -Wextra -DANDROID LOCAL_LDLIBS : -llog include $(BUILD_EXECUTABLE)3.2 交叉编译参数配置通过环境变量指定目标架构以arm64为例export TARGETaarch64-linux-android export API_LEVEL21 export CC$TARGET$API_LEVEL-clang export CXX$TARGET$API_LEVEL-clang修改Makefile关键参数CFLAGS --sysroot$(ANDROID_NDK_HOME)/sysroot LDFLAGS -pie -fPIE4. 编译执行与部署4.1 执行编译流程make clean make -j$(nproc)验证生成的可执行文件file mmc_utils # 应显示ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked...4.2 设备部署与测试推送二进制文件到开发板adb push mmc_utils /data/local/tmp/ adb shell chmod x /data/local/tmp/mmc_utils验证基本功能adb shell /data/local/tmp/mmc_utils extcsd read /dev/block/mmcblk0如需永久安装到系统分区adb remount adb push mmc_utils /system/bin/ adb shell sync5. 典型问题排查指南5.1 常见编译错误解决错误现象解决方案根本原因undefined reference to clock_gettime添加-lrt链接参数Bionic库分离时间函数htobe32 undeclared添加endian.h头文件Android去除非标准APIstructure has no member named x更新结构体初始化代码版本差异5.2 运行时问题处理问题权限不足# 查看设备节点权限 adb shell ls -l /dev/block/mmcblk* # 临时解决方案 adb shell su -c chmod 666 /dev/block/mmcblk0问题SELinux限制创建te规则文件allow mmc_utils block_device:file { read write open };加载新策略adb push mmc_utils.te /data/local/tmp/ adb shell checkmodule -M -m -o /data/local/tmp/mmc_utils.mod /data/local/tmp/mmc_utils.te adb shell semodule_package -o /data/local/tmp/mmc_utils.pp -m /data/local/tmp/mmc_utils.mod adb shell semodule -i /data/local/tmp/mmc_utils.pp6. 高级功能扩展6.1 RPMB分区安全操作生成HMAC密钥dd if/dev/random ofrpmb_key.bin bs32 count1写入密钥到设备adb shell /data/local/tmp/mmc_utils rpmb write-key /dev/block/mmcblk0rpmb rpmb_key.bin读取计数器值adb shell /data/local/tmp/mmc_utils rpmb read-counter /dev/block/mmcblk0rpmb6.2 FFU固件更新流程准备镜像文件mkimage -T mmc -C none -d fw.bin fw.img执行更新需设备支持adb shell /data/local/tmp/mmc_utils ffu fw.img /dev/block/mmcblk0注意FFU操作具有风险务必提前备份关键数据在实际项目中我们发现Rockchip平台对mmc-utils的兼容性最佳而部分Amlogic芯片需要额外patch才能支持完整功能。建议开发者根据具体平台调整编译参数必要时联系芯片厂商获取专用补丁。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2437793.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!