好吧,最后还是自问自答: 这个问题和ARM的内存管理单元(mmu)、协处理器CP15有关。 ARM为了实现地址重映射,将内存进行分段处理,每段为1MB大小。段还可以根据需要再分为页,页可以为1KB、4KB、64KB大小。这是两级页表。 Mmu的另一个作用就是访问控制。 在mmu.c的初始化程序中有以下程序: MMU_SetMTT(0x00000000,0x03f00000,(int)__ENTRY,RW_CB); //bank0 MMU_SetMTT(0x04000000,0x07f00000,0,RW_NCNB); //bank0 MMU_SetMTT(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1 MMU_SetMTT(0x10000000,0x17f00000,0x10000000,RW_NCNB);//bank2 MMU_SetMTT(0x18000000,0x1ff00000,0x18000000,RW_NCNB);//bank3 //MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CB);//bank4 MMU_SetMTT(0x20000000,0x27f00000,0x20000000,RW_CNB);//bank4 for STRATA Flash MMU_SetMTT(0x28000000,0x2ff00000,0x28000000,RW_NCNB);//bank5 //30f00000->30100000,31000000->30200000 MMU_SetMTT(0x30000000,0x30100000,0x30000000,RW_CB); //bank6-1 MMU_SetMTT(0x30200000,0x33e00000,0x30200000,RW_NCNB);//bank6-2 // MMU_SetMTT(0x33f00000,0x33f00000,0x33f00000,RW_CB); //bank6-3 MMU_SetMTT(0x38000000,0x3ff00000,0x38000000,RW_NCNB);//bank7 MMU_SetMTT(0x40000000,0x47f00000,0x40000000,RW_NCNB);//SFR MMU_SetMTT(0x48000000,0x5af00000,0x48000000,RW_NCNB);//SFR MMU_SetMTT(0x5b000000,0x5b000000,0x5b000000,RW_NCNB);//SFR MMU_SetMTT(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//notused 这里语句MMU_SetMTT()实际上就是在对内存分段处理,因为每个bank为128MB,所以可以分为128段,我没有看到程序里再对段进行分页,所以这里大概就只有到分段为止了。不过这些还和我要解决的问题无关,我要解决问题的关键是MMU_SetMTT()的第三个参数,我将上面涉及到的参数写一下: RW_CB; RW表示定义的段可读可写(这就是访问控制),C表示使用cache,B表示使用写缓冲器 RW_NCNB; RW同上,NC表示不使用cache,NB表示不使用写缓冲器 RW_FAULT; 这个表示定义的段不可读写 其他依次类推。 由于DM9000接的是nGCS4,所以与上面的bank4那段程序有关,它原来的参数是RW_CNB,就是说可读可写,使用cache,不使用写缓冲。将这个参数改为RW_NCNB(可读写,不使用cache,不使用写缓冲)或者RW_NCB(可读写,不使用cache,使用写缓冲)就可以输出正确结果了,总之就是这里不用cache。 当然,至于为何不用cache就可以了,我还是不知道,需要的知识真是太多了。希望对遇到和我有类似问题的人有所帮助。
|