/* * (C) Copyright 2017 * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_SUNXI_USER_KEY char *IGNORE_ENV_VARIABLE[] = { "console", "root", "init", "loglevel", "partitions", "vmalloc", "earlyprintk", "ion_reserve", "enforcing", "cma", "initcall_debug", "gpt", }; #define NAME_SIZE 32 int USER_DATA_NUM; char USER_DATA_NAME[10][NAME_SIZE] = { { '\0' } }; void check_user_data(void) { char *command_p = NULL; char temp_name[32] = { '\0' }; int i, j; if ((get_boot_storage_type() == STORAGE_SD) || (get_boot_storage_type() == STORAGE_EMMC)) { command_p = env_get("setargs_mmc"); } else { command_p = env_get("setargs_nand"); } //printf("cmd line = %s\n", command_p); if (!command_p) { printf("cann't get the boot_base from the env\n"); return; } while (*command_p != '\0' && *command_p != ' ') { //过滤第一个环境变酿 command_p++; } command_p++; while (*command_p == ' ') { //过滤多余的空枿 command_p++; } while (*command_p != '\0' && *command_p != ' ') { //过滤第二个环境变酿 command_p++; } command_p++; while (*command_p == ' ') { command_p++; } USER_DATA_NUM = 0; while (*command_p != '\0') { i = 0; while (*command_p != '=') { temp_name[i++] = *command_p; command_p++; } temp_name[i] = '\0'; if (i != 0) { for (j = 0; j < sizeof(IGNORE_ENV_VARIABLE) / sizeof(IGNORE_ENV_VARIABLE[0]); j++) { if (!strcmp(IGNORE_ENV_VARIABLE[j], temp_name)) { //查词典库,排除系统的环境变量,得到用户的数据 break; } } if (j >= sizeof(IGNORE_ENV_VARIABLE) / sizeof(IGNORE_ENV_VARIABLE[0])) { if (!strcmp(temp_name, "mac_addr")) { //处理mac_addr和mac不相等的情况(特殊情况) strcpy(USER_DATA_NAME[USER_DATA_NUM], "mac"); } else { strcpy(USER_DATA_NAME[USER_DATA_NUM], temp_name); } USER_DATA_NUM++; } } while (*command_p != '\0' && *command_p != ' ') { //下一个变酿 command_p++; } while (*command_p == ' ') { command_p++; } } /* printf("USER_DATA_NUM = %d\n", USER_DATA_NUM); for (i = 0; i < USER_DATA_NUM; i++) { printf("user data = %s\n", USER_DATA_NAME[i]); } */ } static int get_key_from_private(char *filename, char *data_buf, int *len) { int ret = 0; int partno = -1; char part_info[16] = { 0 }; /* format: "partno:0" */ char addr_info[32] = { 0 }; /* 00000000 */ char file_info[64] = { 0 }; char fetch_name[64] = { 0 }; char *bmp_argv[6] = { "fatload", "sunxi_flash", part_info, addr_info, file_info, NULL }; /* check serial_feature config info */ strcpy(fetch_name, filename); strcat(fetch_name, "_filename"); ret = script_parser_fetch("/soc/serial_feature", fetch_name, (int *)file_info, sizeof(file_info) / 4); if ((ret < 0) || (strlen(file_info) == 0)) { strcpy(file_info, "ULI/factory/"); strcat(file_info, filename); strcat(file_info, ".txt"); } /* check private partition info */ partno = sunxi_partition_get_partno_byname("private"); if (partno < 0) { return -1; } /* get data from file */ sprintf(part_info, "0:%x", partno); sprintf(addr_info, "%lx", (ulong)data_buf); memset(data_buf, 0, *len); if (do_fat_fsload(0, 0, 6, bmp_argv)) { pr_error("load file(%s) error.\n", bmp_argv[4]); return -1; } data_buf[*len] = 0; return 0; } int update_user_data(void) { if (get_boot_work_mode() != WORK_MODE_BOOT) { return 0; } check_user_data(); //从env中检测用户的环境变量 int data_len; int ret, k; char buffer[512]; int updata_data_num = 0; int found = 0; int sec_inited = !sunxi_secure_storage_init(); for (k = 0; k < USER_DATA_NUM; k++) { found = 0; memset(buffer, 0, 512); if (sec_inited) { ret = sunxi_secure_object_read(USER_DATA_NAME[k], buffer, 512, &data_len); if (!ret && data_len < 512) { found = 1; } } if (!found) { data_len = 512; ret = get_key_from_private(USER_DATA_NAME[k], buffer, &data_len); if (!ret) { found = 2; } } if (found) { env_set(USER_DATA_NAME[k], buffer); pr_msg("update %s = %s, source:%s\n", USER_DATA_NAME[k], buffer, found == 2 ? "private" : "secure"); memset(buffer, 0, 512); updata_data_num++; strcpy(USER_DATA_NAME[k], "\0"); } } return 0; } #endif void update_bootargs(void) { int dram_clk = 0; char *str; char cmdline[2048] = { 0 }; char tmpbuf[128] = { 0 }; char *verifiedbootstate_info = env_get("verifiedbootstate"); str = env_get("bootargs"); __attribute__((unused)) char disp_reserve[80]; strcpy(cmdline, str); if ((!strcmp(env_get("bootcmd"), "run setargs_mmc boot_normal")) || !strcmp(env_get("bootcmd"), "run setargs_nand boot_normal")) { if (gd->chargemode == 0) { pr_msg("in boot normal mode,pass normal para to cmdline\n"); strcat(cmdline, " androidboot.mode=normal"); } else { pr_msg("in charger mode, pass charger para to cmdline\n"); strcat(cmdline, " androidboot.mode=charger"); } } #ifdef CONFIG_SUNXI_SERIAL //serial info str = env_get("snum"); sprintf(tmpbuf, " androidboot.serialno=%s", str); strcat(cmdline, tmpbuf); #endif #ifdef CONFIG_SUNXI_MAC str = env_get("mac"); if (str && !strstr(cmdline, " mac_addr=")) { sprintf(tmpbuf, " mac_addr=%s", str); strcat(cmdline, tmpbuf); } str = env_get("wifi_mac"); if (str && !strstr(cmdline, " wifi_mac=")) { sprintf(tmpbuf, " wifi_mac=%s", str); strcat(cmdline, tmpbuf); } str = env_get("bt_mac"); if (str && !strstr(cmdline, " bt_mac=")) { sprintf(tmpbuf, " bt_mac=%s", str); strcat(cmdline, tmpbuf); } #endif //harware info sprintf(tmpbuf, " androidboot.hardware=%s", CONFIG_SYS_CONFIG_NAME); strcat(cmdline, tmpbuf); /*boot type*/ sprintf(tmpbuf, " boot_type=%d", get_boot_storage_type_ext()); strcat(cmdline, tmpbuf); sprintf(tmpbuf, " androidboot.boot_type=%d", get_boot_storage_type_ext()); strcat(cmdline, tmpbuf); /*Only 64bit kernel "secure_os_exist" exists * 64bit normal cpu no need OP-TEE service *secure_os_exist= 0 ---> secure os no exist *secure_os_exist= 1 ---> secure os exist * */ if (sunxi_probe_secure_monitor()) { sprintf(tmpbuf, " androidboot.secure_os_exist=%d", sunxi_probe_secure_os()); strcat(cmdline, tmpbuf); } #ifdef CONFIG_SUNXI_ANDROID_BOOT str = env_get("android_trust_chain"); if (str) { sprintf(tmpbuf, " androidboot.trustchain=%s", str); strcat(cmdline, tmpbuf); } else { sprintf(tmpbuf, " androidboot.trustchain=false"); strcat(cmdline, tmpbuf); } #endif /*dram_clk*/ script_parser_fetch("soc/dram_para", "dram_clk", (int *)&dram_clk, 1); #ifdef CONFIG_ARCH_SUN8IW15P1 sprintf(tmpbuf, " dram_clk=%d", dram_clk); strcat(cmdline, tmpbuf); #endif /* gpt support */ sprintf(tmpbuf, " gpt=1"); strcat(cmdline, tmpbuf); if (gd->securemode) { /* verified boot state info */ sprintf(tmpbuf, " androidboot.verifiedbootstate=%s", verifiedbootstate_info); strcat(cmdline, tmpbuf); } sprintf(tmpbuf, " uboot_message=%s(%s-%s)", PLAIN_VERSION, U_BOOT_DMI_DATE, U_BOOT_TIME); strcat(cmdline, tmpbuf); #ifdef CONFIG_SPINOR_LOGICAL_OFFSET /*spi-nor logical offset */ sprintf(tmpbuf, " mbr_offset=%d", (CONFIG_SPINOR_LOGICAL_OFFSET * 512)); strcat(cmdline, tmpbuf); #endif #if defined(CONFIG_BOOT_GUI) || defined(CONFIG_SUNXI_SPINOR_BMP) || defined(CONFIG_SUNXI_SPINOR_JPEG) #ifdef CONFIG_BOOT_GUI save_disp_cmdline(); #endif if (env_get("disp_reserve")) { snprintf(disp_reserve, 80, " disp_reserve=%s", env_get("disp_reserve")); strcat(cmdline, disp_reserve); } #endif #ifdef CONFIG_SUNXI_POWER str = env_get("bootreason"); if (str) { snprintf(tmpbuf, 128, " bootreason=%s", str); strcat(cmdline, tmpbuf); } #endif str = env_get("aw-ubi-spinand.ubootblks"); if (str) { snprintf(tmpbuf, 128, " aw-ubi-spinand.ubootblks=%s", str); strcat(cmdline, tmpbuf); } str = env_get("trace_enable"); if (str && strcmp(str, "1") == 0) { str = env_get("trace_buf_size"); if (str) { snprintf(tmpbuf, 128, " trace_buf_size=%s", str); strcat(cmdline, tmpbuf); } str = env_get("trace_event"); if (str) { snprintf(tmpbuf, 128, " trace_event=%s", str); strcat(cmdline, tmpbuf); } } env_set("bootargs", cmdline); pr_msg("android.hardware = %s\n", CONFIG_SYS_CONFIG_NAME); #ifdef CONFIG_SUNXI_VERIFY_BOOT_INFO_INSTALL sunxi_keymaster_verify_boot_params_install(); #endif }