static int switch_to_sf_bootargs(void) { char bootcmd[1024]; char bootargs[1024]; if (fw_env_open()) { ERROR("Failed calling fw_env_open"); return -1; } strncpy(bootcmd,sfbootcmd,1023); strncpy(bootargs,sfbootargs,1023); if (fw_env_write("bootcmd",bootcmd) || fw_env_write("bootargs",bootargs)) { ERROR("Error writing sf boot vars to uboot"); return -1; } if(fw_env_close()) { ERROR("Error calling fw_env_close"); return -1; } return 0; }
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; }
int fw_set_one_env (const char *name, const char *value) { if (fw_env_open ()) { fprintf (stderr, "Error: environment not initialized\n"); return -1; } fw_env_write ((char *)name, (char *)value); return fw_env_close (); }
int bootloader_apply_list(const char *filename) { int lockfd; int ret; lockfd = lock_uboot_env(); if (lockfd < 0) { ERROR("Error opening U-Boot lock file %s, %s", lockname, strerror(errno)); return -ENODEV; } ret = fw_parse_script((char *)filename, fw_env_opts); fw_env_close (fw_env_opts); unlock_uboot_env(lockfd); return ret; }
int bootloader_env_set(const char *name, const char *value) { int lock = lock_uboot_env(); int ret; if (lock < 0) return -1; if (fw_env_open (fw_env_opts)) { ERROR("Error: environment not initialized, %s", strerror(errno)); unlock_uboot_env(lock); return -1; } fw_env_write ((char *)name, (char *)value); ret = fw_env_flush(fw_env_opts); fw_env_close (fw_env_opts); unlock_uboot_env(lock); return ret; }
int apply_upgrade(const char *data, unsigned int data_length) { int i, ret; struct fwheader *header = (struct fwheader *) data; if (le32toh(header->magic) != FWUPGRADE_MAGIC) { printf("ERROR: Invalid firmware magic, aborting.\n"); return -1; } if (le32toh(header->hwid) != THIS_HWID) { printf("ERROR: Invalid HWID, aborting.\n"); return -1; } /* First loop to verify the CRC */ for (i = 0; i < FWPART_COUNT; i++) { unsigned int sz, offset; char computed_crc[FWPART_CRC_SZ]; sz = le32toh(header->parts[i].length); if (! sz) continue; printf("Checking part %s\n", header->parts[i].name); offset = le32toh(header->parts[i].offset); md5(data + offset, sz, computed_crc); if (memcmp(computed_crc, header->parts[i].crc, FWPART_CRC_SZ)) { printf("ERROR: Invalid CRC in firmware image part %s\n", header->parts[i].name); return -1; } } ret = fw_env_open(); if (ret) { printf("ERROR: Cannot read the U-Boot environment, aborting.\n"); return -1; } /* Second loop to actually apply the upgrade */ for (i = 0; i < FWPART_COUNT; i++) { unsigned int sz, offset; int ret; sz = le32toh(header->parts[i].length); if (! sz) continue; printf("Applying part %s\n", header->parts[i].name); offset = le32toh(header->parts[i].offset); ret = handle_fwpart(header->parts[i].name, data + offset, sz); if (ret) return ret; } ret = fw_env_close(); if (ret) { printf("ERROR: Could not rewrite U-Boot environment, aborting\n"); return -1; } return 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; }