通过命令行获取序列号:
getprop ro.serialno
从哪来的呢:
android系统层:
/system/core/init/init.c:
static void import_kernel_nv(char *name, int for_emulator)
{
if (!strcmp(name,"qemu")) {
strlcpy(qemu, value, sizeof(qemu));
} else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
const char *boot_prop_name = name + 12; // boot_prop_name: "serialno\0"
char prop[PROP_NAME_MAX];
int cnt;
// prop: "ro.boot.serialno"
cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
if (cnt < PROP_NAME_MAX)
property_set(prop, value);
}
以上确定是通过androidboot.serialno获取的,即通过uboot传递给kernel的cmdline获取的,通过cat /proc/cmdline来查看androidboot.serialno的值即是序列号了,接下来再看bootloader。
bootloader:
找到androidboot.serialno的定义:
bootloader/lk/app/aboot/aboot.c:
static const char *usb_sn_cmdline = " androidboot.serialno=";
查看usb_sn_cmdline的赋值:
unsigned char *update_cmdline(const char * cmdline)
{
cmdline_len += strlen(usb_sn_cmdline);
cmdline_len += strlen(sn_buf);
}
猜测sn_buf就是要找的序列号,继续跟踪sn_buf的赋值处:
bootloader/lk/app/aboot/aboot.c
void aboot_init(const struct app_descriptor *app)
{
target_serialno((unsigned char *) sn_buf);
}
//找到对应target平台下的相应实现:
void target_serialno(unsigned char *buf)
{
uint32_t serialno;
if (target_is_emmc_boot()) {
serialno = mmc_get_psn();
snprintf((char *)buf, 13, "%x", serialno);
}
}
// 再找对应的mmc_get_psn的实现(到此基本可以确定如果是emmcboot的方式,sn应该就是emmc的chipid了)
bootloader/lk/platform/msm_shared/mmc.c:
unsigned mmc_get_psn(void)
{
return mmc_card.cid.psn;
}