一、SN序列号
设置-设备信息-型号和硬件 可以查看到 SN 号,而通过代码分析可以知道、设置是通过读取 ro.serialno 属性来获取SN。
二、SN_Writer 写入 SN
一般我们写入 SN 号是通过MTK的工具 SN_Writer,但是要注意的是!这个工具写入SN号可以分为两种方式。这两种方式都需要注意一个地方、如下图:
一定一定不要勾方框中的玩意、否则写号的时候将不会写入 proinfo 分区,proinfo 分区的信息将会是空、你代码再怎么读读出来都是空,下面是读 proinfo 分区的源码。
vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
下面介绍两种写入的方式。
1、第一种方式 写入Barcode
写入Barcode,然后在代码里把宏开关打开
/vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
中,将 #define SERIAL_NUM_FROM_BARCODE 宏定义打开
这个时候 SN 号就会去读 写入的Barcode的值。
PS说明:用第一种方式 写入 Barcode 的时候,写入了 proinfo分区,然后开机的过程中,会将该分区的 barcode 值赋予 gsm.serialno,如果没有把 #define SERIAL_NUM_FROM_BARCODE 宏定义打开,那么将不会赋予 ro.serialno,所以这个时候你去设置下面查看该序列号,显示的SN号和你写入的SN号是不一样的。为了保证一致,所以记得打开宏定义。
这个时候开机的过程中会把分区的 barcode 值赋予 gsm.serialno 和 ro.serialno 这两个属性。
2、第二种方式 写入Serial No
注意:一般 SN_Writer 是将该选项给隐藏的、如果要想显示出来、按照MTK提供的FAQ操作。
下面是FAQ提供的资料:
1. SN Writer Tool 工具端
1.1. 用 v1.1632.00 及其之后的版本
1.2. SN Writer Tool 先关闭,修改程序目录下 SN_setup.ini 文件
Enable Serial No = True
Serial Num From IMEI = False
1.3. 打开 SN Writer Tool,进入 "System Config" 配置界面,勾选左上方的 "Serial No."
1.4. 返回主界面点击 "Start" ,在号码输入界面中 "SerialNo" 中输入序列号 注意:SerialNo 只能包含英文字母或数字
2. 移动设备端
2.1. 确认 proinfo 分区名称 早期的 MBR 分区格式设备,proinfo分区的名字是"PRO_INFO", 请通过 Scatter File 进行确认。 后续代码中涉及"proinfo"字符串判断的地方请对应修改。
2.2. /app/mt_boot/mt_boot.c 打开宏定义 打开默认关闭的 /* #define SERIAL_NUM_FROM_BARCODE */ -> #define SERIAL_NUM_FROM_BARCODE
2.3. /app/mt_boot/mt_boot.c 中 read_product_info 函数 修改为以下:
static inline int read_product_info(char *buf) {
#define PROINFO_OFFSET 116 // barcode:64 + imei:40 + bt:6 + wifi:6 int tmp = 0;
char * buf_blk = (char *)0;
if (!buf) return 0;
buf_blk = malloc(BLK_SIZE);
if (!buf_blk)
{
dprintf(CRITICAL, "[error] alloc proinfo buffer fail.\n");
return 0;
}
memset(buf_blk, 0, BLK_SIZE);
dprintf(CRITICAL, "begin read proinfo\n");
tmp = mboot_recovery_load_raw_part("proinfo", buf_blk, BLK_SIZE);
if (tmp != BLK_SIZE)
{
dprintf(CRITICAL, "[error] read proinfo fail, only read size %d, block size %d.\n", tmp, BLK_SIZE);
free(buf_blk);
return 0;
}
memcpy(buf, buf_blk + PROINFO_OFFSET, SN_BUF_LEN);
buf[SN_BUF_LEN] = '\0';
dprintf(CRITICAL, "get serialno from proinfo: \"%s\"\n", buf);
free(buf_blk);
for (tmp = 0; tmp < SN_BUF_LEN; tmp++)
{
if ( (buf[tmp] == 0 || buf[tmp] == 0x20) && tmp > 0)
{
break;
}
else if ( !isalpha(buf[tmp]) && !isdigit(buf[tmp]))
return 0;
}
return tmp;
}
3. 编译LK,烧入机器,用 SN Writer tool写入 serial num。
四、后续
如果想了解具体的过程、可以阅读源码、打log理清。
vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c
void mt_boot_init(const struct app_descriptor *app)
{
unsigned usb_init = 0;
unsigned sz = 0;
#ifdef MTK_AB_OTA_UPDATER
int ret;
#endif
set_serial_num();
#ifdef MTK_DEBUG_SHELL
if (app != NULL)
goto lk_debug;
#endif
if (g_boot_mode == FASTBOOT)
goto fastboot;
#ifdef MTK_SECURITY_SW_SUPPORT
#if MTK_FORCE_VERIFIED_BOOT_SIG_VFY
/* verify oem image with android verified boot signature instead of mediatek proprietary signature */
/* verification is postponed to boot image loading stage */
/* note in this case, boot/recovery image will be verified even when secure boot is disabled */
g_boot_state = BOOT_STATE_RED;
#else
if (0 != sec_boot_check(0))
g_boot_state = BOOT_STATE_RED;
#endif
#endif
/* Will not return */
boot_linux_from_storage();
fastboot:
target_fastboot_init();
if (!usb_init)
udc_init(&surf_udc_device);
mt_part_dump();
sz = target_get_max_flash_size();
fastboot_init(target_get_scratch_address(), sz);
udc_start();
#ifdef MTK_DEBUG_SHELL
lk_debug:
mtk_wdt_disable();
dprintf(INFO, "mt_boot_init not go to kernel and disable wdt !!\n");
#endif
}
其中的 set_serial_num() 函数
static void set_serial_num(void)
{
unsigned int len;
char *id_tmp = get_env("MTK_DEVICE_ID");
if (!id_tmp) {
pal_log_info("Set serial # to default value.\n");
len = strlen(DEFAULT_SERIAL_NUM);
len = (len < SN_BUF_LEN) ? len : SN_BUF_LEN;
strncpy(sn_buf, DEFAULT_SERIAL_NUM, len);
sn_buf[len] = '\0';
} else {
pal_log_info("Set serial # from para.\n");
len = strlen(id_tmp);
len = (len < SN_BUF_LEN) ? len : SN_BUF_LEN;
strncpy(sn_buf, id_tmp, len);
sn_buf[len] = '\0';
}
#ifdef CONFIG_MTK_USB_UNIQUE_SERIAL
int errcode = read_product_usbid(sn_buf);
if (errcode)
pal_log_err("Set serial # from efuse. error: %d\n", errcode);
len = strlen(sn_buf);
len = (len < SN_BUF_LEN) ? len : SN_BUF_LEN;
sn_buf[len] = '\0';
#endif // CONFIG_MTK_USB_UNIQUE_SERIAL
#ifdef SERIAL_NUM_FROM_BARCODE
len = (unsigned int)read_product_info(sn_buf); // sn_buf[] may be changed.
if (len == 0) {
len = strlen(DEFAULT_SERIAL_NUM);
len = (len < SN_BUF_LEN) ? len : SN_BUF_LEN;
strncpy(sn_buf, DEFAULT_SERIAL_NUM, len);
} else
len = (len < SN_BUF_LEN) ? len : SN_BUF_LEN;
sn_buf[len] = '\0';
#endif // SERIAL_NUM_FROM_BARCODE
//pal_log_err("Serial #: \"%s\"\n", sn_buf);
surf_udc_device.serialno = sn_buf;
}