[原创].关于SD卡的隐藏分区的认识过程及结果
[原創(chuàng)][連載].基于SOPC的簡易數(shù)碼相框 - Nios II SBTE部分(軟件部分) - SD卡(SPI模式)驅(qū)動
上一次我用Nios II驅(qū)動SD卡(SPI模式),使用的是金斯頓的卡。然后void SD_CARD_Read_Data_LBA(u32 LBA,u16 n_bytes,u8 *buf);讀取的扇區(qū)與使用winhex查看的邏輯扇區(qū)的內(nèi)容,其偏移地址和內(nèi)容是一樣的。這一次,我使用nuc1xx來驅(qū)動SD卡,簡單的把上次用IO模擬的部分,換成了SPI核來操作,一直很順利,讀取的CSD和CID也是吻合的。但不巧的是,這次我手上只有一張CANAN DV上面的SD卡,使用void SD_CARD_Read_Data_LBA(u32 LBA,u16 n_bytes,u8 *buf);讀取的扇區(qū)和winhex查看的邏輯扇區(qū)內(nèi)容是不一致的。
SD卡讀取代碼片段
void SD_CARD_DEMO(void)
{
    uint16_t i;
    uint8_t buf[512];
    
    SD_CARD_DEBUG("\r");    
    SD_CARD_DEBUG("開始讀取SD卡信息\r");   
    SD_CARD_Get_Info(); // 讀取CID和CSD
    SD_CARD_DEBUG("SD卡信息讀取完畢\r");
    
    SD_CARD_DEBUG("\r");
    SD_CARD_DEBUG("開始讀取SD卡的第一個塊(扇區(qū))\r");
    SD_CARD_Read_Data_LBA(0,512,buf); // 讀取SD卡的第一個塊(扇區(qū))
    for(i=0; i<512; i++) {
        if(i%16 == 0) SD_CARD_DEBUG("0x%.3X ", i);
        SD_CARD_DEBUG("%.2X ", buf[i]);
        if((i+1) % 8 == 0) SD_CARD_DEBUG(" ");
        if((i+1) % 16 == 0) SD_CARD_DEBUG("\r");
    }
    SD_CARD_DEBUG("讀取SD卡的第一個塊(扇區(qū))完畢\r");
}
使用串口調(diào)試所顯示的數(shù)據(jù)
SD卡初始化完成
開始讀取SD卡信息
SD-CARD CID:
    Manufacturer ID(MID): 0x88
    OEM/Application ID(OLD): 
    Product Name(PNM): NCard
    Product Revision: 0x10
    Serial Number(PSN): 0x00000286
    Manufacture Date Code(MDT): 0x0AC
    CRC-7 Checksum(CRC7):0x11
SD-CARD CSD:
    max.read data block length: 1024
    device size: 3821
    device size multiplier: 7
    device capacity: 1911 MB
SD卡信息讀取完畢
開始讀取SD卡的第一個塊(扇區(qū))
0x000 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x010 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x020 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x030 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x040 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x050 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x060 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x070 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x080 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x090 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0A0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0B0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0C0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0D0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0E0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x0F0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x100 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x110 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x120 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x130 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x140 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x150 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x160 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x170 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x180 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x190 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x1A0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x1B0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 02  
0x1C0 04 00 06 2A EA CA 81 00  00 00 7F B7 3B 00 00 00  
0x1D0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x1E0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  
0x1F0 00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 AA  
讀取SD卡的第一個塊(扇區(qū))完畢
而使用winhex讀取的內(nèi)容卻不一樣,一時間我就蒙了。
圖1 使用winhex讀取的SD卡的邏輯扇區(qū)0內(nèi)容
為何讀取的內(nèi)容不對呢?
在ourdev上面逛,找到如下資料。
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3849969
【3樓】 greenwoods
積分:140
派別:
等級:------
來自:
猜測一下,邏輯地址=物理地址+保留的扇區(qū)數(shù),DBR可能在物理地址的零扇區(qū),也可能不在零扇區(qū)。
如果不在零扇區(qū),在零扇區(qū)的 0x1c6 有保留的扇區(qū)數(shù)。
用WinHex觀察時,如果裝入的是physical media就應(yīng)該是物理地址。可能格式化后,保留的扇區(qū)數(shù)與原來不一樣,所以邏輯地址改變。
__________________________
Across the greatwall we can reach every corner in the world.
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4348878
【5樓】 zxs2000
積分:141
派別:
等級:------
來自:
謝謝!
該扇區(qū)有兩個重要信息:
一、在0x1ca開始的四個字節(jié)代表該SD卡有個扇區(qū)
二、在0x1c6開始的四個字節(jié)表示引導扇區(qū)在哪個扇區(qū)。
于是我對比用串口讀出來的數(shù)據(jù),從0x1C6起的4個字節(jié)為0x00 00 00 81=129,從0x1CA起的4個字節(jié)內(nèi)容為0x00 3B B7 7F=3913599
注意上面圖1 ,
再一次使用winhex讀取SD卡,不過這一次我們要讀取物理扇區(qū)0的內(nèi)容。
圖2 使用winhex讀取的SD卡的物理扇區(qū)0內(nèi)容
圖2所示與SD卡所讀完全一致。這說明,我上次使用nios ii讀取金士頓的卡,屬于“走運”,碰巧物理扇區(qū)核邏輯扇區(qū)重疊。
注意觀察,圖2 和圖一對比,是不是3913728-3713599=129。
SD卡讀取代碼片段
void SD_CARD_DEMO(void)
{
    uint16_t i;
    uint8_t buf[512];
    
    SD_CARD_DEBUG("\r");    
    SD_CARD_DEBUG("開始讀取SD卡信息\r");   
    SD_CARD_Get_Info(); // 讀取CID和CSD
    SD_CARD_DEBUG("SD卡信息讀取完畢\r");
    
    SD_CARD_DEBUG("\r");
    SD_CARD_DEBUG("開始讀取SD卡的第一個塊(扇區(qū))\r");
    SD_CARD_Read_Data_LBA(129,512,buf); // 讀取SD卡的第129個塊(扇區(qū))
    for(i=0; i<512; i++) {
        if(i%16 == 0) SD_CARD_DEBUG("0x%.3X ", i);
        SD_CARD_DEBUG("%.2X ", buf[i]);
        if((i+1) % 8 == 0) SD_CARD_DEBUG(" ");
        if((i+1) % 16 == 0) SD_CARD_DEBUG("\r");
    }
    SD_CARD_DEBUG("讀取SD卡的第129個塊(扇區(qū))完畢\r");
}
使用串口調(diào)試所顯示的數(shù)據(jù)
SD卡初始化完成
開始讀取SD卡信息
SD-CARD CID:
    Manufacturer ID(MID): 0x88
    OEM/Application ID(OLD): 
    Product Name(PNM): NCard
    Product Revision: 0x10
    Serial Number(PSN): 0x00000286
    Manufacture Date Code(MDT): 0x0AC
    CRC-7 Checksum(CRC7):0x11
SD-CARD CSD:
    max.read data block length: 1024
    device size: 3821
    device size multiplier: 7
    device capacity: 1911 MB
SD卡信息讀取完畢
開始讀取SD卡的第129個塊(扇區(qū))
0x000 EB 3C 90 4D 53 44 4F 53  35 2E 30 00 02 40 02 00  
0x010 02 00 02 00 00 F8 EF 00  3F 00 FF 00 81 00 00 00  
0x020 7F B7 3B 00 00 00 29 DD  DF CE AC 4E 4F 20 4E 41  
0x030 4D 45 20 20 20 20 46 41  54 31 36 20 20 20 33 C9  
0x040 8E D1 BC F0 7B 8E D9 B8  00 20 8E C0 FC BD 00 7C  
0x050 38 4E 24 7D 24 8B C1 99  E8 3C 01 72 1C 83 EB 3A  
0x060 66 A1 1C 7C 26 66 3B 07  26 8A 57 FC 75 06 80 CA  
0x070 02 88 56 02 80 C3 10 73  EB 33 C9 8A 46 10 98 F7  
0x080 66 16 03 46 1C 13 56 1E  03 46 0E 13 D1 8B 76 11  
0x090 60 89 46 FC 89 56 FE B8  20 00 F7 E6 8B 5E 0B 03  
0x0A0 C3 48 F7 F3 01 46 FC 11  4E FE 61 BF 00 00 E8 E6  
0x0B0 00 72 39 26 38 2D 74 17  60 B1 0B BE A1 7D F3 A6  
0x0C0 61 74 32 4E 74 09 83 C7  20 3B FB 72 E6 EB DC A0  
0x0D0 FB 7D B4 7D 8B F0 AC 98  40 74 0C 48 74 13 B4 0E  
0x0E0 BB 07 00 CD 10 EB EF A0  FD 7D EB E6 A0 FC 7D EB  
0x0F0 E1 CD 16 CD 19 26 8B 55  1A 52 B0 01 BB 00 00 E8  
0x100 3B 00 72 E8 5B 8A 56 24  BE 0B 7C 8B FC C7 46 F0  
0x110 3D 7D C7 46 F4 29 7D 8C  D9 89 4E F2 89 4E F6 C6  
0x120 06 96 7D CB EA 03 00 00  20 0F B6 C8 66 8B 46 F8  
0x130 66 03 46 1C 66 8B D0 66  C1 EA 10 EB 5E 0F B6 C8  
0x140 4A 4A 8A 46 0D 32 E4 F7  E2 03 46 FC 13 56 FE EB  
0x150 4A 52 50 06 53 6A 01 6A  10 91 8B 46 18 96 92 33  
0x160 D2 F7 F6 91 F7 F6 42 87  CA F7 76 1A 8A F2 8A E8  
0x170 C0 CC 02 0A CC B8 01 02  80 7E 02 0E 75 04 B4 42  
0x180 8B F4 8A 56 24 CD 13 61  61 72 0B 40 75 01 42 03  
0x190 5E 0B 49 75 06 F8 C3 41  BB 00 00 60 66 6A 00 EB  
0x1A0 B0 4E 54 4C 44 52 20 20  20 20 20 20 0D 0A 52 65  
0x1B0 6D 6F 76 65 20 64 69 73  6B 73 20 6F 72 20 6F 74  
0x1C0 68 65 72 20 6D 65 64 69  61 2E FF 0D 0A 44 69 73  
0x1D0 6B 20 65 72 72 6F 72 FF  0D 0A 50 72 65 73 73 20  
0x1E0 61 6E 79 20 6B 65 79 20  74 6F 20 72 65 73 74 61  
0x1F0 72 74 0D 0A 00 00 00 00  00 00 00 AC CB D8 55 AA  
讀取SD卡的第129個塊(扇區(qū))完畢
與winhex的邏輯0扇區(qū)內(nèi)容一致。回頭看上面計算的數(shù)據(jù)
從0x1C6起的4個字節(jié)為0x00 00 00 81=129,從0x1CA起的4個字節(jié)內(nèi)容為0x00 3B B7 7F=3913599
原來我現(xiàn)在使用的這張SD卡,隱藏扇區(qū)大小為129個扇區(qū),可用邏輯扇區(qū)大小為3713599=0x00 3B B7 7F個扇區(qū),而本卡所有的扇區(qū)數(shù)為3913728=0x00 3B B7 7F +0x00 00 00 81。
雖然知道了這些,我還是很沮喪,因為我不曉得用代碼來做,怎樣才能直接訪問到邏輯扇區(qū)?難道是靠碰運氣?每次都拿winhex對比一下?求解答。
安德魯? / CC BY 2.5
總結(jié)
以上是生活随笔為你收集整理的[原创].关于SD卡的隐藏分区的认识过程及结果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: SAP Spartacus SplitV
- 下一篇: SAP Fiori Elements 本
