android4.0 device 设备号 ro.serialno

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的值是相同的。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值