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

📄 sdmmcboot.c

📁 PXA270 下用SD卡启动的代码,已在wince5.0的mainstoneii下测试通过
💻 C
📖 第 1 页 / 共 2 页
字号:
	  if (total_blocks > bootPartInfo.SecPerClus)
	  {
	    // Read the multiple blocks
	    if (send_command_to_cards (18, (BlockAddr * 0x200), 
			                       (CMDAT_DATA_EN | CMDAT_RESP_R1 | CMDAT_DMA_EN), 
								   blk, 1, 0)
		    != MSC_PASSED)
		  return MSC_FAILED;

	    addr = (unsigned int)&(DataBuf[base]);
        dmac_reg->channel[USE_DMA_CHANNEL].dma_dar = addr & 0x1FFFFFFF;
	    dmac_reg->channel[USE_DMA_CHANNEL].dma_tcr = (blk * 0x200 / 32);
	    dmac_reg->channel[USE_DMA_CHANNEL].dma_ccsr 
	      = (DMA_DCCSR_DAM | DMA_DCCSR_RDIL_IGN | DMA_DCCSR_SWDH32 | DMA_DCCSR_DWDH32
		     | DMA_DCCSR_DS32BYTE | DMA_DCCSR_CHDE);

	    dmac_reg->channel[DMA_CHANNEL_NUM - 1].dma_cr = DMA_DMACR_DME;
	    while (dmac_reg->channel[USE_DMA_CHANNEL].dma_tcr)
		{
		  if (dmac_reg->channel[DMA_CHANNEL_NUM - 1].dma_cr & (DMA_DMACR_HTR | DMA_DMACR_AER))
		  {
            Log ("Data copy error (to address 0x%X)\n", (unsigned int)&(DataBuf[base]));
		    return MSC_FAILED;
		  }
		}
	    dmac_reg->channel[DMA_CHANNEL_NUM - 1].dma_cr = 0;
	  }
	  else
#endif
	  {
	    // Read the multiple blocks

		
	    if (send_command_to_cards (18, (BlockAddr * 0x200), 
			                       (MMC_CMDAT_DATA_EN | MMC_CMDAT_RESPONSE_R1), blk, 1, 0)
		    != MSC_PASSED)
		  return MSC_FAILED;
		i = 0;
		
	    while (i < blk * 0x200)
		{
			do {
		     mmc_ireg = READ_MMC_REGISTER_DWORD(pSDMMCRegisters, MMC_IREG);
			}  while(! (mmc_ireg & MMC_IREG_RXFIFO_REQ));

		  if (mmc_ireg & MMC_IREG_RXFIFO_REQ)
		  {
			  for (j = 0; j < 32; j++){
		      pBufPtr[i++] = *pMMC_RX_Fifo;
			  }
		  }
		}

		pBufPtr += blk * 0x200;
	  }
	  base = base + (blk * 0x80);

	  // Stop multiple blocks Reading
	  if (send_command_to_cards (12, 0, (MMC_CMDAT_RESPONSE_R1 | MMC_CMDAT_EXPECT_BUSY), 
		                         0, 1, 0) != MSC_PASSED)
		return MSC_FAILED;

	  // Dump the message about reading process.
	  if (read_file)
	  {
	    imagefile.BlockCnt += blk;
		dump_copying_process ();
	  }
	  do {
		mmc_stat = READ_MMC_REGISTER_DWORD( pSDMMCRegisters, MMC_STAT);
	  } while (!(mmc_stat & MMC_STAT_DATA_TRANSFER_DONE)) ;
	  
	  // Check the SD card is ready for next reading
	  i = 0xFF;
	  imagefile.SDcardState = 0;
	  while (i--)
	  {
        if (send_command_to_cards (13, CardAddr << 16, MMC_CMDAT_RESPONSE_R1, 0, 1, 0)
	        != MSC_PASSED)
	      return MSC_FAILED;

        if (getrespondR1 (0) != MSC_PASSED)
	      return MSC_FAILED;

	    if (!(imagefile.SDcardState & 0x1))
		  continue;
	  }
	  if (i == 0)
	  {
		Log ("++++ SD card is not ready when reading\n");
		return MSC_FAILED;
	  }

	  // Trans the next MAX_READ_BLOCK blocks 
	  blocks = blocks - blk;
	  BlockAddr = BlockAddr + blk;
	}
  }

  if (send_command_to_cards (13, CardAddr << 16, MMC_CMDAT_RESPONSE_R1, 0, 1, 0)
	   != MSC_PASSED)
	return MSC_FAILED;

  if (getrespondR1 (0) != MSC_PASSED)
	return MSC_FAILED;

  return MSC_PASSED;
}



void dump_sector (unsigned int *buf)
{
  int i;
  for (i = 0; i < 0x80; i++)
  {
	if (i % 4 == 0 && i != 0)
	{
	  if (i)
	    Log ("\n%X:    ", i * 4);
	  else
		Log ("%X:    ", i * 4);
	}
	if (i == 0)
	  Log ("%X:    ", i * 4);

	Log ("%B %B %B %B, ", ((buf[i] >> 0) & 0xff), ((buf[i] >> 8) & 0xff),
		 ((buf[i] >> 16) & 0xff), ((buf[i] >> 24) & 0xff));
  }
  Log ("\n");
}

/* Search the specify files from Directory Table. */

int search_nkfile (unsigned char *DirBuf, unsigned int length)
{
  int pos = 0, found = 0, i;
  unsigned char *EndOfBuf = DirBuf + length;
  struct DirectoryEntryInfo *dir;

  while (DirBuf < EndOfBuf)
  {
	for (i = 0; i < 8; i++)
	{
	  if (DirBuf[i] == ' ')
		break;
	  if ((DirBuf[i] ^ nk_name[i]) & 0xDF)
		break;
	}

	if (nk_name[i] == '\0' && (DirBuf[i] == ' ' || i == 8))
	{
	  for (i = 0; i < 3; i++)
	  {
	   if (DirBuf[8 + i] == ' ')
		break;
	  if ((DirBuf[8 + i] ^ nk_ext[i]) & 0xDF)
		break;
	  }

	  if (nk_ext[i] == '\0' && (DirBuf[8 + i] == ' ' || i == 3))
	  {
	    found = 1;
	    break;
	  }
	}	  
	DirBuf += 32;
  }

  if (found)
  {
	dir = (struct DirectoryEntryInfo *) DirBuf;
	imagefile.File_Size = dir->DIR_FileSize;
	imagefile.File_FstClus = dir->DIR_FstClusLO | (dir->DIR_FstClusHI << 16);
  }
  if (found)
    return MSC_PASSED;
  else
	return MSC_FAILED;
}

int search_next_FATseq ()
{
  unsigned int clusno, count, FatNum, offset;
  unsigned int secnum = bootPartInfo.SecPerClus;

  // Set Current sector with new value
  imagefile.Cur_Clus = imagefile.Next_Clus;
  count = 0;
  clusno = imagefile.Cur_Clus;

  // Search the sequence number about new sector
  while (imagefile.Next_Clus == clusno)
  {
	clusno++;

	// Read FAT table in order to search next sector if needs
	FatNum = (imagefile.Next_Clus * 4) / (secnum * bootPartInfo.BytesPerSec);
	if (imagefile.Cur_FATnum != FatNum)
	{
	  imagefile.Cur_FATnum = FatNum;
	  if (ReadBlocks (imagefile.FATBuff, (bootPartInfo.FatPos + FatNum * secnum), secnum) != MSC_PASSED)
	    return MSC_FAILED;
	}

	// Get the next sector number.
	offset = (imagefile.Next_Clus * 4) % (secnum * bootPartInfo.BytesPerSec);
	imagefile.Next_Clus = imagefile.FATBuff[offset / 4] & 0x0FFFFFFF;
	count++;
  }

  imagefile.Cur_SeqNum = count;
  return MSC_PASSED;
}

int ReadDataFromImageFile (unsigned char *maddr)
{
  ULONG  *pData, clusno, offset, cluscnt, start;
  ULONG  secnum = bootPartInfo.SecPerClus;

  start = (ULONG) maddr;
  clusno = bootPartInfo.DataPos + (imagefile.File_FstClus - 2) * secnum;
  imagefile.FATBuff = ReadDataBuf;
  if (ReadBlocks ((unsigned int *)maddr, clusno, secnum) != MSC_PASSED)
	return 0;

  pData = (ULONG*)(maddr + ROM_SIGNATURE_OFFSET);
  if (*pData != ROM_SIGNATURE) {
	Log ("!! The ImageFile %s.%s is ERROR !!\n", nk_name, nk_ext);
	return 0;
  }

  maddr += (bootPartInfo.BytesPerSec * secnum);

  //Init the FAT pointer about image file.
  imagefile.Cur_FATnum = (imagefile.File_FstClus * 4) / (secnum * bootPartInfo.BytesPerSec);
  if (ReadBlocks (imagefile.FATBuff, (bootPartInfo.FatPos + imagefile.Cur_FATnum * secnum), secnum) != MSC_PASSED)
	return 0;

  offset = (imagefile.File_FstClus * 4) % (bootPartInfo.BytesPerSec * secnum);
  imagefile.Next_Clus = imagefile.FATBuff[offset / 4] & 0x0FFFFFFF;
  imagefile.Cur_Clus = imagefile.File_FstClus;
  imagefile.Cur_SeqNum = 1;
  imagefile.BlockCnt = secnum;
  imagefile.OutCnt = 0;

#ifdef USE_DMA_CHANNEL
  Log ("Cur: 0x%x, Next: 0x%x, SeqNum: 0x%x; DMA is enable\n", imagefile.Cur_Clus, 
	   imagefile.Next_Clus, imagefile.Cur_SeqNum);
#else
  Log ("Cur: 0x%x, Next: 0x%x, SeqNum: 0x%x; DMA is disable\n", imagefile.Cur_Clus, 
	   imagefile.Next_Clus, imagefile.Cur_SeqNum);
#endif
  // Read the image file to SDRAM
  cluscnt = 1;
  while (imagefile.Next_Clus < 0x0FFFFFF0)
  {
	if (search_next_FATseq() != MSC_PASSED)
	  return 0;

	read_file = 1;
	clusno = bootPartInfo.DataPos + (imagefile.Cur_Clus - 2) * secnum;	
	if (ReadBlocks ((unsigned int *)maddr, clusno, (imagefile.Cur_SeqNum * secnum)) != MSC_PASSED)
	  return 0;
	
	read_file = 0;

	maddr += bootPartInfo.BytesPerSec * secnum * imagefile.Cur_SeqNum;
	cluscnt += imagefile.Cur_SeqNum;
  }

  if (cluscnt * bootPartInfo.BytesPerSec * secnum < imagefile.File_Size)
  {
	Log ("++++ !! The ImageFile %s.%s is Damage !!\n", nk_name, nk_ext);
	return 0;
  }

  if (imagefile.BlockCnt)
  {
    offset = (imagefile.OutCnt * MAX_READ_BLOCK + imagefile.BlockCnt);
	offset = offset * bootPartInfo.BytesPerSec;
    Log ("--- Reading file: 0x%x (%d) completed !! \n", offset, offset);
  }

  Log ("!! OK. Copying ImageFile %s.%s to memory is completed\n", nk_name, nk_ext);

  //Jump to image to start OS
  Log("Jumping to image at 0x%X...\n", start);
  //FlushDCache();
  //FlushICache();
  //dump_sector ((unsigned int *)0x80002000); while (1);
  //JumpTo(start);
  return 1;
}



int OEMLaunchSDCard(unsigned char *maddr)
{
  unsigned int next_table, part, secno, found, clus, FatCnt, cnt;
  unsigned char partion_type;

  if (checkSDcard () != MSC_PASSED)
  {
	Log ("!! ERROR !! (not found SD card or SD card failed !)\n");
	return 0;
  }
 
  if (initSDcard () != MSC_PASSED)
  {
	Log ("!! ERROR !! (operation of SD card)\n");
	return 0;
  }

// Read the Main partition Table
  if (ReadBlocks (ReadDataBuf, 0, 1) != MSC_PASSED)
  {
	Log ("!! ERROR !! when reading the Main partion Table\n");
	return 0;
  }

  if ((ReadDataBuf[0x7f] >> 16) != 0xAA55)
  {
	Log ("!! ERROR !! <reading the main partition table>\n");
	return 0;
  }
  
  // If "MSDOS" appear in the ReadBuf header
  if ((ReadDataBuf[0] & 0xFF0000FF) == 0x4D0000EB && ReadDataBuf[1] == 0x534F4453)
  {
	unsigned int i;
	for (i = 0; i < 0x80; i++)
	  PartInfoBuf[i] = ReadDataBuf[i];
  }
  else
  {
	  
     partion_type = (ReadDataBuf[0x70] >> 16) & 0xFF;
     next_table = 0;

     // 05H and 0F is extension partition
     if (partion_type == 0x05 || partion_type == 0x0f)
	 {
       next_table = (ReadDataBuf[0x71] >> 16) | (ReadDataBuf[0x72] << 16);

       // Read the next partition Table (extend or main)
       if (ReadBlocks (ReadDataBuf, next_table, 1) != MSC_PASSED)
	   {
	     Log ("!! ERROR !! when reading the Extension partition Table\n");
	     return 0;
	   }

       if ((ReadDataBuf[0x7f] >> 16) != 0xAA55)
	   {
	     Log ("!! ERROR !! <reading the extension partition table>\n");
	     return 0;
	   }
	 }

     partion_type = (ReadDataBuf[0x70] >> 16) & 0xFF;
     Log ("Read SD Card partition type: 0x%x\n", partion_type);

     // This partition is FAT32 ??
     if (partion_type != 0x0B && partion_type != 0x1B
	     && partion_type != 0x0C && partion_type != 0x1C)
	 {
	   Log ("!! ERROR !! <Not Found the FAT32 partition table>\n");
	   return 0;
	 }

     part = (ReadDataBuf[0x71] >> 16) | (ReadDataBuf[0x72] << 16);
     part = part + next_table;

	 

     // Read the partition Contents (extend or main)
     bootPartInfo.PartPos = part;

     if (ReadBlocks (PartInfoBuf, part, 1) != MSC_PASSED)
	   return 0;
  }

  if ((PartInfoBuf[0x7f] >> 16) != 0xAA55)
  {
	Log ("!! ERROR !! <reading the partition contents>\n");
	return 0;
  }

  pBootSec = (struct BootSec *)PartInfoBuf;

// Compute the Partition Info pointer.
  bootPartInfo.BytesPerSec = pBootSec->BytesPerSec[0] | (pBootSec->BytesPerSec[1] << 8);
  bootPartInfo.SecPerClus = pBootSec->SecPerClus[0];
  bootPartInfo.RsvdSecCnt = pBootSec->RsvdSecCnt[0] | (pBootSec->RsvdSecCnt[1] << 8);
  bootPartInfo.NumFATs = pBootSec->NumFATs[0];
  bootPartInfo.RootEntCnt = pBootSec->RootEntCnt[0] | (pBootSec->RootEntCnt[1] << 8);
  bootPartInfo.HiddSec = pBootSec->HiddSec[0] | (pBootSec->HiddSec[1] << 8)
	                     | (pBootSec->HiddSec[2] << 16) | (pBootSec->HiddSec[3] << 24);
  bootPartInfo.TotSec32 = pBootSec->TotSec32[0] | (pBootSec->TotSec32[1] << 8)
	                     | (pBootSec->TotSec32[2] << 16) | (pBootSec->TotSec32[3] << 24);
  bootPartInfo.FATSz32 = pBootSec->FATSz32[0] | (pBootSec->FATSz32[1] << 8)
	                     | (pBootSec->FATSz32[2] << 16) | (pBootSec->FATSz32[3] << 24);
  bootPartInfo.RootClus = pBootSec->RootClus[0] | (pBootSec->RootClus[1] << 8)
	                     | (pBootSec->RootClus[2] << 16) | (pBootSec->RootClus[3] << 24);
  bootPartInfo.FSInfo = pBootSec->FSInfo[0] | (pBootSec->FSInfo[1] << 8);
  bootPartInfo.BkBootSec = pBootSec->BkBootSec[0] | (pBootSec->BkBootSec[1] << 8);

  bootPartInfo.FatPos = bootPartInfo.PartPos + bootPartInfo.RsvdSecCnt;
  bootPartInfo.RootPos = bootPartInfo.FatPos + bootPartInfo.FATSz32 
	                     + (bootPartInfo.RootClus - 2) * bootPartInfo.SecPerClus;
  bootPartInfo.DataPos = bootPartInfo.FatPos + bootPartInfo.FATSz32 * bootPartInfo.NumFATs;

#if 1
  Log ("bootPartInfo.BytesPerSec is 0x%x (%d)\n", bootPartInfo.BytesPerSec, bootPartInfo.BytesPerSec);
  Log ("bootPartInfo.SecPerClus is 0x%x (%d)\n", bootPartInfo.SecPerClus, bootPartInfo.SecPerClus);
  Log ("bootPartInfo.RsvdSecCnt is 0x%x (%d)\n", bootPartInfo.RsvdSecCnt, bootPartInfo.RsvdSecCnt);
  Log ("bootPartInfo.NumFATs is 0x%x (%d)\n", bootPartInfo.NumFATs, bootPartInfo.NumFATs);
  Log ("bootPartInfo.RootEntCnt is 0x%x (%d)\n", bootPartInfo.RootEntCnt, bootPartInfo.RootEntCnt);
  Log ("bootPartInfo.HiddSec is 0x%x (%d)\n", bootPartInfo.HiddSec, bootPartInfo.HiddSec);
  Log ("bootPartInfo.TotSec32 is 0x%x (%d)\n", bootPartInfo.TotSec32, bootPartInfo.TotSec32);
  Log ("bootPartInfo.FATSz32 is 0x%x (%d)\n", bootPartInfo.FATSz32, bootPartInfo.FATSz32);
  Log ("bootPartInfo.RootClus is 0x%x (%d)\n", bootPartInfo.RootClus, bootPartInfo.RootClus);
  Log ("bootPartInfo.FSInfo is 0x%x (%d)\n", bootPartInfo.FSInfo, bootPartInfo.FSInfo);
  Log ("bootPartInfo.BkBootSec is 0x%x (%d)\n", bootPartInfo.BkBootSec, bootPartInfo.BkBootSec);

  Log ("bootPartInfo.PartPos is 0x%x (%d)\n", bootPartInfo.PartPos, bootPartInfo.PartPos);
  Log ("bootPartInfo.FatPos is 0x%x (%d)\n", bootPartInfo.FatPos, bootPartInfo.FatPos);
  Log ("bootPartInfo.RootPos is 0x%x (%d)\n", bootPartInfo.RootPos, bootPartInfo.RootPos);
  Log ("bootPartInfo.DataPos is 0x%x (%d)\n", bootPartInfo.DataPos, bootPartInfo.DataPos);
#endif

  if (bootPartInfo.BytesPerSec != 0x200 || bootPartInfo.SecPerClus > MAX_SEC_PER_CLUS)
  {
	Log ("!! ERROR !! --- Sector size is not 0x200 or Sector Per Cluster is very big (> 0x%x)\n",
		 bootPartInfo.SecPerClus);
	return 0;
  }

// Search the NK IMAGE FILES (nk.bin)

  found = 0;
  FatCnt = 0xFFFFFFFF;
  clus = bootPartInfo.RootClus;
  cnt = bootPartInfo.SecPerClus;

  while (! found)
  {
	unsigned int num, offset;

	secno = (clus - 2) * 4;

    if (ReadBlocks (ReadDataBuf, (bootPartInfo.DataPos + secno), cnt) != MSC_PASSED)
	  return 0;

    if (search_nkfile ((unsigned char *)ReadDataBuf, cnt * bootPartInfo.BytesPerSec) == MSC_PASSED)
	{
      found = 1;
	  break;
	}

	/* Get the next clus number.  */
	num = (clus * 4) / (cnt * bootPartInfo.BytesPerSec);
	if (num != FatCnt)
	{
	  if (ReadBlocks (ReadFatBuf, (bootPartInfo.FatPos + num), cnt) != MSC_PASSED)
	    return 0;
	}

	offset = (clus * 4) % (cnt * bootPartInfo.BytesPerSec);
	clus = ReadFatBuf[offset / 4] & 0x0FFFFFFF;

	/* It is the Last sector.  */
	if (clus >= 0x0FFFFFF0)
	  break;
  }

  if (! found)
  {
	Log ("!! EEROR !! <Can not found NK Image file: %s.%s\n", nk_name, nk_ext);
	return 0;
  }

  Log ("File size is 0x%x(%d), FstClus is 0x%x(%d)\n", imagefile.File_Size, imagefile.File_Size,
	    imagefile.File_FstClus, imagefile.File_FstClus);

// Read Data from the NK IMAGE FILES (nk.nb0)
  return ReadDataFromImageFile (maddr);
}

⌨️ 快捷键说明

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