⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flasher.c

📁 采用ST20 CPU的机顶盒的烧写程序
💻 C
📖 第 1 页 / 共 5 页
字号:
   * Read in entire contents of file.
   */
  if (fread(buffer, 1, fileSize, fp) == 0)
  {
    fprintf(stderr, "flasher: Failed to read from %s\n", fileName);
    exit(1);
  }

  /*
   * Check have read entire file.
   */
  if (fgetc(fp) != EOF)
  {
    fprintf(stderr, "flasher: Incomplete read from %s\n", fileName);
    exit(1);
  }

  fclose(fp);

  /*
   * Tokenise buffer into white space separated arguments.
   */
  for (s = strtok(buffer, " \n\r\t"); s; s = strtok(NULL, " \n\r\t"))
  {
    (*argc)++;
    argv = reallocate(argv, (*argc + 1) * sizeof(char*));
    argv[*argc - 1] = allocate(strlen(s) + 1);
    strcpy(argv[*argc - 1], s);
  }

  if (*argc)
  {
    argv[*argc] = NULL;
  }

  free(buffer);

  return argv;
}

/*
 * Add an image file to the given list.
 */
static void addImage(image_t* head, image_t* image)
{
  image->prev = head->prev;
  image->next = head;
  head->prev->next = image;
  head->prev = image;
}

/*
 * Routine to parse the command line.
 */
static void processCmdLine(int argc, char* argv[], int isOptionFile)
{
  int c;
  int slot;
  image_t* image;
  char* ptr;

  if (isOptionFile)
  {
    optind = 0; /* Do not skip argv[0] */
  }
  else
  {
    if (argc < 2)
    {
      usage("");
    }
  }
  
  /* We look for long options before using getopt to process the short ones.
     Any long options recognised are replaced with -[ to be ignored by getopt
     short argument processing.
   */
  for (c = 0; c < argc; c++)
  {
    if (*argv[c] == '-' && strlen(argv[c]) > 2)
    {
      /* This looks like a long option - see if it matches any of the valid ones */
      if (!strcmp(argv[c], "-fs"))
      {
        /* Fail-safe image option */
        argv[c++] = "-[";
        failsafeImage = (image_t*)allocate(sizeof(image_t));
        failsafeImage->fileName = (char*)malloc(strlen(argv[c]) + 1);
        strcpy((char*)failsafeImage->fileName, argv[c]);
        failsafeImage->slot = FAILSAFE_SLOT;
        argv[c] = "-[";
        continue;
      }
      else if (!strcmp(argv[c], "-bootsep"))
      {
        /* Separate FLASH blocks containing boot code from application code so
         * they can be protected.
         */
        argv[c] = "-[";
        separateBootAndAppFlashBlocks = 1;
        continue;
      }
    }
  }

  while ((c = getopt(argc, argv, "p:d:ev:s:i:I:b:r:f:t:[")) != EOF)
  {
    switch (c)
    {
      case 'b':
        slot = getSlot(optarg);
        bootList = reallocate(bootList, (slotsToMakeBootable + 1) * sizeof(int));
        bootList[slotsToMakeBootable++] = slot;
        break;

      case 'd':
        slot = getSlot(optarg);
        deleteList = reallocate(deleteList, (slotsToDelete + 1) * sizeof(int));
        deleteList[slotsToDelete++] = slot;
        break;

      case 'e':
        eraseFlag = 1;
        break;

      case 'f':
        if (optionFile)
        {
          usage("Cannot specify multiple -f");
        }
        optionFile = (const char*)optarg;
        optionFileArgv = inputOptionFile(optionFile, &optionFileArgc);
        break;

      case 'p':
        if (binDump)
        {
          usage("Cannot specify -p with -r");
        }
        romProgram = 1;
        romFile = (const char*)optarg;
        {
          char* addrPtr;
          if ((addrPtr = strchr(optarg, '@')))
          {
            binaryBaseAddr = getAddress(addrPtr + 1);
            *addrPtr = 0;
          }
        }
        break;

      case 'r':
        if (romProgram)
        {
          usage("Cannot specify -p with -r");
        }
        binDump = 1;
        romFile = (const char*)optarg;
        break;

      case 'i':
        image = (image_t*)allocate(sizeof(image_t));
        image->fileName = strtok(optarg, "@");
        ptr = strtok(NULL, "@");
        if (!ptr)
        {
          image->slot = ANY_SLOT;
        }
        else
        {
          image->slot = getSlot(ptr);
        }
        addImage(&images, image);
        break;

      case 's':
        image = (image_t*)allocate(sizeof(image_t));
        image->fileName = (const char*)optarg;
        image->slot = ANY_SLOT;
        addImage(&bootStraps, image);
        break;

      case 't':
        if (target)
        {
          usage("Cannot specify multiple -t");
        }
        if ((target = flashGetTarget(optarg)) == NULL)
        {
          usage("Unrecognised target board");
        }
        break;

      case 'v':
        image = (image_t*)allocate(sizeof(image_t));
        image->fileName = (const char*)optarg;
        image->slot = ANY_SLOT;
        addImage(&bootVectors, image);
        break;

      case '[':
        /* This is a replaced long option - ignore it */
        break;

      default:
        usage("Unrecognised command line switch");
        break;
    }
  }

  if ((bootStraps.next != bootStraps.next) || (bootVectors.next != bootVectors.next) ||
      (images.next != images.next) || deleteList || bootList || failsafeImage)
  {
    if (romProgram || binDump)
    {
      usage("Cannot mix -p or -r with any other options");
    }
  }
  
  if ((argc > 0) && (optind != argc))
  {
    usage("Extra characters on command line");
  }
}
#endif /* !SFXIMAGENAME */


/*
 * Routine used by determineProgramming(), which proceses a new boot vector
 * file.
 */
static void processBootVector(image_t* image, bootPages_t* bootPages)
{
  FILE* fp;
  fileHeader_t header;
  imageControl_t* imageInfo;
  unsigned int loadAddress;

  /*
   * Open up the specified image file.
   */
  if (!(fp = fopen(image->fileName, "rb")))
  {
    fprintf(stderr, "flasher: Failed to open %s\n", image->fileName);
    exit(1);
  }

  /*
   * Read in the header.
   */
  if (fread(&header, sizeof(header), 1, fp) != 1)
  {
    fprintf(stderr, "flasher: Failed to read header from %s\n", image->fileName);
    exit(1);
  }

  /*
   * It should have the correct magic number.
   */
  if (header.magic != IMAGE_FILE_MAGIC)
  {
    fprintf(stderr, "flasher: Invalid image in %s\n", image->fileName);
    exit(1);
  }

  imageInfo = &header.imageInfo;

  /*
   * Check the CPU is sane.
   */
  if ((imageInfo->CPU & FLASH_CPU_MASK) >= FLASH_MAX_CPUS)
  {
    fprintf(stderr, "flasher: Invalid CPU number for bootvector in %s\n", image->fileName);
    exit(1);
  }

  /*
   * Boot vectors must contain just 1 section.
   */
  if (imageInfo->numSections != 1)
  {
    fprintf(stderr, "flasher: Invalid number of bootvector sections in %s (%d > 1)\n",
            image->fileName, imageInfo->numSections);
    exit(1);
  }

  printf("Placing bootvector for CPU %d (%s)\n", imageInfo->CPU & FLASH_CPU_MASK, imageInfo->description);

  /*
   * And they must fit!
   */
  if (imageInfo->sections[0].length >= FLASH_BOOT_VECTOR_SIZE)
  {
    fprintf(stderr, "flasher: Invalid size of bootvector section in %s (0x%08x > 0x%08x)\n",
            image->fileName, imageInfo->sections[0].length, FLASH_BOOT_VECTOR_SIZE);
    exit(1);
  }

  /*
   * Work out where it should go, and check the header agrees.
   */
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
  loadAddress = (unsigned int)0x7FFFFF00;
#else
  loadAddress = ((imageInfo->CPU & FLASH_CPU_MASK) * FLASH_BOOT_VECTOR_SIZE) + FLASH_BASE;
#endif

  switch (imageInfo->sections[0].type & PLACEMENT_TYPE_MASK)
  {
    case PLACEMENT_TYPE_ANYWHERE:
      break;

    case PLACEMENT_TYPE_INPLACE:
      if ((loadAddress != imageInfo->sections[0].destinationAddress) && (loadAddress != imageInfo->entryAddress))
      {
        fprintf(stderr, "flasher: Invalid bootvector in %s\n", image->fileName);
        exit(1);
      }
      break;

    default:
      fprintf(stderr, "flasher: Unsupported bootvector placement type in %s\n", image->fileName);
      exit(1);
      break;
  }

  /*
   * All looks OK, so read the code into the new boot page.
   */
  if (fread(&bootPages->bootVectors[imageInfo->CPU & FLASH_CPU_MASK], imageInfo->sections[0].length, 1, fp) != 1)
  {
    fprintf(stderr, "flasher: Failed to read from %s\n", image->fileName);
    exit(1);
  }

#if !(defined(__mb390__) || defined(__mb424__) || defined(__mb435__))
  /*
   * Place the description too (if not an STb5301).
   */
  strncpy(bootPages->bootVectorDescriptions[imageInfo->CPU & FLASH_CPU_MASK], imageInfo->description, FLASH_DESC_LEN);
#endif

  /*
   * All done, so close file.
   */
  fclose(fp);
}

/*
 * Routine to relocate an ELF image.
 */
static void processElfRelocs(unsigned char* image,
                             unsigned int   baseAddress,
                             unsigned int   architecture,
                             reloc_t*       relocs,
                             size_t         numRelocs,
                             symb_t*        symbs,
                             size_t         numSymbs)
{
  int i;
  reloc_t* reloc;
  unsigned int value = 0;
  unsigned int symbol;

  switch (architecture)
  {
    case FLASH_CPU_ARCH_LX:
    case FLASH_CPU_ARCH_SH4:
      break;

    default:
      fprintf(stderr, "flasher: Unsupported architecture (%d)\n", architecture);
      exit(1);
  }

  for (i = 0; i < numRelocs; i++)
  {
    reloc = relocs + i;

    switch (reloc->info & 0xff)
    {
      case R_SH_DIR32:
      case R_LX_32:
      case R_LX_JMP_SLOT:
        symbol = reloc->info >> 8;
        if (symbol >= numSymbs)
        {
          fprintf(stderr, "flasher: Invalid relocation symbol reference (%d)\n", symbol);
          exit(1);
        }
        value = baseAddress + symbs[symbol].value + reloc->addend;
        break;

      case R_SH_RELATIVE:
      case R_LX_REL32:
        value = baseAddress + reloc->addend;
        break;

      default:
        fprintf(stderr, "Unsupported relocation (%d)\n", reloc->info & 0xff);
        exit(1);
    }

    *(unsigned int*)(image + reloc->offset) = value;
  }
}

/*
 * Routine used by determineProgramming(), which processes a new bootstrap file.
 */
static void processBootStrap(image_t* image, bootPages_t* bootPages, int phase)
{
  FILE* fp;
  fileHeader_t header;
  imageControl_t* imageInfo;
  buffer_t* buffer;
  buffer_t* update;
  buffer_t* relocInfo = NULL;
  unsigned int bootStrapAddress;
  imageSection_t* imageSections;
  int i;

  /*
   * Open the image file.
   */
  if (!(fp = fopen(image->fileName, "rb")))
  {
    fprintf(stderr, "flasher: Failed to open %s\n", image->fileName);
    exit(1);
  }

  /*
   * Read in the header.
   */
  if (fread(&header, sizeof(header), 1, fp) != 1)
  {
    fprintf(stderr, "flasher: Failed to read header from %s\n", image->fileName);
    exit(1);
  }

  /*
   * It should have the correct magic number.
   */
  if (header.magic != IMAGE_FILE_MAGIC)
  {
    fprintf(stderr, "flasher: Invalid image in %s\n", image->fileName);
    exit(1);
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -