在android5.1的init进程中加入读取手机序列码

来源:互联网 发布:网络用语ysl什么意思 编辑:程序博客网 时间:2024/06/07 06:23

在and4.4上之前在init进程中读取amt/sn.txt中的内容,设置到"ro.serialno"的系统属性中。而Settings会去读取这个属性的值,从而将手机的序列码显示出来。

    if (!is_charger) {        action_for_each_trigger("early-fs", action_add_queue_tail);        action_for_each_trigger("fs", action_add_queue_tail);        action_for_each_trigger("post-fs", action_add_queue_tail);        action_for_each_trigger("post-fs-data", action_add_queue_tail);    }    /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random     * wasn't ready immediately after wait_for_coldboot_done     */    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");    queue_builtin_action(property_service_init_action, "property_service_init");    queue_builtin_action(signal_init_action, "signal_init");    queue_builtin_action(check_startup_action, "check_startup");    queue_builtin_action(set_usb_serial_action, "set_usb_serial_action");    

set_usb_serial_action函数就是读取sn.txt的内容,如果没有这个文件再从/amt/nvram_amt_data.bin读取,这里就不再详细展开这个函数。

直接看代码吧:

static int set_usb_serial_action(int nargs,char **args) {    FILE *fp;    char serial_no[LINE_SIZE] = {0};    int len = 0;    bool isSNExist = true;    fp = fopen(SN_FILE, "r");    if (fp == NULL) {        isSNExist = false;        ERROR("file %s is not exist in AMT\n", SN_FILE);        fp = fopen(NVRAM_AMT_DATA_FILE, "r");        if (fp == NULL) {            property_set("ro.serialno", "");            ERROR("both %s and %s is not exist in AMT\n", SN_FILE, NVRAM_AMT_DATA_FILE);            goto fail_exit;        }        int result = fseek(fp, 0x560, SEEK_SET);        if (result) {            property_set("ro.serialno","");            ERROR("seek file %s error", NVRAM_AMT_DATA_FILE);            goto fail_exit;        }    }    if (fgets(serial_no, LINE_SIZE, fp) == NULL) {        ERROR("read file error");        property_set("ro.serialno","");        goto fail_exit;    }    for (len = 0; len < LINE_SIZE; len++) {        if(serial_no[len] == 0)            break;    }    if (len == 0) {        property_set("ro.serialno","0123456789ABCDEF");        goto fail_exit;    }    property_set("ro.serialno", serial_no);    fclose(fp);    if (!isSNExist) {        fp = fopen(SN_FILE, "w");        if (fp) {            fwrite(serial_no, sizeof(char), len, fp);            fclose(fp);            chown(SN_FILE, AID_ROOT, AID_RADIO);            chmod(SN_FILE, S_IRUSR | S_IWUSR);        }    }    return 0;fail_exit:    if (fp)        fclose(fp);    return -1;}

然后把这个函数移植到5.1,同样放在执行队列的最后,确没有成功。log显示读取文件失败。

先是怀疑5.1上开启了selinux,于是在init.te中加入了对/amt目录的读取权限,但还是不行,将selinux的CR回退结果还是一样。于是就排除了selinux的问题。


排序selinux的问题后,基本上确定是amt分区还没有加载的原因。

于是先去搜4.1的init.rc,将amt分区挂载是在fs触发器中,在4.4的init是将fs这个触发器单独放在执行列表中,而我们的函数放在其后面,所以是没有问题的。

fs触发器的内容如下,其中就有挂载amt分区

on fs    # mount partitions    mount_all /fstab.leadcoreinnopower    # enable swap    swapon_all /fstab.leadcoreinnopower    write /proc/sys/vm/page-cluster 0    # If no amt file, to prevent the failure of mount_all    mount ext4 /dev/block/platform/comip-mmc.1/by-name/amt /amt wait rw    copy /amt/vbatt /proc/driver/comip_battery    setprop ro.crypto.fuse_sdcard true

然而5.1上是将fs这个触发器放在:

on late-init    trigger early-fs    trigger fs    trigger post-fs    trigger post-fs-data
因此,在代码里放进执行队列的只是late-init,执行到late-init后再把fs等再加入执行队列。而这一步骤是在解析执行队列的时候,所以我们在之前加入队列,是肯定在fs之前了,也就是在amt分区还没有挂载的时候就去读取其中的文件,所以就出错了。

    if (is_charger) {        action_for_each_trigger("charger", action_add_queue_tail);    } else {        action_for_each_trigger("late-init", action_add_queue_tail);    }
解决的方法,是在解析到fs这个触发器的时候,再把我们这个函数加入执行队列中,这样就把这个问题解决了:

void execute_one_command(void){    int ret, i;    char cmd_str[256] = "";    if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {        cur_action = action_remove_queue_head();        cur_command = NULL;        if (!cur_action)            return;        INFO("processing action %p (%s)\n", cur_action, cur_action->name);        if (!strcmp(cur_action->name, "fs")) {            queue_builtin_action(set_usb_serial_action, "set_usb_serial_action");// 解析到fs后,再把我们的函数加入到执行队列尾        }        cur_command = get_first_command(cur_action);    } else {        cur_command = get_next_command(cur_action, cur_command);    }








1 0
原创粉丝点击