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

📄 flasher.c

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

  imageInfo = &header.imageInfo;

  if ((imageInfo->CPU & FLASH_CPU_MASK) >= FLASH_MAX_CPUS &&
      !(imageInfo->CPU & FLASH_IMAGE_TYPE_MASK)
     )
  {
    fprintf(stderr, "flasher: Invalid CPU number for application in %s\n", image->fileName);
    exit(1);
  }

  if ((imageInfo->CPU & FLASH_IMAGE_TYPE_MASK) == FLASH_IMAGE_TYPE_DATA)
  {
    printf("Placing data image (%s) in image slot %d\n", imageInfo->description, image->slot);
  }
  else if ((imageInfo->CPU & FLASH_IMAGE_TYPE_MASK) == FLASH_IMAGE_TYPE_RELOC_LIB)
  {
    printf("Placing relocatable library (%s) in image slot %d\n", imageInfo->description, image->slot);
    rlImage = 1;
  }
  else
  {
    printf("Placing image for CPU %d (%s) in image slot %d",
           imageInfo->CPU & FLASH_CPU_MASK, imageInfo->description, image->slot);
    if (image->slot == FAILSAFE_SLOT)
    {
      printf(" (fail-safe image slot)");
      /* Also flag the fail-safe image as bootable */
      imageInfo->CPU |= FLASH_BOOT_FLAG;
    }
    printf("\n");
  }
  st40Image = ((imageInfo->CPU & FLASH_CPU_ARCH_MASK) == FLASH_CPU_ARCH_SH4);

  /*
   * Read in all the sections.
   * The header is defined to contain a single section (as a place holder) so
   * make things easy we rewind the file, and read in all the sections in one
   * go.
   */
  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);
  }

  if (phase == 0)
  {
    image->controlStruct = malloc(sizeof(imageControl_t) + ((imageInfo->numSections - 1) * sizeof(imageSection_t)));
    /* Copy from the file to our imageControlStruct in RAM */
    *image->controlStruct = *imageInfo;
  }
  
  /*
   * Process each section...
   */
  for (section = 0; section < imageInfo->numSections; section++)
  {
    buffer_t* buffer;
    int process_it = 0;

    image->controlStruct->sections[section].length = imageSections[section].length;
    image->controlStruct->sections[section].destinationAddress =
      (unsigned int)(imageSections[section].destinationAddress);
    image->controlStruct->sections[section].type = imageSections[section].type & SECTION_TYPE_MASK;

    switch (imageSections[section].type & PLACEMENT_TYPE_MASK)
    {
      case PLACEMENT_TYPE_NONE:
        if (phase == 1)
        {
          image->controlStruct->sections[section].sourceAddress = 0;
        }
        break;

      case PLACEMENT_TYPE_ANYWHERE:
        if (phase == 1)
        {
          image->controlStruct->sections[section].sourceAddress =
            findBestFree(imageSections[section].length, MIN_SECTION_ALIGNMENT,
                         &flashMap, image->slot == -1 ? (unsigned int) bootPages->imageControlDirectoryPtr : 0);
          process_it = 1;
        }
        break;

      case PLACEMENT_TYPE_INPLACE_BLANK:
      case PLACEMENT_TYPE_INPLACE:
        if (phase == 0)
        {
          image->controlStruct->sections[section].sourceAddress =
            (unsigned int)(imageSections[section].sourceAddress);
          process_it = 1;
        }
        break;

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

    if ((imageSections[section].type & PLACEMENT_TYPE_MASK) != PLACEMENT_TYPE_NONE)
    {
      if (process_it)
      {
        buffer = allocate(sizeof(buffer_t));

        buffer->address = image->controlStruct->sections[section].sourceAddress;
        buffer->length = image->controlStruct->sections[section].length;
        buffer->info.data = (unsigned char*)allocate(buffer->length);

        /*
         * Setup the image data, either from file or init to 0xff.
         */
        if ((imageSections[section].type & PLACEMENT_TYPE_MASK) == PLACEMENT_TYPE_INPLACE_BLANK)
        {
          memset(buffer->info.data, 0xff, buffer->length);
        }
        else
        {
          if (fread(buffer->info.data, buffer->length, 1, fp) != 1)
          {
            fprintf(stderr, "flasher: Failed to read section data from %s\n", image->fileName);
            exit(1);
          }
        }

        /*
         * Add the update to the update list.
         */
        addBuffer(buffer, &updateList);

        /*
         * Finally mark this region of FLASH as allocated.
         */
        allocBlock = allocate(sizeof(buffer_t));

        allocBlock->address = buffer->address;
        allocBlock->length = buffer->length;
        allocBlock->info.type = MEM_USED;

        updateMemMap(allocBlock, &flashMap);

        /*
         * Map LX_BOOT sections to SKIP when in FLASH, and overwrite entrypoint.
         */
        if (image->controlStruct->sections[section].type == SECTION_TYPE_LX_BOOT)
        {
          image->controlStruct->sections[section].type = SECTION_TYPE_SKIP;
          image->controlStruct->entryAddress = image->controlStruct->sections[section].sourceAddress;
        }
      }
      else
      {
        /*
         * Not processing on this pass - seek over the data.
         */
        if (fseek(fp, image->controlStruct->sections[section].length, SEEK_CUR) == -1)
        {
          fprintf(stderr, "flasher: Failed to seek over section data from %s\n", image->fileName);
          exit(1);
        }
      }
    }
  }
  
  if (phase == 1)
  {
    /*
     * Find room for dir entry, if image->slot is zero, then the whole region is
     * free, otherwise, we must abut the existing entries.
     * We use imageInfo->numSections-1 here, because a imageControl_t already
     * contains one section
     */
    entrySize = sizeof(imageControl_t) + ((imageInfo->numSections - 1) * sizeof(imageSection_t));
    if (image->slot == FAILSAFE_SLOT)
    {
      controlStruct = (imageControl_t*)&bootPages->failsafeImageControlStructure;
    }
    else
    {
      controlStruct = (imageControl_t*)findBestFree(entrySize, 1, &controlMap, 0);

      allocBlock = allocate(sizeof(buffer_t));
  
      allocBlock->address = (unsigned int)controlStruct;
      allocBlock->length = entrySize;
      allocBlock->info.type = MEM_USED;
  
      updateMemMap(allocBlock, &controlMap);
    }

    /*
     * Fill in the boot control structure, and place the sections.
     *
     * Set the pointer in the table.
     */
    if (image->slot != FAILSAFE_SLOT)
      imageDirectoryPages->directory.entries[image->slot] = controlStruct;

    /*
     * Copy the header from the file into the boot control structure.
     */
    *controlStruct = *image->controlStruct;
    {
      int secNo;
      for (secNo = 1; secNo < controlStruct->numSections; secNo++)
        controlStruct->sections[secNo] = image->controlStruct->sections[secNo];
    }
  }

  /*
   * Free off imageSections - its job is done.
   */
  free(imageSections);
}

/*
 * Routine to perform the image slot deletes given on the command line with
 * '-d'.
 */
static void processDeletes(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages)
{
  int* ptr = deleteList;
  int i;

  for (i = 0; i < slotsToDelete; i++)
  {
    printf("Deleting image in slot %d", *ptr);
    if (*ptr == FAILSAFE_SLOT)
      printf(" (fail-safe image slot)\n");
    printf("\n");
    deleteSlot(*ptr++, bootPages, imageDirectoryPages);
  }
}

/*
 * Routine to perform the make bootable requests.
 */
static void processMakeBoots(imageDirectoryPages_t* imageDirectoryPages)
{
  int i;

  for (i = 0; i < slotsToMakeBootable; i++)
  {
    makeBootable(imageDirectoryPages, bootList[i]);
  }
}

/*
 * This routine generates new boot and image pages, loads the image data to be
 * blown and creates the update descriptors describing what to do.
 */
static void determineProgramming(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages,
                                 unsigned int flashSize, flashDevice_t** devices, flashTarget_t* target)
{
#if defined(__mb376__) || defined(__espresso__)
  static unsigned char sti5528BootPage[1024] = {
    0x01, 0xD0, 0x0B, 0x40,
    0x09, 0x00, 0x09, 0x00,
    0x00, 0x04, 0x00, 0xA0
  };
#endif
  image_t* ptr;
  buffer_t* buffer;
  int phase;

  printf("Beginning analysis...\n");
  /*
   * Create the FLASH memory map, so we can place the user images. This involves
   * examining the existing state of the FLASH directories, and building a
   * picture of what is in use, and what is not.
   */
  createMemoryMap(bootPages, imageDirectoryPages, flashSize);

  /*
   * Delete any slots we were asked to.
   */
  processDeletes(bootPages, imageDirectoryPages);

  /*
   * We place sections in the following order:
   *  1) Boot vectors
   *  2) in-place sections for all images
   *  3) bootstraps (in-place and then anywhere sections)
   *  4) failsafe image anywhere sections
   *  5) remaining anywhere sections
   *
   * In processBootStrap() and processImage() calls the phase parameter is 0 to
   * deal with in-place sections, and 1 to deal with anywhere sections.
   */
  for (ptr = bootVectors.next; ptr != &bootVectors; ptr = ptr->next)
  {
    processBootVector(ptr, bootPages);
  }

  /* Place in-place sections for the failsafe and main application images */
  if (failsafeImage)
    processImage(failsafeImage, bootPages, imageDirectoryPages, 0, devices, target);
  for (ptr = images.next; ptr != &images; ptr = ptr->next)
    processImage(ptr, bootPages, imageDirectoryPages, 0, devices, target);
  
  /* Place both in-place and then anywhere sections for the bootstraps */
  for (phase = 0; phase < 2; phase++)
    for (ptr = bootStraps.next; ptr != &bootStraps; ptr = ptr->next)
      processBootStrap(ptr, bootPages, phase);
  
  /* Place failsafe image anywhere sections */
  if (failsafeImage)
    processImage(failsafeImage, bootPages, imageDirectoryPages, 1, devices, target);
  
  if (!bootPages->imageControlDirectoryPtr)
  {
    /*
     * We can now set the base address for the image directory and image
     * control structures in FLASH.
     * We must find a suitable address after (before on the STb5301) any
     * failsafe and bootstrap sections.  We then rounded off to the nearest new
     * FLASH block if the -bootsep option was specified and find the next space
     * which is large enough to contain the image directory pages.
     * We have to scan what exists in bootPages - recording what we did above is
     * not enough as we need to take into account anything already in FLASH.
     */
    unsigned int protectableWatermark =
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
      (0x80000000 - sizeof(bootPages_t));
#else
      FLASH_BASE + sizeof(bootPages_t);
#endif
    int count;
    buffer_t* buffer;
    
    /* Search bootstrap descriptors */
    for (count = 0; count < FLASH_MAX_CPUS; count++)
    {
      if (*((unsigned int*)&bootPages->bootStrapDescriptors[count]))
      {
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
        if (bootPages->bootStrapDescriptors[count].startAddress < protectableWatermark)
          protectableWatermark = bootPages->bootStrapDescriptors[count].startAddress;
#else
        if (bootPages->bootStrapDescriptors[count].startAddress +
            bootPages->bootStrapDescriptors[count].length > protectableWatermark)
          protectableWatermark = bootPages->bootStrapDescriptors[count].startAddress + 
                                 bootPages->bootStrapDescriptors[count].length;
#endif
      }
    }
    
    /* Search failsafe image sections */
    if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF)
    {
      imageControl_t* fsImg = &bootPages->failsafeImageControlStructure;
      for (count = 0; count < fsImg->numSections; count++)
      {
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
        if (fsImg->sections[count].sourceAddress < protectableWatermark)
          protectableWatermark = fsImg->sections[count].sourceAddress;
#else
        if (fsImg->sections[count].sourceAddress +
            fsImg->sections[count].length > protectableWatermark)
          protectableWatermark = fsImg->sections[count].sourceAddress + 
                                 fsImg->sections[count].length;
#endif
      }
    }
  
    /*
     * Move on to next new FLASH block if we are separating boot and main
     * application image FLASH blocks or there is a failsafe application.
     */
    if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF ||
        separateBootAndAppFlashBlocks)
    {
      int deviceIndex;
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
      protectableWatermark = flashBlockBase(devices, protectableWatermark, &deviceIndex) -
                             sizeof(imageDirectoryPages_t);
#else
      protectableWatermark = flashBlockBase(devices, protectableWatermark, &deviceIndex) +
                             flashBlockSize(devices[deviceIndex], protectableWatermark);
#endif
    }

    /* Use findBestFree to get to a space big enough (we may already be there) */
    protectableWatermark = findBestFree(sizeof(imageDirectoryPages_t),
                                        MIN_SECTION_ALIGNMENT, &flashMap,
                                        protectableWatermark);
    
    bootPages->imageControlDirectoryPtr = (unsigned int*)protectableWatermark;
      
    /* Also reserve the space in the flashMap */
    buffer = (buffer_t*)allocate(sizeof(buffer_t));
 
    buffer->address = protectableWatermark;
    buffer->length = sizeof(imageDirectoryPages_t);
    buffer->info.type = MEM_USED;
      
    updateMemMap(buffer, &flashMap);
  }

  if (*((unsigned int*) &bootPages->failsafeImageControlStructure) != 0xFFFFFFFF ||
      separateBootAndAppFlashBlocks)
  {
    /*
     * If there is a new or existing failsafe image ensure findBestFree will
     * never return an address below the main application image control
     * directory by setting the whole range as used in the flashMap.
     */
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
    forceRangeInMemMap((unsigned int) bootPages->imageControlDirectoryPtr, 
                       0x80000000 - (unsigned int)bootPages->imageControlDirectoryPtr,
#else
    forceRangeInMemMap(FLASH_BASE, ((unsigned int)bootPages->imageControlDirectoryPtr) - FLASH_BASE,
#endif
                       MEM_USED, &flashMap);
  }
  
  /* Place remaining anywhere sections */
  for (ptr = images.next; ptr != &images; ptr = ptr->next)
    processImage(ptr, bootPages, imageDirectoryPages, 1, devices, target);

  /*
   * Process any specific requests to make given slots bootable.
   */
  processMakeBoots(imageDirectoryPages);

  /*
   * Ensure at least one image per CPU is bootable.
   */
  checkBootableImages(imageDirectoryPages);

  printf("\n");

  /*
   * Prepare the image directory pages for placement in FLASH.
   * This warps the RAM pointers to be FLASH pointers.
   */
  romifyImageDir(boot

⌨️ 快捷键说明

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