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