BIOS中的内存测试memtest

参考:

https://blog.csdn.net/evenness/article/details/7818857

https://blog.csdn.net/skdkjzz/article/details/17073455

https://blog.csdn.net/sannik/article/details/8930625#

在 U-Boot中,Denx(U-Boot的开发商)针对常见的DDR内存故障进行了严格的检测处理,上图描述了该检测处理过程的三个步骤:检测数据线、地址线和DDR物理存储部件,主要涉及这三个步骤的处理过程和方法,对于DDR子系统,是很容易出故障并且是很难debug检测出来的,而Denx所针对 DDR内存故障设计的检测方法是非常严谨,值得学习研究的。

 

1、为什么先检测数据线?

因为如果数据线是断开的,那么一切无从谈起!接下来是检测地址线,只有数据线和地址线都通过,检测内存的存储单元才有意义,这样的流程也利于分割定位问题。上面testingsequence框图将整个检测过程分成三大步,用三个虚线方框表示。

2、数据线的连接错误

数据线的连接可能存在两种错误,一种是被断开,另一种布线或生产造成互相短路。

3、如何检测数据线的连接错误

Denx设计的数据线检测算法还是很Tricky和精秒的,整个处理流程如下例子:如果是两根数据线,只需要写入并读出一个pattern=0b01(0b开头表示二进制数)就能判断它们是否短路或断开。很明显,大部分的嵌入式平台不止两根数据线,我们以64位地址线为例,pattern= 0b101010101010101010....能检测出奇偶位之间的数据错误。如果这个错误被排除,每两根数据线组成一组(这是理解下一个pattern的关键),再用相同的办法,检测每相邻两组之间是否有短路,就得到第二个pattern,就是0b110011001100...... 依次类推,以4根数据线为一组,8根线为一组,相继得到共6个pattern,分别是0xaaaaaaaaaaaaaaaa,0xcccccccccccccccc,0xf0f0f0f0f0f0f0f0,0xff00ff00ff00ff00,0xffff0000ffff0000,0xffffffff00000000。只要相继写入并读出这6个pattern就能验证是否存在数据线交叉短路错误。

4、如何检测数据线与板上其它信号线交叉短路或断路

取以上6个pattern的反码,总共12个pattern就能检测到每一位都可以写入和读出0和1。

5、什么是floating buses错误

floatingbuses会“欺骗”测试软件,如果测试软件写入并很快读出一个值的时候,写操作会跟数据线上的电容充电,总线会短暂的保持它的状态。当测试软件读操作时,总线会返回刚写入的值,即使实际上该数据线是断路的。

6、如何检测数据线的floating buses错误

检测floatingbuses错误的算法不复杂,在写入和读回之间再插入一次对不同地址写入不同值的操作。例如,X写入X1位置,Y写入Y1位置,再从X1位置读出X值则表示floatingbuses错误不存在。

7、地址线的错误

如果地址线存在错误,其症状是地址空间中的两个不同位置被映射到同一物理存储位置。更通俗地讲,就是写一个位置却“改变”了另一个位置。

8、地址线的错误检测

地址线的错误检测相对简单,其算法是:

1)、将地址的值作为内容写入该地址处,汇编的表示方法是 (addr) =addr。即将地址值写到地址对应的空间里,这样确保每一个位置的内容不同。

2)、依次将内存基地址的某一根地址线的值翻转(flip/toggle)得到某个地址,从该地址取值,如果该值和基地址的值相等,则表示某一位地址线有问题。

这个算法的特点是每次只检测一根地址线,方法简单有效。

9、存储单元的错误

以上数据线和地址线的检测都是检测布线或工厂生产的错误,而存储单元的检测则是真正对DDR内存芯片的检测。内存芯片的常见错误是bit-stuck,简而言之,就是让它是0,它偏为1,让它为1,它偏为0,检测方法也很简单,就是用不同的pattern去写尽可能所有的地址并读回比较。有一些常用的pattern如0x5555, 0xAAAA等。

10、几个简单的检测DDR故障的方法

上面的DDR检测算法,虽然全面,但是耗时比较长,常常需要好几个小时,在Uboot命令行下也有几个简单的命令可以检测常见内存故障,如下所示:

1)、mtest addr lenth pattern

这个命令需要注意,DDR在Uboot启动后被映射到了0地址,但是uboot的代码和堆、栈空间0x10000000处开始,这些空间是不能被刷的,否则就挂死了。

2)、复制NOR flash的内容到内存中,如 cp.b 0x20080000 0x7fc020000,然后比较 cmp.b 0x20080000 0x7fc0 20000。

3)、下载kernel image到内存中,copy NOR flash或tftp都行,然后调用iminfo LOAD_ADDR 检测CRC错误。

第一种方法是用特定的pattern去刷DDR的空闲空间,第二种和第三种方法可以说Pattern的随机性更大一些。

当然最彻底的检测方法当然是长时间跑Linux系统,上面的方法更适用于系统不稳定时定位错误。
 

实现代码如下:

static void move64(unsigned long long *src, unsigned long long *dest){*dest = *src;}/** This is 64 bit wide test patterns.  Note that they reside in ROM* (which presumably works) and the tests write them to RAM which may* not work.** The "otherpattern" is written to drive the data bus to values other* than the test pattern.  This is for detecting floating bus lines.**/const static unsigned long long pattern[] = {0xaaaaaaaaaaaaaaaaULL,0xccccccccccccccccULL,0xf0f0f0f0f0f0f0f0ULL,0xff00ff00ff00ff00ULL,0xffff0000ffff0000ULL,0xffffffff00000000ULL,0x00000000ffffffffULL,0x0000ffff0000ffffULL,0x00ff00ff00ff00ffULL,0x0f0f0f0f0f0f0f0fULL,0x3333333333333333ULL,0x5555555555555555ULL};const unsigned long long otherpattern = 0x0123456789abcdefULL;/* 数据线检测 */static int memory_post_dataline(unsigned long long * pmem){unsigned long long temp64 = 0;int num_patterns = sizeof(pattern)/ sizeof(pattern[0]);int i;unsigned int hi, lo, pathi, patlo;int ret = 0;for ( i = 0; i < num_patterns; i++) 
{
move64((unsigned long long *)&(pattern[i]), pmem++);
/*
* Put a different pattern on the data lines: otherwise they
* may float long enough to read back what we wrote.
*/
/* 预防floating buses错误 */
move64((unsigned long long *)&otherpattern, pmem--);
move64(pmem, &temp64);#ifdef INJECT_DATA_ERRORS
temp64 ^= 0x00008000;
#endifif (temp64 != pattern[i])
{
pathi = (pattern[i]>>32) & 0xffffffff;patlo = pattern[i] & 0xffffffff;hi = (temp64>>32) & 0xffffffff;lo = temp64 & 0xffffffff;post_log ("Memory (date line) error at %08x, ""wrote %08x%08x, read %08x%08x !\n",pmem, pathi, patlo, hi, lo);ret = -1;}}return ret;}/* 地址线检测 */static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size){ulong *target;ulong *end;ulong readback;ulong xor;int   ret = 0;end = (ulong *)((ulong)base + size);/* pointer arith! */xor = 0;for(xor = sizeof(ulong); xor > 0; xor <<= 1) 
{
/* 对测试的地址的某一根地址线的值翻转 */
target = (ulong *)((ulong)testaddr ^ xor);
if((target >= base) && (target < end)) 
{
/* 由于target是testaddr某一根地址线的值翻转得来故testaddr != target,下面赋值操作后应有*testaddr != *target */
*testaddr = ~*target;
readback  = *target;#ifdef INJECT_ADDRESS_ERRORS
if(xor == 0x00008000) 
{
readback = *testaddr;
}
#endif/* 出现此种情况只有testaddr == target,即某根地址线翻转无效 */
if(readback == *testaddr) 
{
post_log ("Memory (address line) error at %08x<->%08x, ""XOR value %08x !\n",testaddr, target, xor);ret = -1;}}}return ret;}static int memory_post_test1 (unsigned long start,unsigned long size,unsigned long val){unsigned long i;ulong *mem = (ulong *) start;ulong readback;int ret = 0;for (i = 0; i < size / sizeof (ulong); i++) {
mem[i] = val;
if (i % 1024 == 0)
WATCHDOG_RESET ();
}for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
readback = mem[i];
if (readback != val) {
post_log ("Memory error at %08x, ""wrote %08x, read %08x !\n",mem + i, val, readback);ret = -1;
break;
}
if (i % 1024 == 0)
WATCHDOG_RESET ();
}return ret;
}static int memory_post_test2 (unsigned long start, unsigned long size)
{
unsigned long i;
ulong *mem = (ulong *) start;
ulong readback;
int ret = 0;for (i = 0; i < size / sizeof (ulong); i++) {
mem[i] = 1 << (i % 32);
if (i % 1024 == 0)
WATCHDOG_RESET ();
}for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
readback = mem[i];
if (readback != (1 << (i % 32))) {
post_log ("Memory error at %08x, ""wrote %08x, read %08x !\n",mem + i, 1 << (i % 32), readback);ret = -1;
break;
}
if (i % 1024 == 0)
WATCHDOG_RESET ();
}return ret;
}static int memory_post_test3 (unsigned long start, unsigned long size)
{
unsigned long i;
ulong *mem = (ulong *) start;
ulong readback;
int ret = 0;for (i = 0; i < size / sizeof (ulong); i++) {
mem[i] = i;
if (i % 1024 == 0)
WATCHDOG_RESET ();
}for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
readback = mem[i];
if (readback != i) {
post_log ("Memory error at %08x, ""wrote %08x, read %08x !\n",mem + i, i, readback);ret = -1;
break;
}
if (i % 1024 == 0)
WATCHDOG_RESET ();
}return ret;
}static int memory_post_test4 (unsigned long start, unsigned long size)
{
unsigned long i;
ulong *mem = (ulong *) start;
ulong readback;
int ret = 0;for (i = 0; i < size / sizeof (ulong); i++) {
mem[i] = ~i;
if (i % 1024 == 0)
WATCHDOG_RESET ();
}for (i = 0; i < size / sizeof (ulong) && ret == 0; i++) {
readback = mem[i];
if (readback != ~i) {
post_log ("Memory error at %08x, ""wrote %08x, read %08x !\n",mem + i, ~i, readback);ret = -1;
break;
}
if (i % 1024 == 0)
WATCHDOG_RESET ();
}return ret;
}static int memory_post_tests (unsigned long start, unsigned long size)
{
int ret = 0;if (ret == 0)
ret = memory_post_dataline ((unsigned long long *)start);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_addrline ((ulong *)start, (ulong *)start, size);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_addrline ((ulong *)(start + size - 8),(ulong *)start, size);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test1 (start, size, 0x00000000);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test1 (start, size, 0xffffffff);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test1 (start, size, 0x55555555);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test1 (start, size, 0xaaaaaaaa);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test2 (start, size);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test3 (start, size);
WATCHDOG_RESET ();
if (ret == 0)
ret = memory_post_test4 (start, size);
WATCHDOG_RESET ();return ret;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1621724.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Win系统 - 内存稳定性测试软件(MemTest)

给大家介绍一款免安装的内存稳定性测试软件--MemTest&#xff0c;它不但可以彻底的检测出内存的稳定度&#xff0c;还可同时测试记忆的储存与检索资料的能力&#xff0c;memtest pro汉化版软件体积小巧&#xff0c;绿色免安装&#xff0c;使用简单&#xff0c;有兴趣的小伙伴们…

[Linux] VMware虚拟机开机后直接进入memtest

问题描述 今天碰到一个很难受的问题&#xff0c;昨天写报告的时候虚拟机还是正常的&#xff0c;早上开机的时候忽然报错进不了ubuntu虚拟机直接进入一个memtest的界面&#xff0c;情况大概是这样的&#xff1a; 一开始会报一些“error syntax”“error incorrect command”等错…

内存稳定性测试软件(MemTest)

给大家介绍一款免安装的内存稳定性测试软件--MemTest&#xff0c;它不但可以彻底的检测出内存的稳定度&#xff0c;还可同时测试记忆的储存与检索资料的能力&#xff0c;memtest pro汉化版软件体积小巧&#xff0c;绿色免安装&#xff0c;使用简单&#xff0c;有兴趣的小伙伴们…

MemTest内存软件测试介绍说明-2

有很多测试内存的软件。但是&#xff0c;许多测试只是将一些模式套用到内存上&#xff0c;而没有对内存体系结构或如何最好地检测错误进行深入思考或了解。这对于硬盘故障很有效&#xff0c;但很少发现间歇性错误。基于 BIOS 的内存测试对于查找间歇性内存错误毫无用处。 存储…

002微信小程序云开发API数据库-迁移状态查询/更新索引

文章目录 微信小程序云开发API数据库-迁移状态查询案例代码微信小程序云开发API数据库-更新索引案例代码 微信小程序云开发API数据库-迁移状态查询 在微信小程序中&#xff0c;云开发API数据库是一种方便快捷的数据库解决方案。但是&#xff0c;有时候我们可能需要将云开发数据…

PS 见了都自愧不如,吾爱又出新科技

不知道你们在网上见过这样的段子没有&#xff0c;就是某个网友发一张自己的照片出来&#xff0c;然后请求 P 图大神按要求帮助 P 一下图片。 就比如这种&#xff1a; 每次看到这些脑洞与技术同等存在的恶搞 PS 图片&#xff0c;总是让人笑掉大牙的同时理解了一个道理&#xff…

Photoshop 2023官方正版永久使用(卡BUG,无破解)

长话短说 本教程适用于Photoshop 2023版本&#xff0c;其他版本暂未试过&#xff1a; PS是一款收费软件&#xff0c;初次使用有免费试用期限&#xff0c;免费试用期过了以后按如下方式操作即可卡BUG来继续免费使用&#xff1a; 1、 打开软件 2、 点击在adobe.com…

C#---第二十: partial修饰类的特性及应用

0.知识背景 局部类型适用于以下情况&#xff1a; 类型特别大&#xff0c;不宜放在一个文件中实现。一个类型中的一部分代码为自动化工具生成的代码&#xff0c;不宜与我们自己编写的代码混合在一起。需要多人合作编写一个类 局部类型的限制: 局部类型只适用于类、接口、结构&am…

闲人闲谈PS之十九——PS模块的未来

惯例闲话&#xff1a;约莫5年前&#xff0c;闲人曾经对自己职业专业产生过一丝疑虑&#xff0c;SAP实施人们都说五大模块&#xff08;SD/PP/MM/FI/CO&#xff09;&#xff0c;PS模块的存在感如同天边的浮云&#xff0c;也就国网、中石油、国能等这些国字头企业里才有PS的存在&a…

价值240万的photoshop中文教程

PS抠图方法 一、魔术棒法——最直观的方法  适用范围&#xff1a;图像和背景色色差明显&#xff0c;背景色单一&#xff0c;图像边界清晰。  方法意图&#xff1a;通过删除背景色来获取图像。  方法缺陷&#xff1a;对散乱的毛发没有用。  使用方法&#xff1a;1、点击…

PS教程(个人精心整理,你也可以成为PS高手)

1.用钢笔在背部勾勒一个翅膀的外形&#xff0c; 2.在当前的工作路径转换成路径1&#xff0c;双击工作路径即可。 3.将路径转换成选区&#xff08;Alt回车&#xff09;&#xff0c;复制一层&#xff0c;羽化3像素&#xff0c; 4.填充白色&#xff0c;选择合适的强度使用涂抹工具…

meta-transfomer

导读 设计一个统一的网络来处理各种模态&#xff08;例如自然语言、2D图像、3D点云、音频、视频、时间序列和表格数据&#xff09;是一项极具挑战性的工作。 本文提出了一个名为Meta-Transformer的框架&#xff0c;利用一个冻结的编码器在没有任何成对多模态训练数据的情况下…

基于寄生捕食算法优化的BP神经网络(预测应用) - 附代码

基于寄生捕食算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于寄生捕食算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.寄生捕食优化BP神经网络2.1 BP神经网络参数设置2.2 寄生捕食算法应用 4.测试结果&#xff1a;5…

大连海事大学

目录 分数201920202021初试专业课复试总成绩资料复习规划一轮二轮三轮四轮英语政治数学分数 2019 2020

京东接班人徐雷

来源 &#xff1a;商业史记 文&#xff0f; 张小迁 2021年9月6日&#xff0c;京东零售CEO徐雷晋升为拥有32万员工的京东集团总裁。至此&#xff0c;中国三大电商平台阿里巴巴、京东和拼多多&#xff0c;创始人都开始隐身到幕后&#xff0c;进入垂帘听政模式&#xff0c;前台则…

北大双杰——孔庆东和余杰

孔庆东的新浪博客 http://blog.sina.com.cn/kongqd 北大双杰——孔庆东和余杰的书不错&#xff0c;孔的幽默机智&#xff0c;可以让你笑坏肚子同时能明白点道理&#xff1b;余算是个愤青&#xff0c;批判家&#xff0c;思想很有意思&#xff01; ----------------------------…

Nature封面论文创意被剽窃?UC圣迭戈付向东实名举报中科院研究员抄袭

伊瓢 发自 凹非寺量子位 报道 | 公众号 QbitAI 6月25日的Nature封面&#xff0c;刚发布不到10天&#xff0c;还热乎着呢&#xff0c;居然发现已经被抄袭了&#xff1f; 抄袭者还发了另一大顶级刊物Cell&#xff1f; 今天&#xff0c;一封流传的举报信突然引起了轩然大波&#x…

读论文《大气压等离子体电离波沿介质管传输特性研究》

文章目录 一、研究背景和意义二、研究目的与内容三、电离波概述3.1 电离波与传统的流注放电3.2 电离波传输速度的计算方法 四、放电参数对电离波传输特性的影响4.1 施加电压与电压波形对电离波传输的影响4.1.1 交流高压对电离波的影响4.1.2 脉冲高压对电离波的影响 4.2 气体流量…

电商格局谋定重整-万祥军:李玉庭对话中国经济和信息化

电商格局谋定重整-万祥军&#xff1a;李玉庭对话中国经济和信息化 &#xff08;BT传媒《商业价值》杂志9月刊封面文章&#xff0c;记者郭娟&#xff09;中国经济和信息化网 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 经信研究 国研智库 国情讲坛 万赢信采编&#xff…

量子技术在中国「电子政务外网」的应用 | 报告荐读

来源&#xff1a;《信息安全研究》 导读 | 随着量子技术不断取得突破&#xff0c;特别是以美国、欧洲为代表的西方强国量子技术的不断发展&#xff0c;使得我国电子政务外网原有经典密码保障措施受到严重威胁&#xff0c;必须在实际威胁发生前防患于未然&#xff1b;利用量子保…