📄 sdmmcboot.c
字号:
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 + -