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

📄 flasher.c

📁 采用ST20 CPU的机顶盒的烧写程序
💻 C
📖 第 1 页 / 共 5 页
字号:

  imageInfo = &header.imageInfo;

  /*
   * Perform some simple sanity checks.
   */
  if ((imageInfo->CPU & FLASH_CPU_MASK) >= FLASH_MAX_CPUS)
  {
    fprintf(stderr, "flasher: Invalid CPU number for bootstrap in %s\n", image->fileName);
    exit(1);
  }

  /*
   * A bootstrap should be 1 or more sections. The 1st one should be a SKIP
   * section, and any others should be relocation information. Another SKIP
   * section can be ignored.
   */
  if (imageInfo->numSections >= 1)
  {
    if ((imageInfo->sections[0].type & SECTION_TYPE_MASK) != SECTION_TYPE_SKIP)
    {
      fprintf(stderr, "flasher: Invalid bootstrap in %s\n", image->fileName);
      exit(1);
    }
    if (imageInfo->numSections > 1)
    {
      if ((imageInfo->sections[0].type & PLACEMENT_TYPE_MASK) != PLACEMENT_TYPE_ANYWHERE)
      {
        fprintf(stderr, "flasher: Invalid bootstrap in %s\n", image->fileName);
        exit(1);
      }
    }
  }
  else
  {
    fprintf(stderr, "flasher: Invalid number of bootstrap sections in %s (%d < 1)\n",
            image->fileName, imageInfo->numSections);
    exit(1);
  }

  fseek(fp, -sizeof(imageSection_t), SEEK_CUR);

  imageSections = allocate(sizeof(imageSection_t) * imageInfo->numSections);

  if (fread(imageSections, sizeof(imageSection_t) * imageInfo->numSections, 1, fp) != 1)
  {
    fprintf(stderr, "flasher: Failed to read sections from %s\n", image->fileName);
    exit(1);
  }

  for (i = 1; i < imageInfo->numSections; i++)
  {
    switch (imageSections[i].type & SECTION_TYPE_MASK)
    {
      case SECTION_TYPE_SYMBOLS:
      case SECTION_TYPE_RELOCATIONS:
        break;

      case SECTION_TYPE_SKIP:
        /* If we see another skip section, pretend it isn't there */
        imageInfo->numSections--;
        break;

      default:
        fprintf(stderr, "flasher: Invalid bootstrap in %s\n", image->fileName);
        exit(1);
    }
  }

  /*
   * Check the section we've got is appropriate for this phase of placement. If
   * not, do nothing.
   */
  if (phase == 0)
  {
    if ((imageSections[0].type & PLACEMENT_TYPE_MASK) == PLACEMENT_TYPE_ANYWHERE)
    {
      free(imageSections);
      fclose(fp);
      return;
    }
  }
  else
  {
    if ((imageSections[0].type & PLACEMENT_TYPE_MASK) != PLACEMENT_TYPE_ANYWHERE)
    {
      free(imageSections);
      fclose(fp);
      return;
    }
  }

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

  /*
   * Create a buffer to represent this update, and read in the image.
   */
  update = (buffer_t*)allocate(sizeof(buffer_t));
  update->info.data = (unsigned char*)allocate(imageSections[0].length);
  update->length = imageSections[0].length;

  if (fread(update->info.data, imageSections[0].length, 1, fp) != 1)
  {
    fprintf(stderr, "flasher: Failed to read section data from %s\n", image->fileName);
    exit(1);
  }

  /*
   * Also read in any relocation data.
   */
  if (imageInfo->numSections > 1)
  {
    relocInfo = (buffer_t*)allocate(sizeof(buffer_t) * (imageInfo->numSections - 1));
    for (i = 1; i < imageInfo->numSections; i++)
    {
      relocInfo[i - 1].info.data = (unsigned char*)allocate(imageSections[i].length);
      relocInfo[i - 1].length = imageSections[i].length;

      if (fread(relocInfo[i - 1].info.data, relocInfo[i - 1].length, 1, fp) != 1)
      {
        fprintf(stderr, "flasher: Failed to read relocations from %s\n", image->fileName);
        exit(1);
      }
    }
  }

  fclose(fp);

  /*
   * If the bootstrap was already in use, free off the memory it was using, and
   * then allocate the new lot.
   */
  if (bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].startAddress &&
      bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].length)
  {
    buffer = (buffer_t*)allocate(sizeof(buffer_t));

    buffer->address = (unsigned int)(bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].startAddress);
    buffer->length = bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].length;
    buffer->info.type = MEM_FREE;

    updateMemMap(buffer, &flashMap);
  }

  buffer = (buffer_t*)allocate(sizeof(buffer_t));

  /*
   * The section must be type INPLACE, or preferably PIC, so we can place it
   * where ever we want.
   * We align 'anywhere' blocks on MIN_SECTION_ALIGNMENT byte boundaries.
   */
  switch (imageSections[0].type & PLACEMENT_TYPE_MASK)
  {
    case PLACEMENT_TYPE_ANYWHERE:
      buffer->address = findBestFree(imageSections[0].length, MIN_SECTION_ALIGNMENT,
                                     &flashMap, (unsigned int) bootPages->imageControlDirectoryPtr);
      break;

    case PLACEMENT_TYPE_INPLACE:
      buffer->address = (unsigned int)(imageSections[0].sourceAddress);
      break;

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

  buffer->length = imageSections[0].length;
  buffer->info.type = MEM_USED;

  bootStrapAddress = buffer->address;

  updateMemMap(buffer, &flashMap);

  /*
   * Record this update request.
   */
  update->address = bootStrapAddress;
  addBuffer(update, &updateList);

  /*
   * Process any relocations we need to do also.
   */
  if (relocInfo)
  {
    buffer_t* relocs = NULL;
    buffer_t* symbs = NULL;

    for (i = 1; i < imageInfo->numSections; i++)
    {
      unsigned int type = imageSections[i].type & SECTION_TYPE_MASK;

      if (type == SECTION_TYPE_SYMBOLS)
      {
        symbs = &relocInfo[i - 1];
      }
      else if (type == SECTION_TYPE_RELOCATIONS)
      {
        relocs = &relocInfo[i - 1];
      }
    }

    if (symbs && relocs)
      processElfRelocs(update->info.data,
                       bootStrapAddress,
                       imageInfo->CPU & FLASH_CPU_ARCH_MASK,
                       (reloc_t*)relocs->info.data,
                       relocs->length / sizeof(reloc_t),
                       (symb_t*)(symbs ? symbs->info.data : NULL),
                       (symbs ? symbs->length : 0) / sizeof(symb_t));
  }

  /*
   * Update the boot descriptor for this CPU.
   */
  bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].startAddress = bootStrapAddress;
  bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].length = imageSections[0].length;

  strncpy(bootPages->bootStrapDescriptors[imageInfo->CPU & FLASH_CPU_MASK].description,
          imageInfo->description, FLASH_DESC_LEN);

  free(imageSections);
  free(relocInfo);
}

/*
 * Routine used to delete a slot from the image directory.
 * It frees up the memory in the FLASH that the image there was using.
 */
static void deleteSlot(int slot, bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages)
{
  imageControl_t* entry;
  imageSection_t* sections;
  buffer_t* buffer;
  int i;

  if (slot != FAILSAFE_SLOT)
  {
    /*
     * We've been asked to delete this slot - if its already free, we're done.
     */
    if (!imageDirectoryPages->directory.entries[slot])
    {
      return;
    }
    
    entry = imageDirectoryPages->directory.entries[slot];
    sections = entry->sections;
  
    /*
     * This slot is now free.
     */
    imageDirectoryPages->directory.entries[slot] = 0;

    /*
     * Free off the sections used by this image.
     */
    for (i = 0; i < entry->numSections; i++)
    {
      if (sections[i].type != SECTION_TYPE_ZERO)
      {
        buffer = (buffer_t*)allocate(sizeof(buffer_t));
  
        buffer->address = (unsigned int)(sections[i].sourceAddress);
        buffer->length = sections[i].length;
        buffer->info.type = MEM_FREE;
  
        updateMemMap(buffer, &flashMap);
      }
    }
  
    /*
     * Free off the control info too.
     */
    buffer = (buffer_t*)allocate(sizeof(buffer_t));
  
    buffer->address = (unsigned int)&entry;
    buffer->length = sizeof(imageControl_t) + (entry->numSections - 1) * sizeof(imageSection_t);
    buffer->info.type = MEM_FREE;
  
    updateMemMap(buffer, &controlMap);
  }
  else
  {
    /*
     * Deleting the failsafe image slot.
     */
    entry = &bootPages->failsafeImageControlStructure;
    sections = entry->sections;
    
    /*
     * This slot is now free.
     */
    *((unsigned int*)&bootPages->failsafeImageControlStructure) = 0xFFFFFFFF;
  }
}

/*
 * Routine to scan the image directory, and ensure that at least one image per
 * CPU is marked as the boot image. If non is marked, we pick the first one we
 * found.
 */
static void checkBootableImages(imageDirectoryPages_t* imageDirectoryPages)
{
  unsigned int cpu;
  imageControl_t* controlStruct;
  int i;
  int firstFound;
  int bootSlot;

  /*
   * For each possible CPU, scan the table looking for images.
   * If we find no boot images, and there is at least one image present for that
   * CPU, make that first image found the boot image for it.
   */
  for (cpu = 0; cpu < FLASH_MAX_CPUS; cpu++)
  {
    firstFound = -1;
    bootSlot = -1;

    for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
    {
      controlStruct = imageDirectoryPages->directory.entries[i];

      if (controlStruct && ((controlStruct->CPU & FLASH_CPU_MASK) == cpu) &&
          !(controlStruct->CPU & FLASH_IMAGE_TYPE_MASK)
         )
      {
        if (firstFound == -1)
        {
          firstFound = i;
        }

        if (controlStruct->CPU & FLASH_BOOT_FLAG)
        {
          if (bootSlot == -1)
          {
            bootSlot = i;
          }
          else
          {
            fprintf(stderr, "flasher: Internal error: > 1 boot slot for cpu %d found\n", cpu);
            exit(1);
          }
        }
      }
    }

    /*
     * If no boot slot found, pick the first one
     */
    if ((bootSlot == -1) && (firstFound != -1))
    {
      controlStruct = imageDirectoryPages->directory.entries[firstFound];
      controlStruct->CPU |= FLASH_BOOT_FLAG;

      printf("Set image '%s' in slot %d to be a boot image\n", controlStruct->description, firstFound);
    }
  }
}

/*
 * Routine used by determineProgramming() to process a new user image.
 */
static void processImage(image_t* image, bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages,
                         int phase, flashDevice_t** devices, flashTarget_t* target)
{
  int section;
  FILE* fp;
  fileHeader_t header;
  imageControl_t* imageInfo;
  imageControl_t* controlStruct;
  imageSection_t* imageSections;
  size_t entrySize;
  buffer_t* allocBlock;
  int rlImage = 0;
  int st40Image = 0;

  /*
   * The user can specify a slot to use, or ask us to pick one.
   * Do this on the initial phase only.
   */
  if (phase == 0)
  {
    if (image->slot == ANY_SLOT)
    {
      int slot;
      /*
       * Find a spare slot.
       */
      for (slot = 0; slot < FLASH_IMAGE_DIRECTORY_SIZE; slot++)
      {
        if (imageDirectoryPages->directory.entries[slot] == NULL)
        {
          break;
        }
      }

      if (slot == FLASH_IMAGE_DIRECTORY_SIZE)
      {
        fprintf(stderr, "flasher: No spare image slots\n");
        exit(1);
      }
      image->slot = slot;
      /* We just make sure it's non-zero for now - the correct address will be
       * filled in later.
       */
      imageDirectoryPages->directory.entries[slot] = (imageControl_t*)&slot;
    }
    else
    {
      /*
       * Free up the FLASH used by the image there already
       */
      deleteSlot(image->slot, bootPages, imageDirectoryPages);
    }
  }

  /*
   * 'image->slot' is the one we'll use, so we need to find:
   *  - room for the boot control structure in the image directory
   *  - room for the image itself in the rest of the FLASH
   *
   * Open up 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);
  }

  /*
   * Check it is sane.
   */
  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 + -