Android 7.0 写入ro.serialno小结

项目需要,需要写入ro.serialno属性。借鉴了网上的文档,现把这个知识点做个备忘小结。

1.原理:ro.serialno是init从bootcmdline读取androidboot.serialno,设置成系统属性ro.boot.serialno和ro.serialno。bootcmdline是从mboot中android_image_get_kernel设置的。

2.代码相关具体位置:

   a.mboot中 cmd_bootm.c android_image_get_kernel将需要设置为serialno属性的环境变量,以“androidboot.serialno=xxxxx”的形式设置到cmdline中。注意在开始这么设置的时候,ro.boot.serialno是固定值,这里传的参数无法写入,原因是这个是ro属性的变量,在刚开始时,有一个初始化值,这个初始化值需要清空掉:

system/core/init/init.cpp:          

static void process_kernel_dt() {

      static const char android_dir[] = "/proc/device-tree/firmware/android";

       ...

      while ((dp = readdir(dir.get())) != NULL) {
            if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) {
                continue;
            }
            file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name);
            android::base::ReadFileToString(file_name, &dt_file);
            std::replace(dt_file.begin(), dt_file.end(), ',', '.');
            std::string property_name = android::base::StringPrintf("ro.boot.%s", dp->d_name);
            property_set(property_name.c_str(), dt_file.c_str());

        }

}

      b.android系统从cmdline读取key value值转为系统属性。ro.boot.serialno这个属性是通过字符串拼接形成的,所以在源码中是搜索不到的。

cat /proc/cmdline                                  vmalloc=512M console=ttyS0 androidboot.hardware=fbiboard androidboot.console=ttyS0 board.ap_has_alsa=0 init=/init  mtdparts=fbixxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00008000@0x00006000(resource),0x00008000@0x0000e000(kernel),0x00010000@0x00016000(boot),0x00010000@0x00026000(recovery),0x0001a000@0x00036000(backup),0x00040000@0x00050000(cache),0x00002000@0x00090000(kpanic),0x00100000@0x00092000(system),0x00002000@0x00192000(metadata),0x00600000@0x00194000(userdata),0x00020000@0x00794000(radical_update),-@0x007B4000(user) storagemedia=emmc  androidboot.serialno=1234567890 androidboot.mode=emmc  


          system/core/init/init.cpp:

    static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) {
        if (key.empty()) return;
            if (for_emulator) {
            // In the emulator, export any kernel option with the "ro.kernel." prefix.
            property_set(android::base::StringPrintf("ro.kernel.%s", key.c_str()).c_str(), value.c_str());
            return;
        }
        if (key == "qemu") {
            strlcpy(qemu, value.c_str(), sizeof(qemu));
        } else if (android::base::StartsWith(key, "androidboot.")) {
            property_set(android::base::StringPrintf("ro.boot.%s", key.c_str() + 12).c_str(),
                     value.c_str());
            NOTICE("lucky key:[%s]--value[%s].\n",key.c_str(),value.c_str());
        }

    }

   c.ro.boot.serialno怎么变为ro.serialno的呢?

static void export_kernel_boot_props() {
    struct {
        const char *src_prop;
        const char *dst_prop;
        const char *default_value;
    } prop_map[] = {
        { "ro.boot.serialno",   "ro.serialno",   "", },
        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
        { "ro.boot.baseband",   "ro.baseband",   "unknown", },
        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
        { "ro.boot.hardware",   "ro.hardware",   "unknown", },
        { "ro.boot.revision",   "ro.revision",   "0", },
    };
    for (size_t i = 0; i < ARRAY_SIZE(prop_map); i++) {
        std::string value = property_get(prop_map[i].src_prop);
        property_set(prop_map[i].dst_prop, (!value.empty()) ? value.c_str() : prop_map[i].default_value);
    }
}

3.验证:

      #getprop|grep serial

         [ro.boot.serialno]: [123456789]

         [ro.serialno]: [123456789]

<think>好的,我现在需要帮助用户解决如何在Android中自定义ro.serialno的问题。首先,我需要回忆一下之前提供的引用内容。根据引用[1],ro.serialno通常是通过SystemProperties.get方法获取的,而引用[2]提到,ro.开头的属性通常不能直接自定义,因为它们来自内核启动参数中的ro.boot.serialno。 用户可能正在尝试修改设备的序列号,可能用于测试或特定应用场景。但根据Android的安全机制,ro.开头的属性是只读的,不能直接通过常规方法修改。因此,我需要考虑系统级的方法,比如修改内核参数或系统属性文件。 首先,用户可能需要root权限,因为修改系统属性通常需要超级用户权限。然后,检查设备是否解锁了Bootloader,因为修改启动参数可能需要解锁。接下来,可能的步骤包括修改bootloader的启动参数,或者在系统初始化脚本中设置属性。例如,在init.rc文件中添加setprop命令,或者在编译ROM时预先定义该属性。 另外,引用中提到ro.boot.serialno是内核传递的参数,所以可能需要修改内核的启动参数。这涉及到编译内核或修改boot镜像。对于普通用户来说,这可能比较复杂,但对于ROM开发者来说,可能是可行的。 需要注意的是,不同Android版本和厂商可能有不同的机制,比如某些设备可能通过/proc/cmdline或其他方式传递序列号。因此,用户需要根据具体设备型号和Android版本进行调整。 最后,要提醒用户修改系统属性可能违反设备的安全策略,甚至导致设备不稳定或保修失效。需要谨慎操作,并确保符合法律法规。</think>在Android系统中自定义$ro.serialno$属性需要系统级修改,具体实现方法如下: ### 一、实现原理 1. $ro.serialno$属性值来源于内核启动参数$ro.boot.serialno$[^2] 2. Android系统初始化阶段通过解析/proc/cmdline获取序列号 3. 该属性属于只读系统属性(ro.开头),常规setprop命令无法修改 ### 二、实现方法 #### 方法1:内核启动参数修改(推荐) ```bash # 在bootloader启动参数添加 androidboot.serialno=自定义序列号 ``` 需重新编译boot镜像,适用于ROM开发者 #### 方法2:init阶段注入(需root) 在设备初始化脚本中添加: ```rc # /system/core/rootdir/init.rc on early-init setprop ro.serialno "自定义值" ``` #### 方法3:属性重载(临时修改) ```bash # 需要SELinux权限调整 setprop ro.boot.serialno "临时值" stop;start ``` ### 三、验证方法 ```java // Java代码验证 SystemProperties.get("ro.serialno", ""); ``` ### 四、注意事项 1. Android 8.0+版本加强了属性保护,需修改system/sepolicy相关.te文件 2. 部分厂商设备使用独立SN存储芯片(如QCOM的TA分区) 3. 修改后可能影响OTA升级和DRM认证
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值