2011年5月16日 星期一

adb 的serial number要如何修改?

由kernel/drivers/usb/gadget/android.c

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問題排困解難指南最後面那段
步驟:
  1. regedit 並到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags]
  2. 確認GlobalDisableSerNumGen的值是否為1
  3. 新增機碼IgnoreHWSerNum[VID][PID]定設為1 
  4. EX: VID=0x451 PID=0xD101 => IgnoreHWSerNum0451D101 = 1
  5. 開機

1 則留言:

  1. 請問一下如果下adb devices出現的device名稱可以修改嗎?因為如果兩隻手機都是同樣的名稱,無法辨識呀!

    回覆刪除