这里使用香橙派5 max适配的 redroid,拉取源码并编译 ,并且修改 adb_key的认证方式,使用预埋证书完成认证。
源码版本是 Android12,并且使用user模式编译。
香橙派5max的板子是这样的(实际测试不能这样裸着,必须加上散热和风扇,否则同时跑多个实例cpu热到死机):
香橙派安装 Ubuntu参考 : 香橙派刷入Ubuntu系统
1、拉取源码
mkdir ~/redroid && cd ~/redroid# 拉取源码apt install repo git-lfs -yecho "y" | repo init -u c60K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6J5k6h3c8J5L8$3W2V1i4K6u0V1M7X3!0U0K9$3y4Z5K9i4m8Q4x3V1k6H3L8r3q4@1k6X3!0J5L8g2)9#2k6X3#2S2L8X3W2X3k6i4y4@1M7#2)9J5k6h3N6A6N6q4)9J5y4X3&6T1M7%4m8Q4x3@1u0Q4x3X3c8T1i4K6t1$3L8X3u0K6M7q4)9K6b7Y4u0W2k6s2u0G2K9h3c8Q4x3X3b7I4x3W2)9J5k6e0m8Q4x3X3f1H3i4K6t1$3L8X3u0K6M7q4)9K6b7W2)9J5k6q4)9J5k6r3c8W2M7s2c8Z5i4K6y4p5x3b7`.`.cp /root/redroid/.repo/repo/repo /usr/bin/reporepo sync -j4repo forall -g lfs -c git lfs pull
2、修改源码
1)编译增加user模式
修改device文件 device/redroid/AndroidProducts.mk ,新增 redroid_arm64-user
COMMON_LUNCH_CHOICES := redroid_x86_64-userdebug redroid_x86_64_only-userdebug redroid_arm64-user redroid_arm64-userdebug redroid_arm64_only-user redroid_arm64_only-userdebug
2)新增adb_keys文件和shell文件:
adb_keys主要用于存放adb认证用的公钥,preinstall用于在系统第一次启动时,拷贝相关文件。
preinstall.sh文件内容如下,目的在系统启动时将 adb_keys文件拷贝到 data/system目录下:
#!/system/bin/shCUSTOMIZED_APK=/system/usr/appDATA_APK=/data/appecho "CUSTOMIZED_APK=${CUSTOMIZED_APK}"#获取是否已经预安装过标记位PREINSTALL_RESULT=`getprop persist.sys.preinstall.value`echo "PREINSTALL_RESULT=${PREINSTALL_RESULT}"apk_files=""#判断标记位是否为空,为空则没有预装过。然后将所有apk均copy到data/app下面。if [ -z "${PREINSTALL_RESULT}" ]; thencd ${CUSTOMIZED_APK}apk_files=$(ls *.apk )echo "apks files = ${apk_files}"for apkfile in $apk_filesdoecho " apkfiles = ${apkfile} "cp -vf ${CUSTOMIZED_APK}/${apkfile} ${DATA_APK}/${apkfile}echo "start copy "chmod 777 ${DATA_APK}/${apkfile}done#设置标记位setprop persist.sys.preinstall.value 1# 拷贝 设备改机文件cp /system/etc/device.json /data/system/device.jsonchmod 666 /data/system/device.json# 拷贝adb公钥cp /system/etc/adb_keys /data/system/adb_keyschown -R shell:shell /data/system/adb_keyschmod 666 /data/system/adb_keyscd ../..fi
3) 打包时拷贝相关文件
修改 build/target/product/base_product.mk,增加内容:
# 拷贝APPPRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,/data1/rom/android/redroid12/apps/apps,/system/usr/app)# 拷贝shellPRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,/data1/rom/android/redroid12/apps/shell,/system/bin)# 拷贝改机文件及adb公钥PRODUCT_COPY_FILES += $(call find-copy-subdir-files,*,/data1/rom/android/redroid12/apps/devices,/system/etc)
4)系统启动时运行preinstall.sh
修改 system/core/rootdir/init.rc ,在 on_boot 最后新增:
on boot start preinstall
修改 system/sepolicy/private/file_contexts 以及 system/sepolicy/prebuilts/api/31.0/private/file_contexts,新增:
/system/bin/preinstall.sh u:object_r:preinstall_exec:s0
新增文件 system/sepolicy/private/preinstall.te 以及 system/sepolicy/prebuilts/api/31.0/private/preinstall.te ,内容如下:
type preinstall, domain, coredomain;type preinstall_exec, exec_type, file_type, system_file_type;# init_daemon_domain(preinstall)#全部默认允许permissive preinstall;
修改 system/sepolicy/private/init.te 以及 system/sepolicy/prebuilts/api/31.0/private/init.te,新增:
domain_trans(init, preinstall_exec, preinstall)allow init preinstall_exec:file {read open getattr execute};
编译时如果还有其他selinux问题,自行看提示解决。因为我也忘了还修改了哪些。
5) 修改adb认证
修改 frameworks/native/libs/adbd_auth/adbd_auth.cpp,路径中新增 /data/system/adb_keys
static constexpr constchar* key_paths[] = {"/adb_keys", "/data/misc/adb/adb_keys", "/data/system/adb_keys"};void IteratePublicKeys(bool (*callback)(void*, constchar*, size_t), void* opaque) { for (const auto& path : key_paths) { if (access(path, R_OK) == 0) { LOG(INFO) << "adbd_auth: loading keys from " << path; std::string content; if (!android::base::ReadFileToString(path, &content)) { PLOG(ERROR) << "adbd_auth: couldn't read " << path; continue; } for (const auto& line : android::base::Split(content, "n")) { if (!callback(opaque, line.data(), line.size())) { return; } } } }}
修改 frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
//第一处,指向我们自己预埋的adb_keysprivate static final String SYSTEM_KEY_FILE = "/data/system/adb_keys";//第二处,系统adb_keys也增加过期时间public void setLastConnectionTime(String key, long connectionTime, boolean force) { // Do not set the connection time to a value that is earlier than what was previously // stored as the last connection time unless force is set. if (mKeyMap.containsKey(key) && mKeyMap.get(key) >= connectionTime && !force) { return; } // System keys are always allowed so there's no need to keep track of their connection // time. // if (mSystemKeys.contains(key)) { // return; // } // if this is the first time the key is being added then write it to the key file as // well. if (!mKeyMap.containsKey(key)) { writeKey(key); } mKeyMap.put(key, connectionTime);}//第三处,如果是预埋的key,直接允许并返回case MESSAGE_ADB_CONFIRM: { String key = (String) msg.obj; String fingerprints = getFingerprints(key); Slog.d(TAG, "confirm: " + key); Slog.d(TAG, "fingerprints: " + fingerprints); if(mAdbKeyStore.isKeyAuthorized(key)) { Slog.d(TAG, "confirm in system key"); mFingerprints = fingerprints; allowDebugging(true, key); return; }
6)开机时启动adb服务
修改 frameworks/base/services/core/java/com/android/server/adb/AdbService.java
/** * Callend in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}. */public void bootCompleted() { if (DEBUG) Slog.d(TAG, "boot completed"); if (mDebuggingManager != null) { mDebuggingManager.setAdbEnabled(true, AdbTransportType.USB); //mIsAdbUsbEnabled mDebuggingManager.setAdbEnabled(true, AdbTransportType.WIFI); //mIsAdbWifiEnabled }}
修改 system/core/rootdir/init.usb.rc
on boot && property:persist.sys.usb.config=* # setprop sys.usb.config ${persist.sys.usb.config} start adbd
7)修改adb连接过期时间
修改 frameworks/base/core/java/android/provider/Settings.java
/** * The default time in ms within which a subsequent connection from an always allowed system * is allowed to reconnect without user interaction. * * @hide */public static final long DEFAULT_ADB_ALLOWED_CONNECTION_TIME = 604800000 * 365;
8)保持adb root 权限
修改 packages/modules/adb/daemon/main.cpp , should_drop_privileges函数返回false
static bool should_drop_privileges() { // The properties that affect `adb root` and `adb unroot` are ro.secure and // ro.debuggable. In this context the names don't make the expected behavior // particularly obvious. // // ro.debuggable: // Allowed to become root, but not necessarily the default. Set to 1 on // eng and userdebug builds. // // ro.secure: // Drop privileges by default. Set to 1 on userdebug and user builds.bool ro_secure = android::base::GetBoolProperty("ro.secure", true);bool ro_debuggable = __android_log_is_debuggable(); // Drop privileges if ro.secure is set...bool drop = ro_secure; // ... except "adb root" lets you keep privileges in a debuggable build. std::string prop = android::base::GetProperty("service.adb.root", "");bool adb_root = (prop == "1");bool adb_unroot = (prop == "0"); if (ro_debuggable && adb_root) { drop = false; } // ... and "adb unroot" lets you explicitly drop privileges. if (adb_unroot) { drop = true; } return false;}
9)其它可能需要修改
修改 system/sepolicy/public/domain.te 及 system/sepolicy/prebuilts/api/31.0/public/domain.te,注释内容:
# neverallowxperm * *:{ dir notdevfile_class_set socket_class_set blk_file } ioctl { 0 };
修改 hardware/rockchip/librkvpu/omx_get_gralloc_private/Android.bp, 在 cc_library_shared的 include_dirs 新增 "hardware/rockchip/libgralloc/utgard
include_dirs: [ "hardware/libhardware/include/", "system/core/libcutils/include", "hardware/rockchip/libgralloc/utgard", "hardware/libhardware/modules/gralloc", "system/core/libsystem/include", "system/memory/libion/original-kernel-headers",],
修改system/sepolicy/Android.mk,注释下面代码,允许user模式下使用permissive
$(hide) if [ "$(TARGET_BUILD_VARIANT)" = "user" -a -s $@.permissivedomains ]; then echo "==========" 1>&2; echo "warning: permissive domains not allowed in user builds" 1>&2; echo "List of invalid domains:" 1>&2; cat $@.permissivedomains 1>&2; fi
3、编译
# 编译 cd ~/redroidsource build/envsetup.shlunch redroid_arm64-userexport TARGET_BOARD_PLATFORM_GPU=mali-G52export TARGET_RK_GRALLOC_VERSION=4m
4、导入docker
# 编译产物目录cd ~/redroid/out/target/product/redroid_arm64# 挂载并导入到 dockermount system.img system -o romount vendor.img vendor -o rotar --xattrs -c vendor -C system --exclude="./vendor" . | DOCKER_DEFAULT_PLATFORM=linux/arm64 docker import -c 'ENTRYPOINT ["/init", "androidboot.hardware=redroid"]' - redroid12_userumount system vendor# 或者打包成tar文件tar --xattrs -cf redroid12_user.tar vendor -C system --exclude="./vendor" . && # 并从tar文件导入到dockerDOCKER_DEFAULT_PLATFORM=linux/arm64 docker import -c 'ENTRYPOINT ["/init", "androidboot.hardware=redroid"]' redroid12_user.tar redroid12_user
导入成功后,可以看到名为 redroid12_user的镜像
5、启动镜像
docker run -d --restart=always --privileged -p 5001:5555 -v ~/redroid-data1:/data -v /dev/net/tun:/dev/tun -v /dev/mali0:/dev/mali0 --name redroid1 redroid12_user androidboot.redroid_height=1280 androidboot.redroid_width=720 androidboot.redroid_magisk=1 androidboot.redroid_virt_wifi=1 androidboot.redroid_gpu_mode=mali
6、查看运行中的镜像
同时运行6个实例效果图
最后,附上一张真机长时间运行的开裂图:
总结:还是云手机香
看雪ID:CCTV果冻爽
https://bbs.kanxue.com/user-home-770147.htm
#
原文始发于微信公众号(看雪学苑):Redroid 镜像编译及预埋 adb_key认证
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论