我目前正尝试使用微控制器将磁盘格式化为exFAT。我的问题是我需要计算校验和,该校验和使用VBR(卷引导区域)的扇区1到11中的字节将其存储到扇区12中,但我的结果不正确。当校验和不正确时,Windows或任何其他识别exFAT的操作系统都无法使用该磁盘,因为校验和已经过验证,如果不正确则会发生致命错误。
这是计算32位校验和的函数:
uint32_t BootChecksum(char * data, long bytes){
uint32_t checksum = 0;
for (uint32_t i = 0 ; i < bytes ; i++){
if (i == 106 || i == 107 || i == 112)
continue;
checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i];
if(checksum == 0xF1924082){
printf("%02X | i = %d", checksum, i);
}
}
return checksum;
}
从我能够阅读的内容来看,该功能是正确的,所以我的猜测是我使用的数据不正确。我只需要占用所需的11个扇区,每个扇区512字节,就会产生5632字节的数组。
我使用类似的函数来计算入口集的校验和(16位校验和),结果是正确的,它实际上必须是数据,但我不明白我是什么&# 39;我在那里失踪了!
任何了解exFAT的人都可以帮助我吗?谢谢!
答案 0 :(得分:1)
我怀疑这是运营商优先的问题。
在this page中,我看到以这种方式修改checksum
的crc定义
checksum = (checksum<<31) | (checksum>> 1) + data[i];
也就是说,如果我没错,相当于
checksum = (checksum<<31) | ((checksum>> 1) + data[i]);
因为(如果我记得很清楚),加号运算符(+
)的优先级高于位或运算符(|
)。
相反,您的代码是
checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i];
这是一个完全不同的代码,因为你首先应用按位或下一个加号。
我想可以使用
checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]);
p.s:抱歉我的英语不好
---编辑2016.06.09 ---
另一个问题应该是data
的签名。
您将data
定义为char
的指针; ntfs.com将data
定义为const unsigned char
的数组。
指针/数组差异不是问题; const
部分并不重要(但我建议您将data
定义为const
;问题(我想)是转换为uint32_t
的{{1}},如果char
使用负值而不是char
进行签名。
示例:假设unsigned char
的值为-1;使用data[i]
时,如果我记得很清楚,首先(uint32_t) data[i]
会转换为data[i]
,然后转换为int(-1)
。所以你得到4294967295。
如果您的uint32_t(-1)
是data[i]
,则代替-1 unsigned char
值为255;所以data[i]
首先将255转换为(uint32_t) data[i]
,即int(255)
旁边的255,仍为255。
简而言之,我的建议是:改变
uint32_t(255)
在
checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]);
或只是
checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) (unsigned char) data[i]);