[讨论] android /linux如何识别S5pv210 双通道不连续的内存?

Wince.Android   2013-5-28 16:52 楼主
我昨晚移植S5pv210 到android2.3.7 发现变得很慢。
真是很多事情要做啊,
我是双通道接法,每个通道两片内存256M。
DMC0 :0x20000000~0x2FFFFFFF
DMC1:0x40000000~0x4FFFFFFF

这个造成了0x30000000~0x3FFFFFFF 有一个256M 的内存空洞了,
wince下是可以枚举不连续的内存的。
但是linux 和android是否能识别呢?
应该是可以的,强大的linux 是无所不能的。
但是怎么感觉我新的android2.3.7 怎么会这么慢呢?!why?
看看怎么办。
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460

回复评论 (3)

这位哥设置寄存器映射硬件内存连续的方法倒是不错 不过我不相信linux不支持不连续的物理内存接法。


S5PV210有两个独立的内存控制器:DMC0和DMC1,每个控制器又有两个片选:CS0和CS1。它可以支持16bits和32bits的内存。两个控制器对应的地址空间是 DMC0 0x2000_0000 ~ 0x3FFF_FFFF
DMC1 0x4000_0000 ~ 0x7FFF_FFFF 内存控制器的配置寄存器也分为两块, DMC0 0xF000_xxxx DMC1 0xF140_xxxx 这一块主要需要设置的寄存器设置是:MEMCONTROL、MEMCONFIG0、MEMCONFIG1 这些是基本的。然后剩下的就要看你的内存是咋接的了。 我这块开发板用的是4片1Gb x16的内存,两片两片按数据线的高16bits和低16bits组成两组32bits的256M,分别挂载了DMC0的CS0和DMC1的CS1。 然后看一下三个寄存器的相应配置了。
MEMCONTROL里面有个num_chip,这个说白了就是使用了几个CS信号。像我的虽然每个控制器上挂了两块内存,但是他们是按高 16bits和低 16bits组成的32bits挂在CS0上。只用了一个CS0,对于210来说就是一片,所以设置为 0x0 = 1 chip 然后 MEMCONTROL的mem_width,当然就设为 0x2 = 32-bit 了。 其它的mem_type、bl啥的自己看吧,不讲了。
MEMCONFIG0和MEMCONFIG1是一样的,一个设置相应控制器的CS0,一个设置CS1。 MEMCONFIG里面的chip_bank、chip_row、chip_col设置要自己找内存的手册了。这个最好不要设错了,就像我开始把chip_col多设了一根,我写0x21xx_xxxx的值,0x23xx_xxxx的值也会跟着变了(其实内存里面都指向同一个区域了) chip_map的设置在13.2.2 Address Mapping里面讲了,后来试下来Linear和 Interleaved都能跑,只是在内存里面放的位置不一样吧。 chip_base和chip_mask是最让人疑惑的了,我折腾了半天也都是在这。这两个寄存器合起来,可以决定DMC0/DMC1 CS0和CS1下挂着的内存对应哪一段内存地址。我理解的是当你要放问地址0x21xx_xxxx的地址的时候,DMC0会将访问地址的高8bits 0x21和chip_mask求与,要是等于chip_base,他就会使用相应的控制器的相应的片选去读数据。就像假如 DMC0_MEMCONFIG0 chip_base = 0x20 chip_mask=0xf8 DMC0_MEMCONFIG1 chip_base = 0x28 chip_mask=0xf8 当你要访问的地址是 0x22xx_xxxx的时候, (0x22 & 0xf8) == 0x20,所以使用CS0 那要是 0x2exx_xxxx呢? (0x2e & 0xf8)
== 0x28 ,当然使用CS1了。 也就是说CS0对应的是 0x2000_0000 ~ 0x27ff_ffff,128M CS1对应的是 0x2800_0000 ~ 0x28ff_ffff,128M 同样的每个CS下都是256M呢? DMC0_MEMCONFIG0 chip_base = 0x20 chip_mask=0xf0 // 0x2000_0000 ~ 0x2fff_ffff 256M DMC0_MEMCONFIG1 chip_base = 0x30 chip_mask=0xf0 // 0x3000_0000 ~ 0x3fff_ffff 256M DMC0和DMC1配置一样,但是DMC0只能配置为0x2000_0000~0x3fff_ffff的空间,DMC1只能配置为0x4000_0000~0x5fff_ffff的空间。这是DMC的地址空间决定的,我就是在这郁闷了两天。 我的板子上面DMC0和DMC1上都只使用了CS0,然后我的设置就是 DMC0_MEMCONFIG0 chip_base = 0x20 chip_mask=0xf0 // 0x2000_0000 ~ 0x2fff_ffff 256M DMC1_MEMCONFIG0 chip_base = 0x40 chip_mask=0xf0 // 0x4000_0000 ~ 0x4fff_ffff 256M 注意,DMC1只能从0x4000_0000开始。 问题又来了,这样内存地址空间不就不连续了嘛? 后来的解决办法,内存的地址空间不从0x2000_0000开始,从0x3000_0000开始,不就正好接上DMC1的了。只是CONFIG_SYS_SDRAM_BASE和CONFIG_SYS_TEXT_BASE相应的改一下: DMC0_MEMCONFIG0 chip_base = 0x30 chip_mask=0xf0 // 0x3000_0000 ~ 0x3fff_ffff 256M DMC1_MEMCONFIG0 chip_base = 0x40 chip_mask=0xf0 // 0x4000_0000 ~ 0x4fff_ffff 256M
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
点赞  2013-5-28 16:53
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
点赞  2013-5-28 16:53
  1. #ifdef CONFIG_SETUP_MEMORY_TAGS
  2. static void setup_memory_tags (bd_t *bd)
  3. {
  4.         int i;

  5.         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  6.                 params->hdr.tag = ATAG_MEM;
  7.                 params->hdr.size = tag_size (tag_mem32);

  8.                 params->u.mem.start = bd->bi_dram[i].start;
  9.                 params->u.mem.size = bd->bi_dram[i].size;

  10.                 params = tag_next (params);
  11.         }
  12. }
  13. #endif /* CONFIG_SETUP_MEMORY_TAGS */

这个是支持的不连续的物理内存的,2.4 以后的内核都支持不连续的内存了,呵呵,这个不必担心,但是为什么会变慢呢!再检查一下!
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
点赞  2013-5-28 17:27
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复