bdkinfo.c

来自「M-System DOC(Disk on a Chip) Flash芯片的诊断工」· C语言 代码 · 共 396 行

C
396
字号
#include "bdkinfo.h"
#include "saftl.h"
#include "docbdk.h"

#define MAX_NUM_OF_SUB_PARTITIONS 20
#define MAX_NUM_OF_BINAYR_PARTITIONS (FL_MAX_TL_PARTITIONS-1)

char  subs[MAX_NUM_OF_SUB_PARTITIONS * MAX_NUM_OF_BINAYR_PARTITIONS * 4];

#ifndef FL_MALLOC
	EXDWORD     BadBlockTable_area[0x500];
#endif

FLStatus DINFO_BDK(EXBYTE handle)
{
  FLStatus          Status;
  IOreq             ioreq;
  EXWORD            j,part_cnt;
  EXBYTE            BDK_END_SIGN[4];
  BDKStruct         bdkStruct;
  EXWORD            noOfBinaryOnMedia;
  EXWORD            noOfSubs;
  EXDWORD           noOfBads;
  FLExtendedDiskInfo info;

  DinfoPrint( EX_TEXT("\n BDK (binary) INFO.\n") );
  ExPrintLine( 20 );

  ExMemSet( BDK_END_SIGN, 0xff, BDK_SIGNATURE_NAME );

  /************************************************/
  /* Find the number of Binary partition on media */
  /************************************************/

  ioreq.irHandle          = handle;
  bdkStruct.signOffset    = 8;
  bdkStruct.startingBlock = 0;
  ioreq.irData            =  &bdkStruct;
  ExMemCpy(bdkStruct.oldSign,"BIPO",4);
  Status = DINFO_bdkPartitionInfo( &ioreq );

  switch(Status)
  {
     case flOK:
     case flNoSpaceInVolume:
     case flHWProtection:
        noOfBinaryOnMedia = bdkStruct.flags;
        if( noOfBinaryOnMedia == 0 )
        {
           DinfoPrint( EX_TEXT("   There are no Binary Partitions on the media\n") );
           return flOK;
        }
        break;

     case flBadFormat:
        DinfoPrint( ("The BDK information can't be display, the DiskOnChip is probably unformated.\n" ) );
        return Status;

     case flBadDriveHandle:
        DinfoPrint( EX_TEXT("   There are no binary partitions on the media\n"));
        return flOK;

     default:
        DinfoPrint( EX_TEXT("   Failed looking for the binary partitions (with status %s)\n"),TranslateFLStatus(Status) );
        return Status;
  }

  if (noOfBinaryOnMedia == 1)
     DinfoPrint( EX_TEXT("There is %d binary partition on the Media.\n\n"),noOfBinaryOnMedia );
  else
     DinfoPrint( EX_TEXT("There are %d binary partitions on the Media.\n\n"),noOfBinaryOnMedia );


  /************************************************/
  /* Display information on all binary partitions */
  /************************************************/

  for( part_cnt = 0 ; part_cnt < noOfBinaryOnMedia ; part_cnt++ )
  {
    DinfoPrint( EX_TEXT("BDK Partition %d :\n"),part_cnt );

		info.dwStructSize = sizeof(info);
		ioreq.irData      = &info;
		ioreq.irLength    = FL_ALL_FLOORS;
    ioreq.irHandle    = handle;
		ioreq.irCount     = part_cnt;
    ioreq.irFlags     = FL_BDK_PARTITION;
    Status = flGetExtendedDiskInfo( &ioreq );
    if( Status != flOK )
    {
       DinfoPrint( EX_TEXT("   Failed Getting Extended Partition information (with status %s)\n"),TranslateFLStatus(Status) );
       return Status;
    }

		/* No need to print Quick mount info */
    /* DinfoPrint( EX_TEXT("   Quick mount first unit  :  %ld\n"),info.dwFirstQuickMountUnit ); */

    DinfoPrint( EX_TEXT("   Usable units          :  %ld\n"),info.dwVirtualUnits );
    DinfoPrint( EX_TEXT("   First unit            :  %ld\n"),info.dwFirstUnit );
    DinfoPrint( EX_TEXT("   Last unit             :  %ld\n"),info.dwLastUnit );
    if( Option.Extraflag )
    {
       DinfoPrint( EX_TEXT("   TL unit size          :  %ld\n"),info.dwTLUnitSize);
       DinfoPrint( EX_TEXT("   Spare units           :  %ld\n"),info.dwSpareUnits );
       DinfoPrint( EX_TEXT("   Transfer units        :  %ld\n"),info.dwTransferUnits );
    }

    /* Parse the partition flags and print them */
		if (info.dwPartitionFlags & SAFTL_BINARY)
       DinfoPrint( EX_TEXT("   Partition flags       :  BINARY \n") );
    if((info.dwPartitionFlags & SAFTL_REL_PARTITION) &&
       ((info.dwPartitionFlags & SAFTL_FAST_PARTITION) == 0) &&
       ((info.dwPartitionFlags & SAFTL_ADVANCED_MATCHING) == 0) &&
        (info.dwPartitionFlags & SAFTL_NO_MATCHING))
            DinfoPrint( EX_TEXT("   Partition flags       :  SPL PARTITION \n") );

    if( Option.Extraflag )
    {
   		if (info.dwPartitionFlags & SAFTL_ADVANCED_MATCHING)
               DinfoPrint( EX_TEXT("   Partition flags       :  ADVANCED MATCHING \n") );
   		if (info.dwPartitionFlags & SAFTL_REL_PARTITION)
               DinfoPrint( EX_TEXT("   Partition flags       :  TYPE A PARTITION \n") );
   		if (info.dwPartitionFlags & SAFTL_FAST_PARTITION)
               DinfoPrint( EX_TEXT("   Partition flags       :  TYPE B PARTITION \n") );
   		if (info.dwPartitionFlags & SAFTL_NO_MATCHING)
               DinfoPrint( EX_TEXT("   Partition flags       :  TYPE C PARTITION \n") );
    }

/*
		if (info.dwPartitionFlags & SAFTL_RUGGEDIZED)
       DinfoPrint( EX_TEXT("   Partition flags       :  RUGGEDIZED \n") );
		if (info.dwPartitionFlags & SAFTL_BDTL)
       DinfoPrint( EX_TEXT("   Partition flags       :  BDTL \n") );
		if (info.dwPartitionFlags & SAFTL_LAST)
       DinfoPrint( EX_TEXT("   Partition flags       :  LAST \n") );
  	if (info.dwPartitionFlags & SAFTL_QUICK_MOUNT)
       DinfoPrint( EX_TEXT("   Partition flags       :  QUICK MOUNT \n") );
*/

    /*******************************/
    /* Print the protection Status */
    /*******************************/

    DinfoPrint( EX_TEXT("   Protection Status     :  "));
    ioreq.irHandle	 = handle | (part_cnt<<4) ;
    Status = DINFO_bdkIdentifyProtection(&ioreq);
    switch(Status)
    {
       case flOK:
          PrintProtectionType((EXWORD)ioreq.irFlags);
          break;

       case flNotProtected:
       case flFeatureNotSupported:
          DinfoPrint( EX_TEXT("Not Protected\n"));
          Status = flOK;
          break;

       default:
          DinfoPrint( EX_TEXT("Failed getting protection information (with status %s)\n"),TranslateFLStatus(Status) );
          return Status;
    }

    /*********************************************/
    /* Display information on the sub partitions */
    /*********************************************/

    if((ioreq.irFlags & KEY_INSERTED         ) ||   /* Key inserted */
       ((ioreq.irFlags & READ_PROTECTED) == 0)    ) /* Not read protected */
    {
       noOfSubs = getNoOfSubs( handle, part_cnt , &noOfBads);
	   DinfoPrint( EX_TEXT("\n   No of sub partitions : %d\n\n"), noOfSubs );

       for( j = 0 ; j < noOfSubs ; j++ )
       {
         ioreq.irHandle          = handle | ( part_cnt<<4 );
         bdkStruct.signOffset    = 8;
         bdkStruct.startingBlock = 0;
         ioreq.irData            =  &bdkStruct;
         ExMemCpy( bdkStruct.oldSign, &subs[j*4], 4 );

         DinfoPrint( EX_TEXT("   Information of sub partition number %d:\n"), j );

         Status = DINFO_bdkPartitionInfo( &ioreq );
         if( Status == flOK )
         {
           PrintSubPartitionInformation();
         }
         else
         {
           DinfoPrint( EX_TEXT("   Failed analizing (with status %s)\n\n"),TranslateFLStatus(Status) );
         }
       } /* End loop over binary sub-partitions */
    }
    else /* Read protected partiton */
    {
       DinfoPrint( EX_TEXT("   Skip Read protected partition\r\n\n" ));
    } /* End if - not read protected partition */
  } /* End loop over binary partitions */

  return flOK;
}




/*---------------------------------------------------------------------------------*/
EXWORD getNoOfSubs( EXBYTE handle, EXWORD wPartitionNo, EXDWORD* noOfBads )
{
  EXWORD           retValue = 0;
  EXWORD           lastSub = 0;
  IOreq            ioreq;
  FLExtendedDiskInfo info;
  FLStatus          Status;
  EXDWORD           bdkStartAddress;
  EXDWORD           bdkEndAddress;
  EXBYTE            extraBuf[16];
  EXBYTE            i;
  EXBYTE            EMPTY[4] = { 0xff,0xff,0xff,0xff };
  EXDWORD           *pBadBlockTable;
/*  EXDWORD           NoOfBadUnits; */
  EXWORD            bbtSize;
  EXWORD            bbtPtr = 0;
  EXDWORD           floor_size,floor_addr=0;
  int               floor;

 
  for( i = 0 ; i < MAX_NUM_OF_SUB_PARTITIONS ; i++ )
	ExMemSet( &subs[i*4], 0xff, 4 );

  /* GET THE BBT */
	ioreq.irHandle  = handle;
  bbtSize = 0x500;

#ifdef FL_MALLOC
  pBadBlockTable = ( EXDWORD* )ExMemAlloc( bbtSize );
#else
  pBadBlockTable = BadBlockTable_area;
#endif

  ExMemSet( pBadBlockTable, 0x00, bbtSize );
  ioreq.irData = pBadBlockTable;
  Status = DINFO_flReadBBT( &ioreq , DO_NOT_PRINT_MSG );
  /* num_of_bad_blocks = ioreq.irFlags; */

  if(STATUS_ERROR)
		return 0;


  ioreq.irHandle = handle;
  ioreq.irData = &info;
  ioreq.irLength = FL_ALL_FLOORS;
  ioreq.irCount = wPartitionNo;
  ioreq.irFlags = FL_BDK_PARTITION;
  info.dwStructSize = sizeof(info);
  Status = flGetExtendedDiskInfo( &ioreq );
  if( Status != flOK )
    return 0;



  /* bdkStartAddress = info.dwFirstUnit * info.dwUnitSize; */
  bdkStartAddress = info.dwFirstUnit * info.dwUnitSize ;
  bdkEndAddress = info.dwLastUnit * info.dwUnitSize;
  (*noOfBads) = 0;

  floor = 0;
  floor_size = info.dwUnitsInFirstFloor * info.dwUnitSize;

  for( ; bdkStartAddress <= bdkEndAddress ; bdkStartAddress += info.dwUnitSize)
  {
    /* if we pass floor boundary, call flGetExtendedDiskInfo so we will have some */
    /* fields refreshed                                                           */
    if ((bdkStartAddress) && (bdkStartAddress % floor_size) == 0)
    {
       floor ++;
       floor_addr = info.dwUnitsInFirstFloor * info.dwUnitSize * (EXDWORD)floor;
       ioreq.irHandle = handle;
       ioreq.irData   = &info;
       ioreq.irLength = floor;
       ioreq.irCount  = wPartitionNo;
       ioreq.irFlags  = FL_BDK_PARTITION;
       info.dwStructSize = sizeof(info);
       Status = flGetExtendedDiskInfo( &ioreq );
       if( Status != flOK )
         return 0;
    }

    /* if first entry is 0, skip it */
    if (pBadBlockTable[bbtPtr] == 0)
        bbtPtr++;
    /* increament bbtPtr so it will point to the right entry */
    while (( bdkStartAddress > pBadBlockTable[bbtPtr]) &&
           ( pBadBlockTable[bbtPtr] != 0 ))
    {
      bbtPtr++;
    }

    /* 5 first units are reported as bad units */
    if( bdkStartAddress == pBadBlockTable[bbtPtr] )
    {
      (*noOfBads)++;
      bbtPtr++;
      continue;
    }

    /* pass over the media header */
    if ((floor_addr <= bdkStartAddress) &&
        (bdkStartAddress < (info.wHeaderLocation+info.bHeaderUnits)*info.dwUnitSize ))
       continue;


     curFlash->args.opFlags     = MTD_EXTRA ;
     curFlash->args.startSector = bdkStartAddress >> FL_SECTOR_SIZE_BITS ;
     curFlash->args.noOfSectors = 1;
     curFlash->args.extraBuf    = extraBuf;
     Status = curFlash->flashRead(curFlash   /*vols[wPartitionNo].flash*/);
     if (Status != flOK)
        DinfoPrint( EX_TEXT("\t Read Error. \n"));

    /* we use only 95% from the media and those last 5% are marked with */
    /* "ff"s so do'nt use them */
    if( ( ExMemCmp( extraBuf, &subs[lastSub*4], 4 ) != 0 ) && ( ExMemCmp( extraBuf, EMPTY, 4 ) != 0 ) )
    {
      /* NEW SUB PARTITION WAS FOUND */
      ExMemCpy( &subs[retValue*4], extraBuf, 4 );
      retValue++;
      lastSub = retValue - 1;
    }

  }

#ifdef FL_MALLOC
  if( pBadBlockTable )
    ExMemFree( pBadBlockTable ); 
#endif

  return retValue;
}




/*---------------------------------------------------------------------------------*/
void PrintBinaryPartitionInformation( EXDWORD noOfBads )
{
  DinfoPrint( EX_TEXT("      Start block          : %ld\n"), flBdkVol->startPartitionBlock );
  DinfoPrint( EX_TEXT("      End block            : %ld\n"), flBdkVol->endPartitionBlock );
  DinfoPrint( EX_TEXT("      No of Units (gross)  : %ld\n"),flBdkVol->endPartitionBlock-flBdkVol->startPartitionBlock+1 );
  DinfoPrint( EX_TEXT("      Actual no of units   : %ld\n"),flBdkVol->endPartitionBlock-flBdkVol->startPartitionBlock+1 - noOfBads );
  DinfoPrint( EX_TEXT("      Total Size           : %ld bytes (%.2f MB)\n"), flBdkVol->bootImageSize, flBdkVol->bootImageSize/(float)EXMBYTE);

#ifdef HW_PROTECTION
  DinfoPrint( EX_TEXT("      Protection Type      : "));
  if( flBdkVol->protectionType != 0 )
  {
    PrintProtectionType( flBdkVol->protectionType );
    DinfoPrint( EX_TEXT("\n"));
  }
  else
    DinfoPrint( EX_TEXT("Not Protected\n"));
#endif  /* HW_PROTECTION */

}



/*---------------------------------------------------------------------------------*/
void PrintSubPartitionInformation()
{
  EXBYTE j;

  flBdkVol->signBuffer[5] = '\0';

  if( ExMemCmp( SIGN_SPL, flBdkVol->signBuffer, 4 ) == 0 )
    DinfoPrint( EX_TEXT("      Signature            : SPL Signature ") );
  else
    DinfoPrint( EX_TEXT("      Signature            : %s "),flBdkVol->signBuffer );

  /* SIGNATURE IN HEX  */
  DinfoPrint( "( " );
  for( j = 0 ; j < 4 ; j++ )
    DinfoPrint( "0x%X ", flBdkVol->signBuffer[j] );
  DinfoPrint( ")\n" );

  DinfoPrint( EX_TEXT("      Start Unit           : %d\n"), flBdkVol->startImageBlock );
  DinfoPrint( EX_TEXT("      End Unit             : %d\n\n"),flBdkVol->endImageBlock );
}







⌨️ 快捷键说明

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