[原创].关于SD卡的隐藏分区的认识过程及结果
[原创][连载].基于SOPC的简易数码相框 - Nios II SBTE部分(软件部分) - SD卡(SPI模式)驱动
上一次我用Nios II驱动SD卡(SPI模式),使用的是金斯顿的卡。然后void
SD_CARD_Read_Data_LBA(u32 LBA,u16 n_bytes,u8 *buf);
读取的扇区与使用winhex查看的逻辑扇区的内容,其偏移地址和内容是一样的。这一次,我使用nuc1xx来驱动SD卡,简单的把上次用IO模拟的部分,换成了SPI核来操作,一直很顺利,读取的CSD和CID也是吻合的。但不巧的是,这次我手上只有一张CANAN DV上面的SD卡,使用void
SD_CARD_Read_Data_LBA(u32 LBA,u16 n_bytes,u8 *buf);
读取的扇区和winhex查看的逻辑扇区内容是不一致的。
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卡的第一个块(扇区)\r"); SD_CARD_Read_Data_LBA(0,512,buf); // 读取SD卡的第一个块(扇区) 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卡的第一个块(扇区)完毕\r"); }
使用串口调试所显示的数据
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卡的第一个块(扇区) 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卡的第一个块(扇区)完毕
而使用winhex读取的内容却不一样,一时间我就蒙了。
图1 使用winhex读取的SD卡的逻辑扇区0内容
为何读取的内容不对呢?
在ourdev上面逛,找到如下资料。
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3849969
【3楼】 greenwoods
积分:140
派别:
等级:------
来自:
猜测一下,逻辑地址=物理地址+保留的扇区数,DBR可能在物理地址的零扇区,也可能不在零扇区。
如果不在零扇区,在零扇区的 0x1c6 有保留的扇区数。
用WinHex观察时,如果装入的是physical media就应该是物理地址。可能格式化后,保留的扇区数与原来不一样,所以逻辑地址改变。
__________________________
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
派别:
等级:------
来自:
谢谢!
该扇区有两个重要信息:
一、在0x1ca开始的四个字节代表该SD卡有个扇区
二、在0x1c6开始的四个字节表示引导扇区在哪个扇区。
于是我对比用串口读出来的数据,从0x1C6起的4个字节为0x00 00 00 81=129,从0x1CA起的4个字节内容为0x00 3B B7 7F=3913599
再一次使用winhex读取SD卡,不过这一次我们要读取物理扇区0的内容。
图2 使用winhex读取的SD卡的物理扇区0内容
图2所示与SD卡所读完全一致。这说明,我上次使用nios ii读取金士顿的卡,属于“走运”,碰巧物理扇区核逻辑扇区重叠。
注意观察,图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卡的第一个块(扇区)\r"); SD_CARD_Read_Data_LBA(129,512,buf); // 读取SD卡的第129个块(扇区) 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个块(扇区)完毕\r"); }
使用串口调试所显示的数据
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个块(扇区) 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个块(扇区)完毕
与winhex的逻辑0扇区内容一致。回头看上面计算的数据
从0x1C6起的4个字节为0x00 00 00 81=129,从0x1CA起的4个字节内容为0x00 3B B7 7F=3913599
原来我现在使用的这张SD卡,隐藏扇区大小为129个扇区,可用逻辑扇区大小为3713599=0x00 3B B7 7F个扇区,而本卡所有的扇区数为3913728=0x00 3B B7 7F +0x00 00 00 81。
虽然知道了这些,我还是很沮丧,因为我不晓得用代码来做,怎样才能直接访问到逻辑扇区?难道是靠碰运气?每次都拿winhex对比一下?求解答。