static int android_probe(struct platform_device *pdev) { struct android_usb_platform_data *pdata = pdev->dev.platform_data; struct android_dev *dev = _android_dev; printk(KERN_INFO "android_probe pdata: %p\n", pdata); if (pdata) { dev->products = pdata->products; dev->num_products = pdata->num_products; dev->functions = pdata->functions; dev->num_functions = pdata->num_functions; if (pdata->vendor_id) device_desc.idVendor = __constant_cpu_to_le16(pdata->vendor_id); if (pdata->product_id) { dev->product_id = pdata->product_id; device_desc.idProduct = __constant_cpu_to_le16(pdata->product_id); } if (pdata->version) dev->version = pdata->version; if (pdata->product_name) strings_dev[STRING_PRODUCT_IDX].s = pdata->product_name; if (pdata->manufacturer_name) strings_dev[STRING_MANUFACTURER_IDX].s = pdata->manufacturer_name; if (pdata->serial_number) strings_dev[STRING_SERIAL_IDX].s = pdata->serial_number; } return usb_composite_register(&android_usb_driver); }
可以知道serial_number是透過pdata->serial_number得到
而pdata則是在arch/arm/mach-omap2/usb-musb.c被註冊
/* standard android USB platform data */ static struct android_usb_platform_data andusb_plat = { .vendor_id = OMAP_VENDOR_ID, .product_id = OMAP_UMS_PRODUCT_ID, .manufacturer_name = "Texas Instruments Inc.", .product_name = "OMAP-3/4", .serial_number = device_serial, .num_products = ARRAY_SIZE(usb_products), .products = usb_products, .num_functions = ARRAY_SIZE(usb_functions_all), .functions = usb_functions_all, }; static struct platform_device androidusb_device = { .name = "android_usb", .id = -1, .dev = { .platform_data = &andusb_plat, }, };
在andusb_plat的struct中可以發現.serial_number,在深入追下去便發現
static void usb_gadget_init(void) { unsigned int val[4] = { 0 }; unsigned int reg; #ifdef CONFIG_USB_ANDROID_RNDIS int i; char *src; #endif reg = DIE_ID_REG_BASE + DIE_ID_REG_OFFSET; if (cpu_is_omap44xx()) { val[0] = omap_readl(reg); val[1] = omap_readl(reg + 0x8); val[2] = omap_readl(reg + 0xC); val[3] = omap_readl(reg + 0x10); } else if (cpu_is_omap34xx()) { val[0] = omap_readl(reg); val[1] = omap_readl(reg + 0x4); val[2] = omap_readl(reg + 0x8); val[3] = omap_readl(reg + 0xC); } snprintf(device_serial, MAX_USB_SERIAL_NUM, "%08X%08X%08X%08X", val[3], val[2], val[1], val[0]); #ifdef CONFIG_USB_ANDROID_RNDIS /* create a fake MAC address from our serial number. * first byte is 0x02 to signify locally administered. */ rndis_pdata.ethaddr[0] = 0x02; src = device_serial; for (i = 0; *src; i++) { /* XOR the USB serial across the remaining bytes */ rndis_pdata.ethaddr[i % (ETH_ALEN - 1) + 1] ^= *src++; } platform_device_register(&rndis_device); #endif #ifdef CONFIG_USB_ANDROID_MASS_STORAGE platform_device_register(&usb_mass_storage_device); #endif platform_device_register(&androidusb_device); }
原來serial_number是讀取CPU暫存器在丟回serial_number。
詳細的source code可以到gitorious
另外因工作的關係發現異想不到的問題,工作上的需求是出貨時每台serial number都要不一樣以便區分每台,而問題在於第一台插上windows XP並安裝adb driver後,第二台在插上結果卻需要在安裝新的adb driver,這問題看似沒什麼,但對於工廠來說時間就是金錢且windows 7不會有這問題。
參考自製USB問題排困解難指南最後面那段
步驟:
- regedit 並到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags]
- 確認GlobalDisableSerNumGen的值是否為1
- 新增機碼IgnoreHWSerNum[VID][PID]定設為1 EX: VID=0x451 PID=0xD101 => IgnoreHWSerNum0451D101 = 1
- 開機
請問一下如果下adb devices出現的device名稱可以修改嗎?因為如果兩隻手機都是同樣的名稱,無法辨識呀!
回覆刪除