char *bootloader_env_get(const char *name) { int lock; char *value = NULL; char *var; lock = lock_uboot_env(); if (lock < 0) return NULL; if (fw_env_open (fw_env_opts)) { ERROR("Error: environment not initialized, %s", strerror(errno)); unlock_uboot_env(lock); return NULL; } var = fw_getenv((char *)name); if (var) value = strdup(var); fw_env_close (fw_env_opts); unlock_uboot_env(lock); return value; }
static uint32_t get_memsize_from_env(void) { int memsize = 0; char *p; p = fw_getenv("memsize"); if (p) memsize = memparse(p, NULL); return memsize; }
static void activate_context(struct modemdata *data, const char *objpath) { GError *err = NULL; data->context = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, OFONO_SERVICE, objpath, /* FIXME */ OFONO_CONTEXT_INTERFACE, NULL, &err); if (err) { g_warning("no proxy for context: %s\n", err->message); g_error_free(err); return; } strcpy(ipv4.gateway, "0.0.0.0"); g_signal_connect(data->context, "g-signal", G_CALLBACK(context_signal_cb), data); get_process_props(data->context, data, check_context_prop); if (!data->context_active) { char *apn = fw_getenv("pongo_apn"); char *apn_user = fw_getenv("pongo_apn_user"); char *apn_passwd = fw_getenv("pongo_apn_pw"); if (!apn) apn = "internet"; if (strlen(apn) < 2) { g_free(apn); apn = "internet"; } set_proxy_property(data->context, "AccessPointName", g_variant_new_string(apn)); if (apn_user) set_proxy_property(data->context, "Username", g_variant_new_string(apn_user)); if (apn_passwd) set_proxy_property(data->context, "Password", g_variant_new_string(apn_passwd)); set_proxy_property(data->context, "Active", g_variant_new_boolean(TRUE)); } }
unsigned long fw_getenvl(char *envname) { unsigned long envl = 0UL; char *str; int tmp; str = fw_getenv(envname); if (str) { tmp = kstrtoul(str, 0, &envl); if (tmp) envl = 0; } return envl; }
static void __init console_config(void) { char console_string[40]; int baud = 0; char parity = '\0', bits = '\0', flow = '\0'; char *s; s = fw_getenv("modetty0"); if (s) { while (*s >= '0' && *s <= '9') baud = baud*10 + *s++ - '0'; if (*s == ',') s++; if (*s) parity = *s++; if (*s == ',') s++; if (*s) bits = *s++; if (*s == ',') s++; if (*s == 'h') flow = 'r'; } if (baud == 0) baud = 38400; if (parity != 'n' && parity != 'o' && parity != 'e') parity = 'n'; if (bits != '7' && bits != '8') bits = '8'; if (flow == '\0') flow = 'r'; if ((strstr(fw_getcmdline(), "earlycon=")) == NULL) { sprintf(console_string, "uart8250,io,0x3f8,%d%c%c", baud, parity, bits); setup_early_serial8250_console(console_string); } if ((strstr(fw_getcmdline(), "console=")) == NULL) { sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); strcat(fw_getcmdline(), console_string); pr_info("Config serial console:%s\n", console_string); } }
fw_memblock_t * __init fw_getmdesc(void) { char *memsize_str, *ptr; unsigned int memsize; static char cmdline[COMMAND_LINE_SIZE] __initdata; long val; int tmp; /* otherwise look in the environment */ memsize_str = fw_getenv("memsize"); if (!memsize_str) { pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); physical_memsize = 0x02000000; } else { tmp = kstrtol(memsize_str, 0, &val); physical_memsize = (unsigned long)val; } #ifdef CONFIG_CPU_BIG_ENDIAN /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last word of physical memory */ physical_memsize -= PAGE_SIZE; #endif /* Check the command line for a memsize directive that overrides the physical/default amount */ strcpy(cmdline, arcs_cmdline); ptr = strstr(cmdline, "memsize="); if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) ptr = strstr(ptr, " memsize="); if (ptr) memsize = memparse(ptr + 8, &ptr); else memsize = physical_memsize; memset(mdesc, 0, sizeof(mdesc)); mdesc[0].type = fw_dontuse; mdesc[0].base = 0x00000000; mdesc[0].size = 0x00001000; mdesc[1].type = fw_code; mdesc[1].base = 0x00001000; mdesc[1].size = 0x000ef000; /* * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the * south bridge and PCI access always forwarded to the ISA Bus and * BIOSCS# is always generated. * This mean that this area can't be used as DMA memory for PCI * devices. */ mdesc[2].type = fw_dontuse; mdesc[2].base = 0x000f0000; mdesc[2].size = 0x00010000; mdesc[3].type = fw_dontuse; mdesc[3].base = 0x00100000; mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; mdesc[4].type = fw_free; mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); mdesc[4].size = memsize - mdesc[4].base; return &mdesc[0]; }
// command line args come from, in decreasing precedence: // - the actual command line // - the bootloader control block (one per line, after "recovery") // - the contents of COMMAND_FILE (one per line) static void get_args(int *argc, char ***argv) { struct bootloader_message boot; memset(&boot, 0, sizeof(boot)); get_bootloader_message(&boot); // this may fail, leaving a zeroed structure if (boot.command[0] != 0 && boot.command[0] != 255) { LOGI("Boot command: %.*s\n", sizeof(boot.command), boot.command); } if (boot.status[0] != 0 && boot.status[0] != 255) { LOGI("Boot status: %.*s\n", sizeof(boot.status), boot.status); } // --- if arguments weren't supplied, look in the bootloader control block if (*argc <= 1) { boot.recovery[sizeof(boot.recovery) - 1] = '\0'; // Ensure termination const char *arg = strtok(boot.recovery, "\n"); if (arg != NULL && !strcmp(arg, "recovery")) { *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = strdup(arg); for (*argc = 1; *argc < MAX_ARGS; ++*argc) { if ((arg = strtok(NULL, "\n")) == NULL) break; (*argv)[*argc] = strdup(arg); } LOGI("Got arguments from boot message\n"); } else if (boot.recovery[0] != 0 && boot.recovery[0] != 255) { LOGE("Bad boot message\n\"%.20s\"\n", boot.recovery); } } // --- if that doesn't work, try the command file form bootloader:recovery_command if (*argc <= 1) { char *parg = NULL; char *recovery_command = fw_getenv ("recovery_command"); if (recovery_command != NULL && strcmp(recovery_command, "")) { char *argv0 = (*argv)[0]; *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = argv0; // use the same program name char buf[MAX_ARG_LENGTH]; strcpy(buf, recovery_command); if((parg = strtok(buf, "#")) == NULL){ LOGE("Bad bootloader arguments\n\"%.20s\"\n", recovery_command); }else{ (*argv)[1] = strdup(parg); // Strip newline. for (*argc = 2; *argc < MAX_ARGS; ++*argc) { if((parg = strtok(NULL, "#")) == NULL){ break; }else{ (*argv)[*argc] = strdup(parg); // Strip newline. } } LOGI("Got arguments from bootloader\n"); } } else { LOGE("Bad bootloader arguments\n\"%.20s\"\n", recovery_command); } } // --- if that doesn't work, try the command file char * temp_args =NULL; if (*argc <= 1) { FILE *fp = fopen_path(COMMAND_FILE, "r"); if (fp != NULL) { char *argv0 = (*argv)[0]; *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = argv0; // use the same program name char buf[MAX_ARG_LENGTH]; for (*argc = 1; *argc < MAX_ARGS; ) { if (!fgets(buf, sizeof(buf), fp)) break; temp_args = strtok(buf, "\r\n"); if(temp_args == NULL) continue; (*argv)[*argc] = strdup(temp_args); // Strip newline. ++*argc; } check_and_fclose(fp, COMMAND_FILE); LOGI("Got arguments from %s\n", COMMAND_FILE); } } // -- sleep 1 second to ensure SD card initialization complete usleep(1000000); // --- if that doesn't work, try the sdcard command file if (*argc <= 1) { FILE *fp = fopen_path(SDCARD_COMMAND_FILE, "r"); if (fp != NULL) { char *argv0 = (*argv)[0]; *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = argv0; // use the same program name char buf[MAX_ARG_LENGTH]; for (*argc = 1; *argc < MAX_ARGS; ) { if (!fgets(buf, sizeof(buf), fp)) break; temp_args = strtok(buf, "\r\n"); if(temp_args == NULL) continue; (*argv)[*argc] = strdup(temp_args); // Strip newline. ++*argc; } check_and_fclose(fp, SDCARD_COMMAND_FILE); LOGI("Got arguments from %s\n", SDCARD_COMMAND_FILE); } } // --- if that doesn't work, try the udisk command file if (*argc <= 1) { FILE *fp = fopen_path(UDISK_COMMAND_FILE, "r"); if (fp != NULL) { char *argv0 = (*argv)[0]; *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = argv0; // use the same program name char buf[MAX_ARG_LENGTH]; for (*argc = 1; *argc < MAX_ARGS; ) { if (!fgets(buf, sizeof(buf), fp)) break; temp_args = strtok(buf, "\r\n"); if(temp_args == NULL) continue; (*argv)[*argc] = strdup(temp_args); // Strip newline. ++*argc; } check_and_fclose(fp, UDISK_COMMAND_FILE); LOGI("Got arguments from %s\n", UDISK_COMMAND_FILE); } } // --- if no argument, then force show_text if (*argc <= 1) { char *argv0 = (*argv)[0]; *argv = (char **) malloc(sizeof(char *) * MAX_ARGS); (*argv)[0] = argv0; // use the same program name (*argv)[1] = "--show_text"; *argc = 2; } // --> write the arguments we have back into the bootloader control block // always boot into recovery after this (until finish_recovery() is called) strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); int i; for (i = 1; i < *argc; ++i) { strlcat(boot.recovery, (*argv)[i], sizeof(boot.recovery)); strlcat(boot.recovery, "\n", sizeof(boot.recovery)); } set_bootloader_message(&boot); }
static void __init append_memory(void *fdt, int root_off) { __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; unsigned long memsize; unsigned mem_entries; int i, err, mem_off; enum mem_map mem_map; u32 config; char *var, param_name[10], *var_names[] = { "ememsize", "memsize", }; /* if a memory node already exists, leave it alone */ mem_off = fdt_path_offset(fdt, "/memory"); if (mem_off >= 0) return; /* find memory size from the bootloader environment */ for (i = 0; i < ARRAY_SIZE(var_names); i++) { var = fw_getenv(var_names[i]); if (!var) continue; err = kstrtoul(var, 0, &physical_memsize); if (!err) break; pr_warn("Failed to read the '%s' env variable '%s'\n", var_names[i], var); } if (!physical_memsize) { pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); physical_memsize = 32 << 20; } if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) { /* * SOC-it swaps, or perhaps doesn't swap, when DMA'ing * the last word of physical memory. */ physical_memsize -= PAGE_SIZE; } /* default to using all available RAM */ memsize = physical_memsize; /* allow the user to override the usable memory */ for (i = 0; i < ARRAY_SIZE(var_names); i++) { snprintf(param_name, sizeof(param_name), "%s=", var_names[i]); var = strstr(arcs_cmdline, param_name); if (!var) continue; memsize = memparse(var + strlen(param_name), NULL); } /* if the user says there's more RAM than we thought, believe them */ physical_memsize = max_t(unsigned long, physical_memsize, memsize); /* detect the memory map in use */ if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { /* ROCit has a register indicating the memory map in use */ config = readl((void __iomem *)CKSEG1ADDR(ROCIT_CONFIG_GEN1)); mem_map = config & ROCIT_CONFIG_GEN1_MEMMAP_MASK; mem_map >>= ROCIT_CONFIG_GEN1_MEMMAP_SHIFT; } else {
fw_memblock_t * __init fw_getmdesc(int eva) { char *memsize_str, *ememsize_str = NULL, *ptr; unsigned long memsize = 0, ememsize = 0; static char cmdline[COMMAND_LINE_SIZE] __initdata; int tmp; /* otherwise look in the environment */ memsize_str = fw_getenv("memsize"); if (memsize_str) tmp = kstrtol(memsize_str, 0, &memsize); if (eva) { /* Look for ememsize for EVA */ ememsize_str = fw_getenv("ememsize"); if (ememsize_str) tmp = kstrtol(ememsize_str, 0, &ememsize); } if (!memsize && !ememsize) { pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); physical_memsize = 0x02000000; } else { /* If ememsize is set, then set physical_memsize to that */ physical_memsize = ememsize ? : memsize; } #ifdef CONFIG_CPU_BIG_ENDIAN /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last word of physical memory */ physical_memsize -= PAGE_SIZE; #endif /* Check the command line for a memsize directive that overrides the physical/default amount */ strcpy(cmdline, arcs_cmdline); ptr = strstr(cmdline, "memsize="); if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) ptr = strstr(ptr, " memsize="); /* And now look for ememsize */ if (eva) { ptr = strstr(cmdline, "ememsize="); if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) ptr = strstr(ptr, " ememsize="); } if (ptr) memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr); else memsize = physical_memsize; /* Last 64K for HIGHMEM arithmetics */ if (memsize > 0x7fff0000) memsize = 0x7fff0000; memset(mdesc, 0, sizeof(mdesc)); mdesc[0].type = fw_dontuse; mdesc[0].base = PHYS_OFFSET; mdesc[0].size = 0x00001000; mdesc[1].type = fw_code; mdesc[1].base = mdesc[0].base + 0x00001000UL; mdesc[1].size = 0x000ef000; /* * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the * south bridge and PCI access always forwarded to the ISA Bus and * BIOSCS# is always generated. * This mean that this area can't be used as DMA memory for PCI * devices. */ mdesc[2].type = fw_dontuse; mdesc[2].base = mdesc[0].base + 0x000f0000UL; mdesc[2].size = 0x00010000; mdesc[3].type = fw_dontuse; mdesc[3].base = mdesc[0].base + 0x00100000UL; mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - 0x00100000UL; mdesc[4].type = fw_free; mdesc[4].base = mdesc[0].base + CPHYSADDR(PFN_ALIGN(&_end)); mdesc[4].size = memsize - CPHYSADDR(mdesc[4].base); return &mdesc[0]; }
static int switch_to_sd_bootargs(void) { char startName[32]; char sizeName[32]; char c; char bootcmd[1024]; char bootargs[1024]; char bootcmdName[16]; char bootargsName[16]; strncpy(startName, "kernel_start",31); strncpy(sizeName, "kernel_size",31); if (fw_getenv(startName) && fw_getenv(sizeName)) { strncpy(startName,"rootfs_start",31); strncpy(sizeName,"rootfs_size",31); if (fw_getenv(startName) && fw_getenv(sizeName)) { c = 0; } else { c = 1; } } else { strncpy(startName,"rootfs_start",31); strncpy(sizeName,"rootfs_size",31); if (fw_getenv(startName) && fw_getenv(sizeName)) { c = 2; } else { ERROR("No uboot vars for backup firmware booting"); return -1; } } if (fw_env_open()) { ERROR("Failed calling fw_env_open"); return -1; } switch (c) { case 0: strncpy(bootcmd,sdbootcmd,1023); strncpy(bootargs,sdbootargs,1023); break; case 1: strncpy(bootcmd,sdbootcmdkernel,1023); strncpy(bootargs,sdbootargskernel,1023); break; case 2: strncpy(bootcmd,sdbootcmdrootfs,1023); strncpy(bootargs,sdbootargsrootfs,1023); break; default: return -1; } strncpy(bootcmdName,"bootcmd",15); strncpy(bootargsName,"bootargs",15); if (fw_env_write(bootcmdName,bootcmd) || fw_env_write(bootargsName,bootargs)) { ERROR("Error writing sd backup boot vars to uboot"); return -1; } if(fw_env_close()) { ERROR("Error calling fw_env_close"); return -1; } return 0; }
static int sd_write_image(int mtdnum, struct img_type *img) { char startName[32]; char sizeName[32]; char *value; int fdout = -1; FILE* fp = NULL; char line[512]; //size of a block long long startBlock, sizeInBlocks, kernelStartBlock, kernelBlocks; ssize_t bytesWritten,bytesRead, totalBytesWritten; int blocksWritten; int ret = 0; unsigned long offs; off_t pos; struct flash_description *flash = get_flash_info(); struct mtd_dev_info *mtd1, *mtd2; mtd2 = &flash->mtd_info[2].mtd; mtd1 = &flash->mtd_info[1].mtd; if (1 == mtdnum) { strncpy(sizeName,"kernel_size",31); } else if (2 == mtdnum) { //rootfs strncpy(sizeName,"rootfs_size",31); } else { return 0; } pos = lseek(img->fdin,0,SEEK_CUR); if (pos < 0) { ERROR( "%s: %s: %s", __func__, "lseek failed\n", strerror(errno)); return -1; } //attempt to write firmware to backup sd partition, if it doesn't have backup fw already value = fw_getenv(sizeName); if (!value) { if ((fdout = open("/dev/mmcblk0p2", O_WRONLY)) < 0) { ERROR( "%s: %s: %s", __func__, "/dev/mmcblk0p2", strerror(errno)); ret = -1; goto err; } fp = popen("fdisk -ul /dev/mmcblk0 | grep /dev/mmcblk0p2 | awk '{print $2}'","r"); if (fp == NULL) { ERROR( "%s: %s: %s", __func__, "popen", strerror(errno)); ret = -1; goto err; } if (NULL == fgets(line,511,fp)) { ERROR( "%s: %s: %s", __func__, "fgets from popen'd file pointer", strerror(errno)); ret = -1; goto err; } kernelStartBlock = strtoll(line,NULL,10); if (kernelStartBlock == 0) { ERROR( "%s: %s: %s", __func__, "kernel start block is 0\n", strerror(errno)); ret = -1; goto err; } kernelBlocks = ((mtd1->size) % 512 == 0) ? (mtd1->size)/512 : (mtd1->size)/512 + 1; if (1 == mtdnum) { startBlock = kernelStartBlock; sizeInBlocks = kernelBlocks; strncpy(startName,"kernel_start",31); offs = 0; } else { startBlock = kernelStartBlock + kernelBlocks; sizeInBlocks = ((mtd2->size) % 512 == 0) ? (mtd2->size)/512 : (mtd2->size)/512 + 1; strncpy(startName,"rootfs_start",31); offs = kernelBlocks * 512; } if (lseek(fdout,offs,SEEK_SET) < 0) { ERROR( "%s: %s: %s", __func__, "lseek error", strerror(errno)); ret = -1; goto err; } TRACE("Copying %s to backup SD partition.",img->fname); totalBytesWritten = 0; blocksWritten = 0; while ((bytesRead = read(img->fdin,line,512)) > 0) { memset(line + bytesRead,0,512-bytesRead); bytesWritten = write(fdout,line,512); if (bytesWritten != 512) { ERROR("Did not write a complete block to SD\n"); ret = -1; goto err; } totalBytesWritten += bytesWritten; blocksWritten++; } if (0 == ret) { if (fw_env_open()) { ERROR("Failure calling fw_env_open"); ret = -1; goto err; } snprintf(line,511,"0x%llx",startBlock); if (fw_env_write(startName,line)) { ERROR("Failure calling fw_env_write"); ret = -1; goto err; } snprintf(line,511,"0x%llx",sizeInBlocks); if (fw_env_write(sizeName,line)) { ERROR("Failure calling fw_env_write"); ret = -1; goto err; } if (fw_env_close()) { ERROR("Failure calling fw_env_close"); ret = -1; goto err; } } TRACE("kernelStartBlock: %lld, kernelBlocks: %lld, startblock: %lld, blocks: %lld, ret: %d, totalBytesWritten: %zd, blocksWritten: %d\n",kernelStartBlock,kernelBlocks,startBlock,sizeInBlocks,ret,totalBytesWritten,blocksWritten); } err: //restore img->fdin. If we fail here, we give a special error code because we absolutely cannot proceed in this error case (will probably result in corrupt serial flash firmware) if (lseek(img->fdin,pos,SEEK_SET) < 0) { ERROR( "%s: %s: %s", __func__, "lseek error", strerror(errno)); ret = -2; } if (fdout >= 0) {close(fdout);} if (fp) {pclose(fp);} return ret; }