Chinaunix

标题: 请教怎样让1G memory在kernel里注册只使用物理的512m-1G部分 [打印本页]

作者: fei1700    时间: 2012-12-27 22:22
标题: 请教怎样让1G memory在kernel里注册只使用物理的512m-1G部分
我碰到的问题是如果uboot传入的参数是mem=512m系统就正常,mem>512m系统会出现随机死机问题,死机是开机系统报库出错,概率大于10%,每次死的不同。但单纯做 视频播放+memory R/W compare test又正常
我想专门注册后半段memory地址来排除ddr的问题,我目前ddr地址是0x80000000-0xc0000000,我想实际使用0xa0000000-0xc0000000的地址让kernel使用,要怎样做呢?
或者大家觉得可能是哪里的问题?
lk 2.6.34,ARM Cortex A9,谢谢大家
作者: 灌水菜鸟    时间: 2012-12-28 10:24
看kernel-parameter.txt,里面有如何使用特定内存区域的boot command line说明。

你这种情况,你这点线索不好说是哪的事,可能是硬件的,也可能是软件的,我感觉软件的可能要大一些。
作者: hanshu830    时间: 2012-12-28 13:58
你需要修改你的 bootloader  加载 kernel的位置 0xa0000000 + 0x8000

bootloader 传给kernel参数的地址  0xa0000000 + 0x100

然后修改

arch/arm/mach-yourmachine/ 中的某个文件包含 MACHINE_START宏的内容

下面是我的机器用的,只做参考
MACHINE_START(SHOWN, "shown")
        .boot_params    = 0x30000100,
        .map_io         = shown_map_io,
        .init_irq       = shown_init_irq,
        .init_machine   = shown_init,
        .timer          = &shown_timer,
MACHINE_END

红色部分修改成你要用的物理地址 0xa0000100

修改arch/arm/mach-yourmachine/Makefile.boot 中的

zreladdr-y      :=0xa0008000
params_phys-y   :=0xa0000100

修改arch/arm/mach-yourmachine/include/mach/memory.h

#define PLAT_PHYS_OFFSET 0xa0000000



可能会有遗漏, 希望对你有帮助。

作者: oscarvei    时间: 2012-12-28 14:26
回复 3# hanshu830


    boot kernel with mem=X@Y
ex:  mem=176m@16m
作者: fei1700    时间: 2012-12-28 16:31
本帖最后由 fei1700 于 2012-12-28 16:36 编辑

回复 4# oscarvei


    我试过mem=176m@16m 这类的uboot参数,系统就起不来了

关于这个,我这板子有人改过arch/arm/kernel/setup.c里的early_mem这个函数,所以不是完全线性map,有额外64m video,额外100多m 特定driver的,额外1m suspend等
作者: fei1700    时间: 2012-12-28 16:33
目前的状况是只要High Total为0,系统就正常
1. 修改mem=XXXm,此时lowmem+vmalloc <768M, 让High Total为0, 系统正常
2. 直接去掉CONFIG_HIGHMEM,系统正常
作者: fei1700    时间: 2012-12-28 16:58
hanshu830 发表于 2012-12-28 13:58
你需要修改你的 bootloader  加载 kernel的位置 0xa0000000 + 0x8000

bootloader 传给kernel参数的地址  ...



谢谢你,目前我没有修改uboot,关于启动参数,我修改内核cmdline,让它使用config里的值。lk修改memory.h这样不行,
或许是要改uboot的加载地址,不过lk不是会rellocate吗,读到哪里会有影响吗
作者: hanshu830    时间: 2012-12-28 17:34
bootloader 的relocation 功能应该是搬移自己的代码段, 使之符合自己的连接脚本中的定义

oscarvei兄的方法,我不太清楚

我认为 kernel 必须要知道自己加载的物理位置, 而且bootloader 也需要把kernel加载到该位置

这样kernel才能把自己的代码段做正确的映射
作者: fei1700    时间: 2012-12-28 18:39
回复 8# hanshu830


    hi,目前我不认为是ddr的问题了,所以不打算修改memory注册后512M,谢谢你的帮助

该问题目前的规避办法是去掉CONFIG_HIGHMEM, 修改VMALLOC_END和减小VMALLOC_OFFSET,尽可能扩大系统内存,并修改IO MAP BASE,也就是要浪费一部分内存了,从c0000000-fd0000000(VMALLOC_END)是976M,比原本768M多了一点。

那么其实问题还是HIGHMEM相关的,2.6.34不知问题在哪,我另一个3.0.8版本的平台就没这个问题,但差别就不是一点了.

那么HIGHMEM问题,要怎么入手来查呢,我只打开了highmem debug这一个
作者: hanshu830    时间: 2012-12-29 11:46
回复 9# fei1700

HIGH_MEM 这一块我不太熟悉。。。 我去查查相关资料


   
作者: hanshu830    时间: 2012-12-31 10:28
回复 9# fei1700

我在论坛里找到关于 VMALLOC 这部分相关介绍的帖子, 也许对你分析问题有帮助。

http://bbs.chinaunix.net/thread-2193269-1-1.html


   
作者: fei1700    时间: 2013-01-03 15:14
本帖最后由 fei1700 于 2013-01-03 15:26 编辑

我这还在看2.6.34 ARM 配置CONFIG_HIGHMEM传vmalloc=256m后系统起不来的问题,起不来跟我们注册memory bank有关吧(我们从512M开始又注册了一个bank,然后碰到了__va(bank->start)和vmalloc_min相等的情况),但这里确实也有问题,
http://git.kernel.org/?p=linux/k ... 3b2b9dc1feec3c47ed9

改动是其中这一个
#ifdef CONFIG_HIGHMEM
-               if (__va(bank->start) > vmalloc_min ||
+               if (__va(bank->start) >= vmalloc_min ||
                    __va(bank->start) < (void *)PAGE_OFFSET)
                        highmem = 1;

我在想系统库崩溃的现象在去掉HIGHMEM就正常的问题,或许跟2.6.34-3.0.8之间的改动有关?谁能给些可能的2.6.34到3.0.8之间的patch让我来试试呢?

作者: frank529    时间: 2013-01-04 17:32
写一个程序不停malloc看是不是内存分配到一定大小后就崩溃。这种问题多半是由于CPU的内存控制器初始化得不对,看看芯片的datasheet,然后去一级boot或者u-boot的low_level_init里面找。
作者: fei1700    时间: 2013-01-08 11:05
回复 13# frank529


    走运了,让我试了一个patch,发现能解决问题,但我还没想明白我这边driver调用bio_flush_dcache_page为什么会在highmem有问题
我这是单核,EMMC EXT4,出现android库崩溃就是走的__do_user_fault

http://article.gmane.org/gmane.linux.ports.arm.kernel/51556
Re: MPCore SMP Linux : should all dcaches be invalidated after handling prefetch abort ?

diff --git a/fs/mpage.c b/fs/mpage.c
index 552b80b..979a4a9 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -51,6 +51,7 @@ static void mpage_end_io_read(struct bio *bio, int err)
                        prefetchw(&bvec->bv_page->flags);

                if (uptodate) {
+                        flush_dcache_page(page);
                        SetPageUptodate(page);
                } else {
                        ClearPageUptodate(page);


谢谢大家帮忙,我再想想原因,那么或许真的是2.6.34配我的driver有问题,3.0.8配我的driver没问题了
作者: fei1700    时间: 2013-01-15 09:42
回复 11# hanshu830


    结一下该贴吧,怎么改贴名呢?后面讨论的都不是注册memory的问题了

这个提交可以解决该问题
http://git.kernel.org/?p=linux/k ... 6bd6084d39e5f70a382

commit ac8456d6f9a3011c824176bd6084d39e5f70a382
Author: Gary King <gking@nvidia.com>
Date:   Thu Sep 9 16:38:05 2010 -0700

    bounce: call flush_dcache_page() after bounce_copy_vec()
   
    I have been seeing problems on Tegra 2 (ARMv7 SMP) systems with HIGHMEM
    enabled on 2.6.35 (plus some patches targetted at 2.6.36 to perform cache
    maintenance lazily), and the root cause appears to be that the mm bouncing
    code is calling flush_dcache_page before it copies the bounce buffer into
    the bio.
   
    The bounced page needs to be flushed after data is copied into it, to
    ensure that architecture implementations can synchronize instruction and
    data caches if necessary.
   
    Signed-off-by: Gary King <gking@nvidia.com>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Russell King <rmk@arm.linux.org.uk>
    Acked-by: Jens Axboe <axboe@kernel.dk>
    Cc: <stable@kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/mm/bounce.c b/mm/bounce.c
index 13b6dad..1481de6 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -116,8 +116,8 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
                 */
                vfrom = page_address(fromvec->bv_page) + tovec->bv_offset;

-               flush_dcache_page(tovec->bv_page);
                bounce_copy_vec(tovec, vfrom);
+               flush_dcache_page(tovec->bv_page);
        }
}





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2