This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM5728:Linux 内存策略

Guru**** 2581345 points
Other Parts Discussed in Thread: AM5728

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/629359/linux-am5728-linux-memory-policies

器件型号:AM5728

工具/软件:Linux

大家好、我正在努力让基于 AM5728的定制板启动、并且我在内核启动过程的早期遇到了一个奇怪的挂起。  我认为这可能与我的 RAM 配置有关。  在启动期间、我的内核打印以下消息、然后无限期挂起:

正在启动内核...
[引用][0.000000]  在物理 CPU 0x0[/quot]上引导 Linux

[0.000000]  Linux 版本4.9.28-geed43d1050 (Tom@tom-ThinkPad-P50s)(gcc 版本6.2.1 20161016 (Linaro GCC 6.2-2016.11))#6 SMP 优先于 Mon OCT 2 10:59:18 EDT 2017

[0.000000]  CPU:ARMv7处理器[412fc0f2]修订版2 (ARMv7)、CR=30c5387d

[0.000000]  CPU:可用的 div 指令:修补分部代码

[0.000000]  CPU:PIPT/VIPT 非混叠数据高速缓存、PIPT 指令高速缓存

[0.0000M]  、共个:FDT:机器模型:Tom 的定制板

[0.000000]  引导控制台[earlycon0]已启用

[0.000000]  EFI:从 FDT 获取 EFI 参数:

[0.000000]  EFI:未找到 UEFI。

[0.000000]  保留存储器:创建了0x000095800000 (大小为56 MIB)的 CMA 存储器池

[  0.000000]、共:保留内存:已初始化节点 ipu2_CMA@95800000、兼容 ID shared-dma-pool

[0.000000]  保留的存储器:创建了0x000099000000的 CMA 存储器池、大小为64 MiB

[  0.00000]、共:保留内存:已初始化节点 dsp1_CMA@99000000、兼容 ID shared-dma-pool

[0.000000]  保留内存:创建了0x00009d000000的 CMA 内存池,大小为32 mib

[  0.00000]、共:保留内存:已初始化节点 ipu1_CMA@9d000000、兼容 ID shared-dma-pool

[0.000000]  保留的存储器:创建了0x00009f000000的 CMA 存储器池、大小为8 mib

[  0.00000]、共:保留内存:已初始化节点 dsp2_CMA@9f000000、兼容 ID shared-dma-pool

[0.000000]  CMA:保留0x000000008e400000处的24 MIB

[0.000000]  内存策略:数据高速缓存 writealloc

数据高速缓存写入后挂起是否表示主系统 RAM 出现问题?  我的主板和 AM5728 EVM 之间的主要区别在于、我只有256MB 的 DDR3 RAM、并且时序不同。  为此、我更新了 u-boot 配置、u-boot 在 RAM 中运行和重新定位时似乎没有问题。  U-boot RAM 读取和写入测试还指示高度一致性。


根据 EVM、内核启动中的下一行应为:
[0.000000]  OMAP4:将0x00000000ffd00000映射到 DRAM 隔离层的 fe600000

这就是我觉得问题可能与内存有关的原因。  此假设是否有效?  如果是什么原因会导致 u-boot 与我的 RAM 和 Linux 不能正常工作?

另一种可能是、由调试线路中 IPU/DSP 给出的地址正在访问它们不可用的存储器空间。  由于我们只有256MB 的 RAM、映射为0x8000000000至0x90000000、并且 DSP/IPU 的这些存储器地址超出了该范围(0x95800000、0x99000000、 0x9d000000、 0x9f000000等)、它们正在尝试访问它们根本无法访问的存储器?

这是完全启动、以防有人感兴趣。  完全解编译的器件树也是如此。

e2e.ti.com/.../0525.putty.log

e2e.ti.com/.../2605.customboard.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Tom、

    根据您共享的信息、我认为 Linux 内核正在尝试访问不可用的内存。 默认的 PSDK 4 (内核4.9)附带2GB DRAM、而您只有256MB DRAM。

    您还可以使用 MW/MD 命令在 u-boot 级测试 DRAM 存储器。

    此致、
    帕维尔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Tom、

    如果您假设在物理现有存储器之外访问 DSP/IPU 的存储器地址、则可能会导致系统崩溃。

    BR
    Tsvetolin Shulev
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的澄清、我按照您的建议使用了 MW/MD 命令(以及重新启用 mtest)、我在 DRAM 中发现了一些潜在的棘手问题。  这些似乎是 U-Boot 在 RAM 中放置命令或其他重要数据的部分(我在 RAM 中找到了 FIT/FDT 命令字符串)。  但是、当您说默认的 PSDK4附带2GB (当然要与 AM57x EVM 匹配)时、内核设置中是否有需要指定 RAM 大小的地方?  因为我注意到、我的系统挂起后接下来应该打印的语句是  

    [引用][0.000000]  OMAP4:将0x00000000ffd00000映射到用于 DRAM 隔离层的 fe600000 [/引用]

    或与我的存储器边界等效的东西。  所以我的理论是我的内核在寻找 一个2GB 的边界并且它在寻找我的256MB 边界,因此它被挂起在可用空间之外。

    作为一种中间带辅助解决方案、我现在已经从我的器件树中移除了 DSP/IPU/违规器件树节点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Tom、

    [引用 user="Tom W">感谢您的澄清、我按照您的建议使用了 MW/MD 命令(以及重新启用 mtest)、我在 DRAM 中发现了一些潜在的棘手问题。  这些似乎是 U-Boot 在 RAM 中放置命令或其他重要数据的部分(我在 RAM 中找到了 FIT/FDT 命令字符串)。  [/报价]

    我建议您先修复 DRAM。 查看以下指针是否有助于测试它:

    我将查看您的另一个问题(关于存储器映射)并返回给您。

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="TOM W">但是当您说默认 PSDK4附带2GB (当然要与 AM57x EVM 匹配)时、内核设置中是否有某处需要指定 RAM 大小?  [/报价]

    在 u-boot 中、确保已更新默认配置为2GB DRAM 的 DMM_LISA_MAP_x 寄存器和 DTS 文件:

    u-boot-2017.01/arch/arm/dts/am57xx-beagle-x15-common.dtsi

    存储器@0{
          DEVICE_TYPE ="存储器";
          REG =<0x0 0x8000000000 0x0 0x8000000000>; //2GB DRAM
       };

    在内核中、您可以将 DTS 文件从2GB 调整为256MB:

    linux-4.9.28/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi

    存储器@0{
          DEVICE_TYPE ="存储器";
          REG =<0x0 0x8000000000 0x0 0x8000000000>;
       };

    另请参阅以下指针、以更好地了解 DRAM 配置:

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Pavel 您好、感谢您的回复。  我已经修改了这两个内存@0节点以适应我的配置(从0x8000000开始为256MB):

    存储器@0{
          DEVICE_TYPE ="存储器";
          REG =<0x0 0x8000000000 0x0 0x10000000>;
       };

    我还修改了保留存储器节点、如下所示:

    保留存储器{
    /删除节点/ ipu2_CMA@95800000;
    /delete-node/dsp1_CMA@99000000;
    /delete-node/ipu1_CMA@9d000000;
    /delete-node/dsp2_CMA@9f000000;

    cmem_block_mem_0:cmem_block_mem@a0000000{
    REG =<0x0 0x88000000 0x0 0x01000000>;
    };

    };

    这样、DSP/IPU 节点就不会被使用(它们在 DT 中也会被禁用)、并且 cmem 块会移动到系统上存在的 RAM 中的空间(并压缩)。

    不幸的是、我没有取得任何结果。  这是我接收的输出:

    正在启动内核...

    [0.000000]在物理 CPU 0x0上引导 Linux
    [0.000000] Linux 版本4.9.28-geed43d1050 (Tom@tom-ThinkPad-P50s)(gcc 版本6.2.1 20161016 (Linaro GCC 6.2-2016.11))#16 SMP 抢占 Wed OCT 4 15:08:57 EDT 2017
    [0.000000] CPU:ARMv7处理器[412fc0f2]修订版2 (ARMv7)、CR=30c5387d
    [0.000000] CPU:可用的 div 指令:修补分部代码
    [0.000000] CPU:PIPT/VIPT 非混叠数据高速缓存、PIPT 指令高速缓存
    [0.0000M]、共个:FDT:机器模型:Tom 的定制板
    [0.000000]引导控制台[earlycon0]已启用
    [0.000000] EFI:从 FDT 获取 EFI 参数:
    [0.000000] EFI:未找到 UEFI。
    [0.000000] CMA:保留0x000000008e400000处的24 MIB
    [0.000000]内存策略:数据高速缓存 writealloc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Tom W"]cmem_block_mem_0:cmem_block_mem@a0000000{
    REG =<0x0 0x88000000 0x0 0x01000000>;
    };[/报价]

    您应该删除此节点,或者至少尝试:

    cmem_block_mem_0:cmem_block_mem@88000000
    REG =<0x0 0x88000000 0x0 0x01000000>;
    };

    [引用用户="Tom W"]

    正在启动内核...

    [0.000000]在物理 CPU 0x0上引导 Linux
    [0.000000] Linux 版本4.9.28-geed43d1050 (Tom@tom-ThinkPad-P50s)(gcc 版本6.2.1 20161016 (Linaro GCC 6.2-2016.11))#16 SMP 抢占 Wed OCT 4 15:08:57 EDT 2017
    [0.000000] CPU:ARMv7处理器[412fc0f2]修订版2 (ARMv7)、CR=30c5387d
    [0.000000] CPU:可用的 div 指令:修补分部代码
    [0.000000] CPU:PIPT/VIPT 非混叠数据高速缓存、PIPT 指令高速缓存
    [0.0000M]、共个:FDT:机器模型:Tom 的定制板
    [0.000000]引导控制台[earlycon0]已启用
    [0.000000] EFI:从 FDT 获取 EFI 参数:
    [0.000000] EFI:未找到 UEFI。
    [0.000000] CMA:保留0x000000008e400000处的24 MIB
    [0.000000]内存策略:数据高速缓存 writealloc

    [/报价]

    您能否检查是否启用了 ARM A15 LPAE 功能? 如果是、请禁用它并重试。

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您还可以添加一些调试打印、以确定引导流程到底停留在哪里

    linux-kernel/arch/arm/mm/MMu.c

    /*
     * page_init()设置页表,初始化区域内存
     *映射并设置零页、坏页和坏页表。
     *
    void __init paging _init (const struct machine_desc *mdesc)

       void *zero_page;

       build_mem_type_table ();  //->内存策略:数据高速缓存 writealloc
       preping_page_table();
       map_lowmem ();
       memblock_set_curry_limit (arm_lowmem_limit);
       dma_recremap();
       EARLY_FIXMAP_SHUTDOWN ();
       devicemaps_init (mdesc);//-> OMAP4:将0x00000000ffd00000映射到用于 DRAM 隔离层的 fe600000
       kmap_init();
       tcm_init();

       TOP_PMD = PMD_OFF_k (0xffffff0000);

       /*分配零页。 *
       zero_page = EARLY_alloc (page_size);

       bootmem_init();

       empty_zero_page = virt_TO_PAGE (zero_page);
       __flush_dcache_page (NULL、empty_zero_page);

     

    首先检查该流程是否退出 build_mem_type_table()函数,然后检查该流程是否位于 devicemaps_init()函数内部。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    另请注意、AM335x SK (Starterkit)附带256MB DDR3内存、您可以检查其器件树文件和 Linux 内核配置以获得256MB 内存映射的正确设置。

    www.ti.com/.../tmdssk3358
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    再次感谢 Pavel、我修复了 cmem_block_mem@a0000000的存储器地址、并将其替换为 cmem_block_mem@88000000。

    我禁用了 LPAE、并在引导过程中比以前进一步(日志已连接)、但我注意到我收到了很多 EXT4文件系统错误。  遗憾的是、我的其他 SD 卡都在使用中、因此我无法确定此 SD 卡是否存在故障。  我还注意到这条线路  

    [引用][0.000000]  OMAP4:将0x8fe00000映射到用于 DRAM 隔离层的 fe600000 [/引用]  

    仍在打印。

    从我所读到的 LPAE 的内容来看、A-15架构似乎是相当必要的。  我不打算超过32位寻址限制、因此我可以看到为什么禁用它是合理的、但我不确定它是否明智。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Tom、

    [报价用户="Tom W"]我禁用了 LPAE,并在引导过程中比以前继续执行(附加日志)[/quot]

    我没有看到任何附加的日志。 您可以再次检查吗?

    [引用用户="Tom W"]

    我还注意到这条线路  

    [0.000000]  OMAP4:将0x8fe00000映射到 DRAM 隔离层的 fe600000

     

    仍在打印。

    [/报价]

    我怀疑0xFE600000是0x8FE00000物理地址的虚拟地址、因此这不是问题。 我将进一步检查。

    [引用 USER="TOM W)]从我所读到的有关 LPAE 的内容中,A-15架构似乎是相当必要的。  我不打算超过32位寻址限制、因此我可以了解为什么禁用它是合理的、但我不确定它是否明智。

    读取 AM572x DM 时、LPAE 似乎仅在您具有超过2GB 的 DRAM 时才需要

    3.1器件比较表

    DDR3存储器控制器(2)

    (2)在统一 L3存储器映射中、SDRAM 空间的最大值为2GB、可用于所有 L3启动器、包括 MPU (MPU、GPU、DSP、IVA、DMA、 等)。 通常、该空间在两个 EMIF 之间交错、以优化存储器性能。 如果系统填充超过2GB 的物理内存、则 MPU 只能通过 ARM V7大型物理地址扩展(LPAE)访问该额外的可寻址空间。


    请注意、默认情况下、从4.4内核开始启用 LPAE。 AM572x PSDK 2.02 (内核4.1)中未启用此功能。 请参阅以下 e2e 线程:

     

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Tom W"]

    我还注意到这条线路  

    [0.000000]  OMAP4:将0x8fe00000映射到 DRAM 隔离层的 fe600000

     

    仍在打印。

    [/报价]

    我确认0xfe600000是虚拟地址、因此这不是问题。 请参见 linux-kernel/arch/arm/mach-omap2/omap4-common.c

    /*用于在 DRAM 路径上实施内存边界*/
    #define OMAP4_DRAM_STOPENE_VA         0xfe600000

    静态 void __iomem * DRAM_SYNC,* SRAM_SYNC;
    静态 phys_addr_t DRAM_SYNC_paddr;

    /*为隔离层实现窃取一页物理内存*/
    void __init omap_barer_reserve_memblock (void)

       DRAM_SYNC_SIZE =对齐(PAGE_SIZE、SZ_1M);
       DRAM_SYNC_paddr = arm_memblock_t窃取(DRAM_SYNC_SIZE、SZ_1M);



    void __init omap_barries_init (void)

       struct map_desc dram_io_desc[1];

       DRAM_IO_desc[0].virtual = OMAP4_DRAM_STOPENE_VA;
       DRAM_IO_desc[0].pfn =__phys_TO_pfn (DRAM_SYNC_paddr);
       DRAM_IO_desc[0].length = DRAM_SYNC_SIZE;
       DRAM_IO_desc[0].type = MT_MEMORY_RW_SO;
       iotable_init (DRAM_IO_desc、array_size (DRAM_IO_desc));
       DRAM_SYNC =(void __iomem *) DRAM_IO_desc[0].virtual;

       PR_INFO ("OMAP4:将%PA 映射到%p 以设置 DRAM 屏障\n"、&DRAM_SYNC_paddr、DRAM_SYNC);

       SoC_MB = OMAP4_MB;


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉、我迟到了回复、我已离开办公室。  以下是您请求的日志:

    e2e.ti.com/.../6557.g3_5F00_linux_5F00_no_5F00_lpae.log

    还感谢您确认来自源的 LPAE 和虚拟地址。   

    我曾假设、经过数月的严格使用以及最小的安全弹出、我可以将我的 EXT4文件系统错误归咎于 SD 卡硬件。  使用另一个 SD 卡可以显著减少这些存储器的数量。

    从日志和我的后续测试中、我发现加载内核模块不成功、我觉得奇怪、因为我已经按照 PSDK4 wiki 编译并安装了这些模块。  但是、我的系统似乎读取了一个无法访问的存储器块、自旋锁和紧急情况。  它尝试跳转到的存储器地址从未相同、我还没有识别测试之间的任何模式。

    [引用][6.859521]  无法处理虚拟地址00004d64的内核寻呼请求

    有几个类似的错误、它尝试跳转到小于页面大小的地址、因此会输出 NULL 指针引用的错误。  之后内核会运行并终止。  这似乎仍然是内存/文件系统错误造成的、但更多的是配置错误、而不是硬件故障。

    e2e.ti.com/.../5355.putty.log

    e2e.ti.com/.../2538.putty1.log

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    进一步挖掘、系统显然不想运行的原因是 EXT4访问会导致内核操作错误、进而导致内核停止进程、从而导致整个系统挂起。  当 systemd 的 init 进程也尝试其生命周期时,也会出现这种情况。  我注意到 CMEM 模块(根据 Wiki 页面、至少部分处理虚拟到物理地址转换系统)未加载:  

    [报价][/报价]

    [3.392048] EXT4-FS (mmcblk0p2):已重新安装。 OPTS:(空)
    正在启动加载内核模块...
    [3.432379] cmemk:不同意符号 MODULE_LO布局 的版本
    [3.44311] cryptdev:对符号 MODULE_LO布局 的版本不同意
    [确定]已创建层用户和会话层。
    [3.452841] gdbserverproxy:不同意 symbol module_Layout 的版本
    [3.473874] uio_module_drv:不同意符号 module_Layout 的版本
    [确定]已到达目标层面。
    [确定]收听 Journal Socket (/dev/log)。
    正在安装 POSIX 消息队列文件系统...
    [确定]正在侦听 udev 控制套接字。
    正在开始创建所需 st 的列表... 当前内核的节点...
    正在启动日记账服务...
    正在安装临时目录...
    [确定]收听/dev/initctl 兼容性命名管道。
    [确定]已开始向控制台目录监视发送密码请求。
    [确定]已到达目标路径。
    [确定]已安装调试文件系统。
    [确定]已挂载 POSIX 消息队列文件系统。
    [确定]已挂载的临时目录。
    [确定]已启动日志服务。
    [确定]已启动设置虚拟控制台。
    [确定]已开始重新装载根和内核文件系统。
    [失败]启动加载内核模块失败。

    我注意到这些模块都是外部模块。  它们来自 PSDK4附带的压缩文件系统(在 filesystems/tisdk-rootfs-image-am57xx-evm.tar.xz 中)。  此外、当通过以下命令编译正常模块时:

    使 arch=arm cross_compile=arm-linux-gnueabihf-模块

    这些模块未编译(附加日志): e2e.ti.com/.../2642.compile.log

    我是否正确地假设这些模块不正确地包含在构建中?  如果有一种方法可以使用我的内核重新编译它们以获得正确的版本号、那么这将是非常好的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="Tom W">您请求的日志如下:

    (请访问站点查看此文件)

    从该日志中,我觉得引导流程卡在 rootfs 中,而不是 Linux 内核中。 您是否可以尝试从 tisdk-rootfs 切换到裸最小 Arago 基础 fs 并检查它是如何到达的?

    {PSDK}/filesystem/arago-base-tisdk-image-am57xx-evm.tar.xz

    [引用 user="Tom W">我假设在经过数月严格的使用以及最小的安全弹出情况下、我可以将我的 EXT4文件系统错误归咎于 SD 卡硬件。  使用另一张 SD 卡可以显著减少这些数据。[/报价]

    您可以尝试使用 EXT3吗? 请注意,默认 SD 卡脚本使用 ext3创建 rootfs:

    {PSDK}/bin/create-sdcard.sh

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="TOM W]当系统的初始化进程也尝试其生命周期时,也会出现这种情况。  我注意到 CMEM 模块(根据 Wiki 页面、至少部分处理虚拟到物理地址转换系统)未加载: 

    [引用 user="Tom W">我注意到这些模块都是外部模块。  它们来自 PSDK4附带的压缩文件系统(在 filesystems/tisdk-rootfs-image-am57xx-evm.tar.xz 中)。  此外、当通过以下命令编译正常模块时:

    源代码位于:

    {PSDK}/board-support/extra-drivers

    有关如何构建和安装这些模块(即 cmem_mod)的信息、请参阅 Toplevel Makefiel ({PSDK}/Makefile)

    processors.wiki.ti.com/.../Processor_Linux_SDK_Top-Level_Makefile

    此致、
    帕维尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    啊哈!  这似乎已经完成了!  一旦我移除了有问题的外部模块(并清除了构建主机上的一些文件权限问题)、我就设法到达了紧急终端、并找到了正确的终端。  非常感谢您的帮助、Pavel!