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

📄 flasher.c

📁 采用ST20 CPU的机顶盒的烧写程序
💻 C
📖 第 1 页 / 共 5 页
字号:
           * Reduce the size of the list buffer, and slide it up.
           * Then insert the new buffer before it.
           */
          ptr->address += buffer->length;
          ptr->length -= buffer->length;

          insertBefore(buffer, ptr);
          break;
        }
      }
      else if ((ptr->address + ptr->length) == (buffer->address + buffer->length))
      {
        /*
         * The end addresses match, so we need to shrink the list buffer, and
         * insert the new buffer after it.
         */
        ptr->length -= buffer->length;

        insertBefore(buffer, ptr->next);
        break;
      }
      else
      {
        /*
         * The new buffer is in the middle of the list buffer.
         * We need to shrink the list buffer, then insert the new buffer after
         * it, and finally create another new buffer to go at the very end to
         * account for the residue of the original list buffer.
         */
        buffer_t* newBuffer = (buffer_t*)allocate(sizeof(buffer_t));

        newBuffer->address = buffer->address + buffer->length;
        newBuffer->length = (ptr->address + ptr->length) - newBuffer->address;
        newBuffer->info.type = ptr->info.type;

        ptr->length = (buffer->address - ptr->address);

        insertBefore(buffer, ptr->next);
        insertBefore(newBuffer, buffer->next);
        break;
      }
    }
    else if ((ptr->address > buffer->address) && ((ptr->address + ptr->length) >= buffer->address))
    {
      fprintf(stderr, "flasher: Memory @ 0x%08x cannot be %s\n", buffer->address,
              otherType == MEM_FREE ? "allocated" : "freed");
      exit(1);
    }
  }
  /* Coalesce adjacent regions of same type */
  coalesceMemMap(memRoot);
}

/*
 * Routine to find the best free block for this request.
 * Best is defined as the smallest which can satisfy.
 * The alignment parameter specifies on what boundary the memory must start
 * (e.g. 64 == on a 64 byte boundary).
 * stopAtIfMatch forces the search to finish early if a match has been found by
 * the address given (ignored if 0).
 */
static unsigned int findBestFree(unsigned int length, unsigned int alignment, buffer_t* memRoot, unsigned int stopAtIfMatch)
{
  buffer_t* best = NULL;
  unsigned int bestDiff = 0;
  buffer_t* ptr;

#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
  for (ptr = memRoot->prev; ptr != memRoot; ptr = ptr->prev)
  {
    if (ptr->info.type == MEM_FREE && ptr->length >= length)
    {
      unsigned int diff = (ptr->length - length) - ((ptr->address + ptr->length - length) & (alignment - 1));
      if (stopAtIfMatch && ptr->address + diff <= stopAtIfMatch && best)
        break;
      /* If an aligned version of stopAtIfMatch is within this free region and
         is lower than what diff would currently give us, use it instead.
       */
      if (stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) < ptr->address + diff &&
          stopAtIfMatch > ptr->address)
        diff = (stopAtIfMatch & ~(alignment - 1)) - ptr->address;
#else /* Not an STb5301 */
  for (ptr = memRoot->next; ptr != memRoot; ptr = ptr->next)
  {
    if (ptr->info.type == MEM_FREE && ptr->length >= length)
    {
      unsigned int diff = (alignment - (ptr->address & (alignment - 1))) & (alignment - 1);
      if (stopAtIfMatch && ptr->address + diff >= stopAtIfMatch && best)
        break;
      /* If an aligned version of stopAtIfMatch is within this free region and
         is higher than what diff would currently give us, use it instead.
       */
      if (stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) > ptr->address + diff &&
          stopAtIfMatch && (stopAtIfMatch & ~(alignment - 1)) + length < ptr->address + ptr->length)
        diff = (stopAtIfMatch & ~(alignment - 1)) - ptr->address;
#endif
      if (ptr->length - diff >= length)
      {
        if (best == NULL)
        {
          best = ptr;
          bestDiff = diff;
        }
        else
        {
          if (ptr->length < best->length)
          {
            best = ptr;
            bestDiff = diff;
          }
        }
      }
    }
  }

  if (best == NULL)
  {
    fprintf(stderr, "flasher: Insufficient space in FLASH\n");
    exit(1);
  }

  return best->address + bestDiff;
}

/*
 * Routine to initialise the FLASH memory map. This is used when placing user
 * images into the FLASH.
 */
static void createMemoryMap(bootPages_t* bootPages, imageDirectoryPages_t* imageDirectoryPages, unsigned int flashSize)
{
  buffer_t* buffer;
  int i;

  /*
   * Initial state - boot pages & image dir pages (if valid) allocated, all the
   * rest is free.
   */
  buffer = (buffer_t*)allocate(sizeof(buffer_t));

  buffer->address = FLASH_START;
  buffer->length = flashSize;
  buffer->info.type = MEM_FREE;

  addBuffer(buffer, &flashMap);

  /*
   * Factor in the FLASH allocated to bootstrap sections.
   */
  for (i = 0; i < FLASH_MAX_CPUS; i++)
  {
    bootStrapDescriptor_t* desc;
    
    desc = &bootPages->bootStrapDescriptors[i];
    
    if (desc->startAddress && desc->length)
    {
      buffer = (buffer_t*)allocate(sizeof(buffer_t));
      
      buffer->address = (unsigned int)desc->startAddress;
      buffer->length = desc->length;
      buffer->info.type = MEM_USED;
      
      updateMemMap(buffer, &flashMap);
    }
  }

  /*
   * Set the bootPages as used in the flash map.
   */
  buffer = (buffer_t*)allocate(sizeof(buffer_t));

#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
  buffer->address = 0x80000000 - sizeof(bootPages_t);
#else
  buffer->address = FLASH_BASE;
#endif
  buffer->length = sizeof(bootPages_t);
  buffer->info.type = MEM_USED;
  
  updateMemMap(buffer, &flashMap);

  /* 
   * If we have an image directory pointer in the bootPages, use it to set the
   * image directory and control space as used in the flash map.
   */
  if (bootPages->imageControlDirectoryPtr)
  {
    buffer = (buffer_t*)allocate(sizeof(buffer_t));
  
    buffer->address = (unsigned int)bootPages->imageControlDirectoryPtr;
    buffer->length = sizeof(imageDirectoryPages_t);
    buffer->info.type = MEM_USED;
    
    updateMemMap(buffer, &flashMap);
  }

  /*
   * Create a free region in the control map for image control structures.
   */
  buffer = (buffer_t*)allocate(sizeof(buffer_t));
  buffer->address = (unsigned int)&imageDirectoryPages->imageControlSpace;
  buffer->length = sizeof(imageDirectoryPages->imageControlSpace);
  buffer->info.type = MEM_FREE;

  addBuffer(buffer, &controlMap);

  /*
   * Factor in the FLASH allocated for user images.
   * Don't forget to do any fail-safe image that might be in place (-1).
   */
  for (i = -1; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
  {
    imageControl_t* entry;
    if (i >= 0)
      entry = imageDirectoryPages->directory.entries[i];
    else
      entry = &bootPages->failsafeImageControlStructure;

    if ((i == -1 && *((unsigned int*)&bootPages->failsafeImageControlStructure) != 0xFFFFFFFF) ||
        (i != -1 && entry))
    {
      imageSection_t* sections = entry->sections;
      buffer_t* buffer;
      int j;

      for (j = 0; j < entry->numSections; j++)
      {
        if (sections[j].type != SECTION_TYPE_ZERO)
        {
          buffer = (buffer_t*)allocate(sizeof(buffer_t));

          buffer->address = sections[j].sourceAddress;
          buffer->length = sections[j].length;
          buffer->info.type = MEM_USED;

          updateMemMap(buffer, &flashMap);
        }
      }

      if (i >= 0)
      {
        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_USED;

        updateMemMap(buffer, &controlMap);
      }
    }
  }
}


/*
 * Routine to create a RAM version of the image directory, based on the version
 * found in FLASH. The pointers from the FLASH version are warped into RAM
 * pointers.
 */
static void makeNewImageDir(bootPages_t* bootPages, imageDirectoryPages_t* newPages, imageDirectoryPages_t* romPages)
{
  int i;

  *newPages = *romPages;

  for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
  {
    imageControl_t* entry;

    entry = (imageControl_t*)newPages->directory.entries[i];

    if (entry)
    {
      newPages->directory.entries[i] =
        (imageControl_t*)(((unsigned int)entry - (unsigned int)bootPages->imageControlDirectoryPtr) +
                          (unsigned int)newPages);
    }
  }
}

/*
 * Routine to morph a RAM based image directory into a FLASH one (we morph the
 * pointers in the image dir to be FLASH pointers).
 */
static void romifyImageDir(bootPages_t* bootPages, imageDirectoryPages_t* newPages)
{
  int i;

  for (i = 0; i < FLASH_IMAGE_DIRECTORY_SIZE; i++)
  {
    imageControl_t* entry;

    entry = newPages->directory.entries[i];

    if (entry)
    {
      newPages->directory.entries[i] =
        (imageControl_t*)((unsigned int)entry - (unsigned int)newPages + 
                          (unsigned int)bootPages->imageControlDirectoryPtr);
    }
  }
}

/*
 * Routine to report command usage and abort.
 */
static void usage(const char* msg)
{
  fprintf(stderr, "flasher: %s\n"
      "Usage: flasher [-t <target board>]\n"
      "               [-p <binary or hex image>[@<binary_base_address>]] |\n"
      "               [-r <binary image>] |\n"
      "               [[-v <bootvector image> [-v...]]\n"
      "                [-s <bootstrap image> [-s...]]\n"
      "                [-fs <fail-safe image>]\n"
      "                [-i <application image>[@<slot>] [-i...]]\n"
      "                [-d <slot> [-d ...]]\n"
      "                [-b <slot>]\n"
      "                [-bootsep]]\n"
      "               [-f <option file>]\n"
      "               [-e]\n\n"
      "<slot> must be in the range 0..63\n\n"
      "-v <imgfile> : install image as a CPU boot vector\n"
      "-s <imgfile> : install image as a CPU boot strap\n"
      "-fs <imgfile>: install image as the fail-safe image\n"
      "-i <imgfile> : install image as an application image\n"
      "-d <slot>    : delete the image in slot\n"
      "-b <slot>    : make the image in slot a boot image\n"
      "-bootsep     : separate FLASH blocks containing boot code and application code so they\n"
      "               can be protected\n"
      "-p <binfile> : program with raw binary image (or ST20-style hex file if .hex extension)\n"
      "-r <binfile> : dump all FLASH to binary image\n"
      "-f <optfile> : read options from file\n"
      "-e           : erase the FLASH\n"
      "-t <board>   : override default target board ("DEFAULTPLATFORM")\n"
      "               %s\n",
      msg, flashGetTargetNames());

  exit(1);
}

/*
 * Routine to make the given slot the boot slot for that CPU.
 * No other slot for that CPU will be marked as bootable.
 */
static void makeBootable(imageDirectoryPages_t* imageDirectoryPages, int slot)
{
  unsigned int cpu;
  imageControl_t* controlStruct;
  int i;

  controlStruct = imageDirectoryPages->directory.entries[slot];

  if (!controlStruct)
  {
    fprintf(stderr, "flasher: Slot %d is empty\n", slot);
    exit(1);
  }

  cpu = controlStruct->CPU & FLASH_CPU_MASK;
  controlStruct->CPU |= FLASH_BOOT_FLAG;

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

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

      if (controlStruct && ((controlStruct->CPU & FLASH_CPU_MASK) == cpu))
      {
        controlStruct->CPU &= (~FLASH_BOOT_FLAG);
      }
    }
  }
}

#ifndef SFXIMAGENAME
/*
 * Routine used when parsing the command line to extract an address.
 */
static int getAddress(char* ptr)
{
  unsigned int addr;
  char* endp;

  addr = strtoul(ptr, &endp, 0);

  if (endp == ptr)
  {
    usage("Failed to parse address");
  }

  return addr;
}

/*
 * Routine used when parsing the command line to extract a slot number.
 */
static int getSlot(char* ptr)
{
  int slot;
  char* endp;

  slot = strtol(ptr, &endp, 10);

  if (endp == ptr)
  {
    usage("Failed to parse slot number");
  }

  if ((slot < -1) || (slot >= FLASH_IMAGE_DIRECTORY_SIZE))
  {
    usage("Invalid slot number specified");
  }

  return slot;
}

/*
 * Read command line arguments from file.
 */
static char** inputOptionFile(const char* fileName, int* argc)
{
  FILE* fp;
  size_t fileSize;
  char* s, *buffer;
  char** argv = NULL;
  *argc = 0;

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

  /*
   * Allocate enough space for entire file.
   */
  fseek(fp, 0, SEEK_END); /* End of file */
  fileSize = ftell(fp);
  fseek(fp, 0, SEEK_SET); /* Beginning of file */
  buffer = allocate(fileSize + 1);

  /*

⌨️ 快捷键说明

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