android4.0 device 设备号 ro.serialno

本文详细解析了Android系统中ro.serialno属性的生成过程及用途,包括从bootloader传入的参数、通过cmdline解析的过程、如何在系统属性中设置以及与USB设备名称的关系。

1.ro.serialno不存在于任何属性文件,比如build.prop, default.prop等,而是在/system/core/init/init.c里由ro.boot.serialno 转换而来,见export_kernel_boot_props()。

2.而ro.boot.serialno的来源是/proc/cmdline,也就是linux kernel启动时被传入的cmdline, 由bootloader传入。 

bootloader传进来的是androidboot.serialno, 而不是ro.boot.serialno,因为还要解析过cmdline 
3.ro.serialno的用处是来保存唯一设备号,在settings->about->status里会显示,也会用在USB device name里。 
about->status 里获取serialno的流程: 
Build.SERIAL 
->getString(“ro.serialno”) 
->SystemProperties.get() 
->SystemProperties.native_get() 
->SystemProperties_getSS() in android_os_SystemProperties.cpp 
->property_get() in Properties.c 
->__system_property_get() in System_properties.c in bionic

获取到的前提是之前已经有设置好,也就是有调用property_set() in init.c

ro.serialno设置过程:

首先调用import_kernel_nv函数(/system/core/init/init.c文件中)解析从bootloader中传进来的cmdline中的参数,并把

androidboot.serialno的值复制到serialno[32]变量中,如下:

static void import_kernel_nv(char *name, int in_qemu)

{
    char *value = strchr(name, '=');

……
        /* on a real device, white-list the kernel options */
        if (!strcmp(name,"qemu")) {
        } else if (!strcmp(name,"androidboot.serialno")) {
            strlcpy(serialno, value, sizeof(serialno));

        } else if (!strcmp(name,"androidboot.baseband")) {
……
        }
    } else {
        /* in the emulator, export any kernel option with the
         * ro.kernel. prefix */
        char  buff[32];
        int   len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
        if (len < (int)sizeof(buff)) {
            property_set( buff, value );
        }
    }
}

之后在set_init_properties_action函数(/system/core/init/init.c文件中)中设置ro.serialno属性,

queue_builtin_action(set_init_properties_action, "set_init_properties");

-->static int set_init_properties_action(int nargs, char **args)

{
    char tmp[PROP_VALUE_MAX];
    unsigned int deviceuuid[4];
……

//判断serialno[0]里是否有值,有值则直接设置,为空,则设置为空
    property_set("ro.serialno", serialno[0] ? serialno : "");

    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
……
    return 0;
}

测试发现如果使用adb devices或者adb get-serialno命令时,显示的不是ro.serialno的值,而是

sys/class/android_usb/android0/iSerial 类中的值,当ro.serialno有值时,在之后的初始化中会把ro.serialno的

值写到iSerial里,在init.xxxxx.usb.rc 文件中,代码如下:

on boot

write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer
    write /sys/class/android_usb/android0/iProduct $ro.product.model
    write /sys/class/android_usb/android0/iSerial $ro.serialno
    write /sys/class/android_usb/android0/f_mass_storage/inquiry_string "Android  Mass Storage"
    write /sys/class/android_usb/android0/f_rndis/manufacturer Samsung
    write /sys/class/android_usb/android0/f_rndis/vendorID 04e8
    write /sys/class/android_usb/android0/f_rndis/wceis 1

网上有说ro.serialno为空时,会把iSerial的值写到ro.serialno里面,不过在我们的Android4.0里没有找到相关代码,

而且测试时,ro.serialno为空时,就会一直是空的,iSerial的值则会使用默认值,其默认值在kernel里的

drivers/usb/gadget/android.c文件中定义:

DESCRIPTOR_STRING_ATTR(iProduct, product_string)

DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)

DESCRIPTOR_STRING_ATTR(iSerial, serial_string)

serial_string的值在android_bind函数中定义:

static int android_bind(struct usb_composite_dev *cdev)

{
struct android_dev *dev = _android_dev;
struct usb_gadget*gadget = cdev->gadget;
intgcnum, id, ret;
……
/* Default strings - should be updated by userspace */
strncpy(manufacturer_string, "Android", sizeof(manufacturer_string) - 1);
strncpy(product_string, "Android", sizeof(product_string) - 1);
strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
……
return 0;
}

ro.serialno为空时,使用adb devices或者adb get-serialno命令则会一直显示默认值0123456789ABCDEF。

如果ro.serialno 不为空,则ro.serialno和iSerial的值是相同的。

<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、付费专栏及课程。

余额充值