flashdir.c

来自「采用ST20 CPU的机顶盒的烧写程序」· C语言 代码 · 共 890 行 · 第 1/2 页

C
890
字号
 * Returns 0 if nothing present, else returns non-zero
 */
static int showBootPage(bootPages_t* bootPages)
{
  unsigned int crcBoot;
  int i;

  /*
   * Check for a valid CRC on this page first of all
   */
  crcBoot = flashCalcCRC((unsigned int*)bootPages, (sizeof(bootPages_t) - sizeof(int)) / sizeof(int));

  if (crcBoot != bootPages->crc)
  {
    printf("FLASH does not contain valid boot pages\n");
    return 0;
  }
  else
  {
    printf("\nBOOT VECTOR INFORMATION\n\n");

    printf(" CPU Description                      Boot Address\n");
    printf(" -------------------------------------------------\n");

    for (i = 0; i < FLASH_MAX_CPUS; i++)
    {
      unsigned int bootAddr;
      if (romImage)
      {
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
        bootAddr = 0x80000000 - sizeof(bootPages_t) + ((unsigned int)&bootPages->bootVectors[i] - (unsigned int)bootPages);
#else
        bootAddr = FLASH_BASE + ((unsigned int)&bootPages->bootVectors[i] - (unsigned int)bootPages);
#endif /* defined(__mb390__) || defined(__mb424__) || defined(__mb435__) */
      }
      else
      {
        void* physAddr;
        if (OS21_SUCCESS != vmem_virt_to_phys(&bootPages->bootVectors[i], &physAddr))
        {
          fprintf(stderr, "flashdir: Failed to convert bootvector %d virtual address 0x%08x to a physical address - attempting to continue using virtual address\n",
                  i, (int)&bootPages->bootVectors[i]);
          physAddr = &bootPages->bootVectors[i];
        }
        bootAddr = (unsigned int)physAddr;
      }
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
        printf("  %-2d %-32s 0x%08x\n", i, "STb5301 boot vector", bootAddr);
#else
      if (strlen(bootPages->bootVectorDescriptions[i]))
      {
        printf("  %-2d %-32s 0x%08x\n", i, bootPages->bootVectorDescriptions[i],
               bootAddr);
      }
#endif /* defined(__mb390__) || defined(__mb424__) || defined(__mb435__) */

    }

    printf("\nBOOTSTRAP INFORMATION\n\n");

    printf(" CPU Identifier                       Start      Size\n");
    printf(" ----------------------------------------------------------\n");

    for (i = 0; i < FLASH_MAX_CPUS; i++)
    {
      if (bootPages->bootStrapDescriptors[i].length)
      {
        printf("  %-2d %-32s 0x%08x 0x%08x\n", i, bootPages->bootStrapDescriptors[i].description,
               bootPages->bootStrapDescriptors[i].startAddress, bootPages->bootStrapDescriptors[i].length);

        /*
         * Record this as a used region
         */
        recordRegion(bootPages->bootStrapDescriptors[i].startAddress,
                     bootPages->bootStrapDescriptors[i].length,
                     bootPages->bootStrapDescriptors[i].description);
      }
    }
    
    printf("\nFAIL-SAFE IMAGE INFORMATION\n");
    /* Show any fail-safe application information */
    if (*(unsigned int*)(&bootPages->failsafeImageControlStructure) == 0xFFFFFFFF)
    {
      printf("\nNo fail-safe boot image.\n");
    }
    else
    {
      int i;
      int protectable = 1;
      imageControl_t* failSafeImage = (imageControl_t*)(&bootPages->failsafeImageControlStructure);
      printImageInfo(-1, failSafeImage, 1);
      
      /* Before we can say FLASH blocks can be protected, we should ensure all
       * sections for the fail-safe image are the correct side of the boundary.
       */
      for (i = 0; i < failSafeImage->numSections; i++)
      {
        if (failSafeImage->sections[i].sourceAddress
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
            < (unsigned int) bootPages->imageControlDirectoryPtr + sizeof(imageDirectoryPages_t))
#else
            > (unsigned int) bootPages->imageControlDirectoryPtr)
#endif    
          protectable = 0;
      }

      if (protectable)      
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
        printf("\nFLASH blocks at and above 0x%08x can be protected\n",
               (int) bootPages->imageControlDirectoryPtr + sizeof(imageDirectoryPages_t));
#else
        printf("\nFLASH blocks below 0x%08x can be protected\n",
               (int)bootPages->imageControlDirectoryPtr);
#endif
      else
        fprintf(stderr, "Warning: Fail-safe image has sections outside of 'protectable' FLASH blocks, so it is no longer 'fail-safe'.\n");
    }
  }
  return 1;
}

/*
 * Routine to display the image directory
 */
static void showImageDirectory(imageDirectoryPages_t* pages, unsigned long physPagesBase)
{
  imageDirectory_t dir = pages->directory;
  int printBanner = 1;
  int slot;
  unsigned int crcImage;

  /*
   * Check the CRC on the pages
   */
  crcImage = flashCalcCRC((unsigned int*)pages, (sizeof(imageDirectoryPages_t) - sizeof(int)) / sizeof(int));

  recordRegion(physPagesBase, sizeof(imageDirectoryPages_t), "Main application image control directory and structures");

  printf("\nIMAGE INFORMATION\n");
  printf("\nImage control directory is at 0x%08x.\n", (int)physPagesBase);

  if (crcImage != pages->crc)
  {
    printf("\nFLASH does not contain any images\n");
  }
  else
  {
    /*
     * Pages look good, so dump them
     */
    for (slot = 0; slot < FLASH_IMAGE_DIRECTORY_SIZE; slot++)
    {
      imageControl_t* element;
      if (romImage)
        element = (imageControl_t*)(((unsigned long)dir.entries[slot] - physPagesBase) + (unsigned long)pages);
      else
        element = (imageControl_t*)physToCachedFlashAddr((unsigned int)(dir.entries[slot]));
      
      if (dir.entries[slot] != 0)
      {
        printImageInfo(slot, element, printBanner);
        if (!fullOption)
        {
          printBanner = 0;
        }
      }
    }
  }
}

/*
 * Routine to figure out what bits of the FLASH are free.
 * These are simply the bits that are not used for anything
 * else!
 */
static void addFreeRegions(bootPages_t* bootPages, unsigned int flashSize)
{
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
  unsigned int address = (unsigned int)FLASH_START;
#else
  unsigned int address = (unsigned int)(bootPages->imageControlDirectoryPtr + sizeof(imageDirectoryPages_t));
#endif /* defined(__mb390__) || defined(__mb424__) || defined(__mb435__)*/
  region_t* ptr;

  for (ptr = regions.next; ptr != &regions; ptr = ptr->next)
  {
    if (ptr->address > address)
    {
      recordRegion(address, ptr->address - address, "FREE");
    }
    address = ptr->address + ptr->length;
  }

  if (address < flashSize + FLASH_START)
  {
    recordRegion(address, (flashSize + FLASH_START) - address, "FREE");
  }
}

/*
 * Routine to parse the command line
 */
static void processCmdLine(int argc, char* argv[])
{
  int c;

  while ((c = getopt(argc, argv, "t:m:fr:")) != EOF)
  {
    switch (c)
    {
      case 'f':
        fullOption = 1;
        break;

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

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

  if ((argc > 0) && (optind != argc))
  {
    usage("Extra characters on command line");
  }
  if (romImage && blockMapFile)
  {
    fprintf(stderr, "flashdir: A FLASH block map file can not be generated from a ROM image\n");
    exit(1);
  }
}

/*
 * Routine to show the raw layout of the FLASH
 */
static void showRegions(void)
{
  region_t* ptr;

  printf("\nFLASH LAYOUT\n\n");
  printf("  Address    Length      Usage\n");
  printf("  ----------------------------------------------------------------\n");

  for (ptr = regions.next; ptr != &regions; ptr = ptr->next)
  {
    printf("  0x%08x 0x%08x  %s\n", ptr->address, ptr->length, ptr->use);
  }
}

/*
 * Entry point
 */
int main(int argc, char* argv[])
{
  bootPages_t* bootPages;
  imageDirectoryPages_t* imageDirectoryPages;
  unsigned int flashSize = 0;
  flashDevice_t** devices = NULL;
  int i;

  /*
   * Fire up OS21
   */
  kernel_initialize(NULL);
  kernel_start();

  /*
   * Read in any options
   */
  processCmdLine(argc, argv);

  if (!romImage)
  {
    /* Generic FLASH access setup */
    init_flash_access();

#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
    bootPages = (bootPages_t*)physToCachedFlashAddr(0x80000000 - sizeof(bootPages_t));
#else
    bootPages = (bootPages_t*)physToCachedFlashAddr(FLASH_BASE);
#endif /* defined(__mb390__) || defined(__mb424__) || defined(__mb435__) */
    imageDirectoryPages = (imageDirectoryPages_t*)physToCachedFlashAddr((unsigned int)bootPages->imageControlDirectoryPtr);

    if (!target)
    {
      if ((target = flashGetTarget(DEFAULTPLATFORM)) == NULL)
      {
        usage("Unrecognised target board");
      }
    }
  }
  else
  {
    /* Read the ROM image into RAM for checking (need to cope with .bin and .hex
       files and a .bin file with an @<addr> postfix).
     */
    char* s = strrchr(romImage, '.');

    /* Allocate mem for bootPages and imageDirectoryPages */
    if (!(bootPages = (bootPages_t*)malloc(sizeof(bootPages_t))))
    {
      fprintf(stderr, "flashdir: Unable to allocate memory for internal copy of boot pages\n");
      exit(1);
    }
    if (!(imageDirectoryPages = (imageDirectoryPages_t*)malloc(sizeof(imageDirectoryPages_t))))
    {
      fprintf(stderr, "flashdir: Unable to allocate memory for internal copy of image directory pages\n");
      exit(1);
    }

    /* Use the correct reading technique (default binary, if suffix is ".hex", hex) */
    if (s && (strcasecmp(s, ".hex") == 0))
    {
      flashSize = readFromHexROM(romImage, bootPages, imageDirectoryPages);
    }
    else
    {
      flashSize = readFromBinROM(romImage, bootPages, imageDirectoryPages);
    }
  }

  printf("\nFLASHDIR V3.0\n");
  printf("Copyright (c) STMicroelectronics 2003-2007\n");

  if (!romImage)
  {
    printf("Platform: %s\n", target->name);
    /*
     * Query the FLASHES, so we know how much we've got
     */
    devices = flashIdentifyFlashes(target);
  
    if (!devices || (devices[0] == NULL))
    {
      fprintf(stderr, "flasher: Could not detect any supported FLASH parts.\n");
      return 1;
    }
  
    /*
     * Work out how much flash we've got
     */
    if (fullOption)
      printf("FLASH devices detected:\n");
    for (i = 0; devices[i]; i++)
    {
      if (fullOption)
      {
        printf("0x%08x -> 0x%08x : %s %s detected\n", devices[i]->baseAddress,
               devices[i]->baseAddress + devices[i]->bankSize - 1, devices[i]->manufacturerName, devices[i]->deviceName);
      }
      flashSize += devices[i]->bankSize;
    }
    if (fullOption)
      printf("\n");
  }
  else
  {
    printf("Layout from: %s\n", romImage);
  }
  
  if (blockMapFile)
  {
    FILE* fp;
    if (!(fp = fopen(blockMapFile, "w")))
    {
      fprintf(stderr, "flashdir: Failed to open %s for writing\n", blockMapFile);
      exit(1);
    }
    dumpBlockMap(devices, fp);
    dumpBlockMap(devices, stdout);
    return 0;
  }

  /*
   * Record the reserved region
   */
  if (!romImage)
  {
    void* physAddr;
    if (OS21_SUCCESS != vmem_virt_to_phys(bootPages, &physAddr))
    {
      fprintf(stderr, "flashdir: Failed to convert boot pages virtual address 0x%08x to a physical address - attempting to continue using virtual address\n",
              (int)bootPages);
      physAddr = bootPages;
    }
    
    recordRegion((unsigned int)physAddr, sizeof(bootPages_t), "Boot control region");
  }
  else
#if defined(__mb390__) || defined(__mb424__) || defined(__mb435__)
    recordRegion(0x80000000 - sizeof(bootPages_t), sizeof(bootPages_t), "Boot control region");
#else
    recordRegion((unsigned int)FLASH_BASE, sizeof(bootPages_t), "Boot control region");
#endif /* defined(__mb390__) || defined(__mb424__) || defined(__mb435__) */

  /*
   * Display the boot page information
   */
  if (showBootPage(bootPages))
  {
    /*
     * Dump image pages
     */
    showImageDirectory(imageDirectoryPages, (unsigned long)bootPages->imageControlDirectoryPtr);
  
    /*
     * Show free regions
     */
    addFreeRegions(bootPages, flashSize);
  
    /*
     * Dump flash region usage
     */
    showRegions();
  }
  
  /* Delete the virtual memory mappings used in accessing FLASH */
  if (!romImage)
    unmapFlash();
    
  return 0;
}

⌨️ 快捷键说明

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