流程大致是lk啟動(dòng)后會(huì)啟動(dòng)kernel,這時(shí)候會(huì)傳一個(gè)cmdline過去,cmdline包含了androidboot.serialno,這個(gè)在aboot啟動(dòng)kernel的時(shí)候生成,存放目錄是在proc/cmdline,該值實(shí)際上是從nv中讀取過來的,如果讀取不到,就是null,有些平臺(tái)會(huì)定義default值是0-F,aboot啟動(dòng)kernel后,init進(jìn)程中的import_kernel_nv會(huì)讀取cmdline 然后將ro.boot.serialno 賦值,這樣sn開機(jī)就已經(jīng)確認(rèn)下來了,那么想修改從哪下手?
不可行方案:從aboot讀取cid,這個(gè)不可行是因?yàn)閍boot起來的時(shí)候 kernel沒有啟動(dòng),所以相關(guān)file、io操作并不能執(zhí)行!文件系統(tǒng)都沒有mount
可行方案:
Android 5.0 在init.c的import_kernel_nv函數(shù)中進(jìn)行讀取cid,并且在ro.boot.serialno賦值前取到,可判斷cmdline里的androidboot。serialno是否為0-F,如果是就證明nv中沒有寫sn,可以把cid截取部分(我這邊截取的后10位)作為sn,這樣既可解決adb devices時(shí)沒有序列號(hào)或者顯示0-F的問題,也可解決三方app讀取問題,但是fastboot模式下devicesinifo信息則還可能為0-F,但絕對(duì)不是截取出來的cid,因?yàn)檫€是要回歸到Boot模式下無法讀取到cid的問題,這個(gè)目前沒什么好的辦法,而且我們正常是鎖fastboot,不允許操作。
具體代碼:
static void import_kernel_nv(char *name, int for_emulator)
{
? ? char *value = strchr(name, '=');
? ? int name_len = strlen(name);
? ? if (value == 0) return;
? ? *value++ = 0;
? ? if (name_len == 0) return;
? ? if (for_emulator) {
? ? ? ? /* in the emulator, export any kernel option with the
? ? ? ? * ro.kernel. prefix */
? ? ? ? char buff[PROP_NAME_MAX];
? ? ? ? int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
? ? ? ? if (len < (int)sizeof(buff))
? ? ? ? ? ? property_set( buff, value );
? ? ? ? return;
? ? }
? ? 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;
? ? ? ? char prop[PROP_NAME_MAX];
? ? ? ? int cnt;
? ? ? ? cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
? ? ? ? if (cnt < PROP_NAME_MAX) {
? ? ? ? ? ? //xxx 20180813 begin
if(!strcmp(boot_prop_name,"serialno") && !strcmp(value,"0123456789ABCDEF")){
? ? ? ? ? ? ? ? int fd;
? ? ? ? ? ? ? ? char snubmer[256];
? ? ? ? ? ? ? ? fd = open("/sys/class/block/mmcblk0/device/cid", O_RDONLY);
? ? ? ? ? ? ? ? if (fd < 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ERROR("fail to open: %s\n", "/sys/class/block/mmcblk0/device/cid");
? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? read(fd, (void *)&snubmer, sizeof(snubmer) - 1);
? ? ? ? ? ? ? ? close(fd);
? ? ? ? ? ? ? ? char tmp_sn[10];
? ? ? ? ? ? ? ? strncpy(tmp_sn,snubmer+22,10);//截取cid的后10位
property_set(prop, tmp_sn);
}else {
property_set(prop, value);
}
? ? ? ? ? ? //xxx 20180813 end
? ? ? ? }
? ? }
}
Android 7.0后在init.cpp里的修改,只不過是c轉(zhuǎn)成c++實(shí)現(xiàn)。