Linux kernel 写入物理内存地址的数据发生意外更改

Linux kernel 写入物理内存地址的数据发生意外更改,linux-kernel,mips32,ioremap,Linux Kernel,Mips32,Ioremap,平台为MIPS,内核为Linux2.6.31 首先,在64M的总RAM中,我保留了8M的RAM区域,所以内核只使用56M的RAM区域。 其次,我使用ioremap()函数将物理地址转换为内核中的虚拟地址,然后写入数据。像这样: void *virt_addr = (void *)ioremap(0x83800000,0x800000);//0x83800000 is the start physical address of 8M memset_io(virt_addr,0,0x800000);

平台为MIPS,内核为Linux2.6.31

首先,在64M的总RAM中,我保留了8M的RAM区域,所以内核只使用56M的RAM区域。 其次,我使用
ioremap()
函数将物理地址转换为内核中的虚拟地址,然后写入数据。像这样:

void *virt_addr = (void *)ioremap(0x83800000,0x800000);//0x83800000 is the start physical address of 8M
memset_io(virt_addr,0,0x800000);
memcpy_toio(virt_addr,buf,0x800000);
iounmap(virt_addr);
然后我读取uboot中的数据:保持电源,重新启动系统,然后输入uboot。Uboot使用物理地址,因此我从开始读取数据 在0x83800000。问题在于:在0x83800000(0M)处,一个字节的数据错误;在0x83c00000(4M)处,一个字节的数据错误;在0x84000000(8M)处,一个字节的数据错误。但是所有其他的数据都是正确的,和buf一样!!
真奇怪!!我不知道原因,谁能帮我?谢谢……

具体一点,什么叫“错”?给出具体的价值观。这些值总是一样的?谢谢!在uboot中,如果我这样做的话,这些值总是相同的:char temp[1];memcpy(临时,(无效*)0x83800000);printf(“%p\n”,temp[0]),printf结果总是“0000000e”,如果printf(“%c\n”,temp[0]),结果是混乱的代码…看起来memcpy_toio函数没有将数据写入0x83800000和其他两个地址…谢谢!在uboot中,如果我这样做的话,这些值总是相同的:char temp[1];memcpy(临时,(无效*)0x83800000);printf(“%p\n”,temp[0]),printf结果总是“0000000e”,如果printf(“%c\n”,temp[0]),结果是混乱的代码……看起来memcpy_toio函数没有将数据写入0x83800000和其他两个地址…@Alex HoppusFirst,使用带有单个字节的“%p”是没有意义的;这仅适用于指针,“%c”仅适用于可打印字符。其次,0x84000000超出了您所说的800万美元,那么您为什么对其价值有任何期望呢。第三,memcpy有3个参数,您只显示了2个。然而,如果你是正确的,每个位置的1个字节实际上都被更改了,我想知道引导加载程序的早期执行部分是否有尝试通过以4M的间隔插入任意值并尝试读回它们来发现可用的RAM区域。谢谢……我今天找到了原因。在uboot中,系统将检查RAM大小:uint8_t*p=(uint8_t*)a0000000,pat=0x77;int i*p=pat;对于(i=1;i++){*(p+i*4*1024*1024)=(uint8_t)(i);if(*p!=pat){break;}