Android设备硬件序列号(SN、串号)分析
生活随笔
收集整理的這篇文章主要介紹了
Android设备硬件序列号(SN、串号)分析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Android設(shè)備硬件序列號(hào)(SN、串號(hào))的序列號(hào)是怎么獲取的,以全志A64平臺(tái)來一步步跟代碼分析:
在設(shè)置-》關(guān)于設(shè)備-》狀態(tài)信息中,顯示的信息來自android.os.Build.SERIAL,代碼位于: frameworks/base/core/java/android/os/Build.java: public static final String SERIAL = getString("ro.serialno");
frameworks/base/core/java/android/os/Build.java: private static String getString(String property) { return SystemProperties.get(property, UNKNOWN); }
由此可見是通過key為"ro.serialno"的SystemProperties 獲取到串號(hào)的,接下來看一下ro.serialno是如何賦值的: 先看init代碼system/core/init/init.c int main(int argc, char **argv) { ....... property_init();
get_hardware_name(hardware, &revision);
process_kernel_cmdline(); ......
原來是從cmdline中獲取的,import_kernel_cmdline把u-boot傳給kernel的cmdline進(jìn)行提取,然后回調(diào)import_kernel_nv進(jìn)行處理 static void process_kernel_cmdline(void) { ...... import_kernel_cmdline(0, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(1, import_kernel_nv); ...... export_kernel_boot_props(); }
import_kernel_nv將cmdline中androidboot.開頭的全部轉(zhuǎn)化為"ro.boot.%s"并設(shè)置到properties中,例如“androidboot.serialno”為“ro.boot.serialno”: static void import_kernel_nv(char *name, int for_emulator) { ...... } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) { const char *boot_prop_name = name + 12; char prop[PROP_NAME_MAX]; int cnt;
cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name); if (cnt < PROP_NAME_MAX) property_set(prop, value); } }
再來看export_kernel_boot_props函數(shù),將ro.boot.serialno賦值給ro.serialno了 static void export_kernel_boot_props(void) { ...... } prop_map[] = { { "ro.boot.serialno", "ro.serialno", "", }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, };
for (i = 0; i < ARRAY_SIZE(prop_map); i++) { ret = property_get(prop_map[i].src_prop, tmp); if (ret > 0) property_set(prop_map[i].dest_prop, tmp); else property_set(prop_map[i].dest_prop, prop_map[i].def_val); }
再來看看u-boot是如何獲取串號(hào)的: u-boot-2014.07/common/cmd_boota.c中有對androidboot.serialno的賦值: void update_bootargs(void) { ...... //serial info str = getenv("sunxi_serial"); sprintf(tmpbuf," androidboot.serialno=%s",str); ...... }
其值來自于u-boot env sunxi_serial,sunxi_serial又是由DTS中的/soc/serial_feature定義的,由sys_config.fex轉(zhuǎn)換的dts內(nèi)容,sn.txt又是放在private分區(qū)中。 [serial_feature] sn_filename = "sn.txt"
int sunxi_set_serial_num(void) { char serial[128] = {0}; if(get_serial_num_from_file(serial)) { get_serial_num_from_chipid(serial); } printf("serial is: %s\n",serial); if(setenv("sunxi_serial", serial)) { printf("error:set variable [sunxi_serial] fail\n"); } return 0; }
就用private分區(qū)存放sn.txt這種方式來驗(yàn)證一下: busybox mkfs.vfat /dev/block/by-name/private busybox mount -t vfat /dev/block/by-name/private /private/ echo "XXXX2017030219360001">/private/sn.txt sync
重啟系統(tǒng),發(fā)現(xiàn)串號(hào)變成了我們sn.txt里面的內(nèi)容,重新刷機(jī)驗(yàn)證序列號(hào)沒有被清掉。
另外根據(jù)android兼容說明,串號(hào)必須滿足以下要求(主要是6~20長度的ASSCII編碼字符) A hardware serial number, which MUST be available and unique across devices with the same MODEL and MANUFACTURER. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^([a-zA-Z0-9]{6,20})$”.
在設(shè)置-》關(guān)于設(shè)備-》狀態(tài)信息中,顯示的信息來自android.os.Build.SERIAL,代碼位于: frameworks/base/core/java/android/os/Build.java: public static final String SERIAL = getString("ro.serialno");
frameworks/base/core/java/android/os/Build.java: private static String getString(String property) { return SystemProperties.get(property, UNKNOWN); }
由此可見是通過key為"ro.serialno"的SystemProperties 獲取到串號(hào)的,接下來看一下ro.serialno是如何賦值的: 先看init代碼system/core/init/init.c int main(int argc, char **argv) { ....... property_init();
get_hardware_name(hardware, &revision);
process_kernel_cmdline(); ......
原來是從cmdline中獲取的,import_kernel_cmdline把u-boot傳給kernel的cmdline進(jìn)行提取,然后回調(diào)import_kernel_nv進(jìn)行處理 static void process_kernel_cmdline(void) { ...... import_kernel_cmdline(0, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(1, import_kernel_nv); ...... export_kernel_boot_props(); }
import_kernel_nv將cmdline中androidboot.開頭的全部轉(zhuǎn)化為"ro.boot.%s"并設(shè)置到properties中,例如“androidboot.serialno”為“ro.boot.serialno”: static void import_kernel_nv(char *name, int for_emulator) { ...... } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) { const char *boot_prop_name = name + 12; char prop[PROP_NAME_MAX]; int cnt;
cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name); if (cnt < PROP_NAME_MAX) property_set(prop, value); } }
再來看export_kernel_boot_props函數(shù),將ro.boot.serialno賦值給ro.serialno了 static void export_kernel_boot_props(void) { ...... } prop_map[] = { { "ro.boot.serialno", "ro.serialno", "", }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, };
for (i = 0; i < ARRAY_SIZE(prop_map); i++) { ret = property_get(prop_map[i].src_prop, tmp); if (ret > 0) property_set(prop_map[i].dest_prop, tmp); else property_set(prop_map[i].dest_prop, prop_map[i].def_val); }
再來看看u-boot是如何獲取串號(hào)的: u-boot-2014.07/common/cmd_boota.c中有對androidboot.serialno的賦值: void update_bootargs(void) { ...... //serial info str = getenv("sunxi_serial"); sprintf(tmpbuf," androidboot.serialno=%s",str); ...... }
其值來自于u-boot env sunxi_serial,sunxi_serial又是由DTS中的/soc/serial_feature定義的,由sys_config.fex轉(zhuǎn)換的dts內(nèi)容,sn.txt又是放在private分區(qū)中。 [serial_feature] sn_filename = "sn.txt"
int sunxi_set_serial_num(void) { char serial[128] = {0}; if(get_serial_num_from_file(serial)) { get_serial_num_from_chipid(serial); } printf("serial is: %s\n",serial); if(setenv("sunxi_serial", serial)) { printf("error:set variable [sunxi_serial] fail\n"); } return 0; }
就用private分區(qū)存放sn.txt這種方式來驗(yàn)證一下: busybox mkfs.vfat /dev/block/by-name/private busybox mount -t vfat /dev/block/by-name/private /private/ echo "XXXX2017030219360001">/private/sn.txt sync
重啟系統(tǒng),發(fā)現(xiàn)串號(hào)變成了我們sn.txt里面的內(nèi)容,重新刷機(jī)驗(yàn)證序列號(hào)沒有被清掉。
另外根據(jù)android兼容說明,串號(hào)必須滿足以下要求(主要是6~20長度的ASSCII編碼字符) A hardware serial number, which MUST be available and unique across devices with the same MODEL and MANUFACTURER. The value of this field MUST be encodable as 7-bit ASCII and match the regular expression “^([a-zA-Z0-9]{6,20})$”.
總結(jié)
以上是生活随笔為你收集整理的Android设备硬件序列号(SN、串号)分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kubernetes pod NodeL
- 下一篇: 一文详解深度相机之双目成像