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.

[参考译文] CCS/AM3352:CCS 7.1 调试器尝试将使用GCC ARM编译器编译的AM3352引导加载程序加载到错误的内存地址

Guru**** 2581345 points
Other Parts Discussed in Thread: AM3352, AM3359

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/598781/ccs-am3352-ccs-7-1-debugger-attempts-to-load-an-am3352-bootloader-compiled-with-the-gcc-arm-compiler-to-an-incorrect-memory-address

部件号:AM3352
主题中讨论的其他部件: AM3359

工具/软件:Code Composer Studio

使用在7.1 Ubuntu 16.04 LTS下运行的CCS SRAS.RAM 0.0.0016万 尝试在AM3352的Cortex-A8上调试引导加载程序 ,其中应加载引导加载程序并从0x402F0400在“SRAM internal”区域中运行。  0x402FFFFFFF。 bootloader使用 gcc-arm-none-eabi-4_9-2015q3编译器编译。

尝试加载程序时,加载失败,并在控制台中报告以下错误:

CortxA8:输出:**** AM3352_SOM初始化正在进行中..........
CortxA8:输出:**** AM335xOPP == Turbo is in progress (OPP == Turbo正在进行AM335x所有PLL配置)..........
CortxA8:输出:从SYSBOOT[15:14]读取输入时钟:24MHz
CortxA8:输出:****转至旁路...
CortxA8:输出:****已绕过,正在更改值...
CortxA8:输出:****锁定臂PLL
CortxA8:输出:****核心绕过
CortxA8:输出:****现在锁定核心...
CortxA8:输出:****内核锁定
CortxA8:输出:****每个DPLL旁路
CortxA8:输出:****每个DPLL锁定
CortxA8:输出:**** AM335x OPP == Turbo的所有PLL配置已完成........
CortxA8:输出:**** AM3352_SOM初始化已完成******************


CortxA8:在长度0x7ff0的第0页上0x402f0074处写入内存块时出错:(错误-1065 @ 0x3D5A)无法访问设备内存。 验证内存地址是否在有效内存中。 如果错误仍然存在,请确认配置,关闭电源后重启板和/或尝试更可靠的JTAG设置(例如,Lower TCLK)。 (仿真软件包6.0 CortxA8.) 628.1
:文件加载器:验证失败:目标写入0x402F0074
CortxA8:GEL:文件:/home/MR_halfworD/AM3352-SOM-EVB_Bare_metal/Debug/bootloader/bootloader.out:加载失败。 

调试器报告尝试写入从 地址 0x402f0074开始的大小为0x7ff0字节的内存块。 但是,该起始地址和大小与程序中的部分不匹配。 在bootloader ELF文件上运行cG_xml sectti实用程序可确认开始加载地址按 预期为0x402f0400:

~/ti/CG_xml/utils/ofd6x -x bootloader/bootloader.out |~/ti/CG_xml/bin/sectti
正在从stdin读取...

***************
文件报告:bootloader/bootloader.out
****************************************************
名称:大小(十进制)大小(十六进制)类型加载地址运行地址
--------------------------- :----------- -------- -------- --------
rs-速记: 32 0x0.002万代码0x402f0400 0x402f0400
文字: 3.5168万 0x0.896万代码0x402f0420 0x402f0420
数据: 1084 0x0.0043万c数据0x402f8d88 0x402f8d88
bss: 2184 0x0.0888万 UDATA 0x402f9200 0x402f9200
堆栈: 8192 0x0.2万 UDATA 0x402f9a90 0x402f9a90

----------------------------------
按区域类型列出的总计
----------------------------------
未初始化的数据: 1.0376万 0x0.2888万
初始化数据: 1084 0x0.0043万c
代码: 3.52万 0x0.898万 

附件是加载失败中的调试服务器日志文件 。e2e.ti.com/.../4645.debug_5F00_server.log.zip

在调试服务器日志中搜索不正确的加载地址 0x402f0074时,它首先出现在日志的部分中,该部分是关于解析要加载的程序的ELF信息:

0x7FD3469FB700 3203827.00320382亿 4 OFS I:PT_LOAD:
0x7FD3469FB700 3203827.00320382亿 4 OFS D:OFS load Section Added:name:.text
0x7FD34696FB700 3203827.00320382亿 4 OFS D:大小(字节):3.72万或0x9150
0x7FD34.6970032亿 3203.8232032亿4 OFS D:加载位置:0x4069FB2700FS
:2700:0x407F0704F0730074:0730074:0x4FD:0x4F0704F0704FFS:0704:0x407F3384
: 内存页面:0
0x7FD3469FB700 3203827.00320382亿 4 OFS D:文件中的偏移:116或0x74
0x7FD3469FB700 3203827.00320382亿 4 OFS D:OFS加载部分添加:名称:填充
0x7FD3469FB700 3203827.00320382亿 4 OFS D:大小(字节):10444或0x28cc
320cc 3207FD3469FB700 32043469 3204 OFS70.032万 OFS:加载4
:0x7FFD:0x7F0709FD: 运行位置:0x402f91c4
0x7FD3469FB700 3203827.00320382亿 4 OFS D:内存页面:0
0x7FD3469FB700 3203827.00320382亿 4 OFS D:文件中的偏移:0或0x0 

因此,认为问题在于CCS 7.1 调试器错误地读取了要从bootloader.out ELF文件加载的部分的地址。 包含bootloader.out文件的生成目录已附加 。e2e.ti.com/.../bootloader.zip

https://github.com/Chester-Gillon/AM3352-SOM-EVB_bare_metal/blob/b99ab552f96f4cab27094f9e5937e012725eee90/bootloader/targetConfigs/AM3352.ccxml 是2.7094万是尝试5937尝试调试1.2725万调试bootloader.out3352.bootloader.out时使用的目标配置文件。 目标配置使用Cortex-A8和ICEPIN_D上的自定义GEL文件,其中GEL文件位于 https://github.com/Chester-Gillon/AM3352-SOM-EVB_bare_metal/tree/b99ab552f96f4cab27094f9e5937e012725eee90/gel_files 目录2.7094万目录中5937中。1.2725万。

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

    使用在 Ubuntu 16.04 LTS下运行的CCS 7.1 .0.0.0016万 尝试在 AM3352的Cortex-A8上调试引导加载程序,在此应加载引导加载程序并从 0x402F0400在"SRAM internal"区域中运行。  0x402FFFFFFF。 bootloader使用 gcc-arm-none-eabi-4_9-2015q3编译器编译。

    项目开始时使用CCS项目文件和TI ARM 5.2 v比6编译器编译。 在某个时候,该项目被更改为使用CMake生成makefile并使用GCC ARM编译器。

    我将该项目恢复为使用TI ARM 5.2 16.04 Tm6编译器和 运行 在Ubuntu 7.1 LTS下的CCS ELF. 0.0.0016万 编译,然后能够成功下载和调试bootloader.out文件。

     由gcc-arm-none-eabi-4_9-2015q3编译器编译的bootloader是有效的程序,因为如果将生成的二进制MLO文件复制到SD卡,则会由AM3352引导ROM成功运行bootloader。 问题在于  ,CCS 7.1 .0.0.0016万 调试程序无法将gcc-arm-none-eabi-4_9-2015q3编译器生成的ELF bootloader.out文件成功下载到RAM中。

    相同的目标硬件Blackhawk USB560-M仿真器,目标配置文件和GEL文件用于成功下载TI ARM编译器生成的程序,而不成功下载GCC ARM编译器生成的程序。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我可以在AM3359 BeagleBone上再现此内容。 我们需要深入了解符号信息,找出负载地址为0x402F0074的CCS原因。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [QUEOTE USER="Johns (报价用户名)]我可以在 AM3359 BeagleBone上再现此内容。 我们需要深入了解符号信息,找出加载地址为0x402F0074的CCS原因。我使用Ubuntu readelf实用程序查看GCC ARM编译器生成的bootloader.out文件的标题,CCS将尝试开始为其写入内存 在地址 0x402F0074处:

    $ readelf -hls bootloader/bootloader.out
    ELF标题:
    magic:7F 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 00 00
    级: ELF32
    数据: 2的补码,小尾端
    版: 1 (当前)
    OS/ABI: UNIX - System V
    ABI版本: 0
    类型: Exec (可执行文件)
    计算机: ARM
    版本: 0x1
    入口点地址: 0x402f0400
    程序头开始: 52 (字节进入文件)
    节标题的起始位置: 9.776万 (字节到文件)
    标志: 0x500.0402万,版本5 EABI,硬浮点ABI,
    此报头的大小<unknown>:
    52 (字节)程序标头大小: 32 (字节)
    程序头数: 2
    部分标题的大小: 40 (字节)
    节标题数: 21
    节标题字符串表索引:18
    
    节标题:
    [nr]名称 类型 地址 Off Size ES Flg Lk Inf AL
    [0](关闭尺寸ES Flg Lk Inf AL [0]) 空 0万00 0000000万000 0000000亿 0 0 0
    [1].rsstire. 程序 402f4亿 000020 00 AX 0 0 4
    [2].text 程序 402f4.2亿 008960 00 AX 0 0 8
    [3].arm.exidx ARM_EXIDX 402f8d8.0008万 008d8000.0008万 00 Al 2 0 4
    [4].data 程序 402f8d8.8008万 008d8800043c 00 WA 0 8
    [5].bss 注 402f9200 0091c4 000888400.0888万 00 WA 0128
    [6].heap 程序 402f9a900091 0091d0万 00 0 0 16
    [7].stack 注 402f9a900091 0091c400.2万 00 a 0 0 16
    [8].arm.attributes arm_attributes 0万 0091d0 00002f000002f 00 001
    1[9].comment 程序 0万 0091ff 0.007万 01 MS 0 1
    [10].ISR_Vector 程序 0万00 0092700.0009万270 0000502.7亿 00 0 0 16
    [11].debug_info 程序 0万 0092c0 0059df00059df 00 0 0 1
    [12].debug_Abbrev. 程序 0万 00ec9f 0010c2 00 0 0 1
    [13].debug_aranges PROGBITS 0万 00fd610008a8 00 0 0 1
    [14].debug_ranges 程序 0万00 0106090.001万609 0007a860.9万7a8 00 0 0 1
    [15].debug_line 程序 0万00 010db10.001万db1 002e601002e60 00 0 0 1
    [16].debug_str 程序 0万00 013c110.0013万c11 0021151100.2115万 01 MS 0 1
    [17].debug_frame 程序 0万00 015d280.0015万d28 001fe82.8001万fe8 00 0 0 4
    [18].shstrtab STRTAB 0万00 017d100.0017万d10 0000cd00000cd 00 0 0 1
    [19].symtab 符号 0万00 0181280.0018万128 0022801.2800228亿 10. 2.0363万 4
    [20].strtab STRTAB 0万 01a3a80013d8 00 01
    标志的关键字:
    W (写入),A (分配),X (执行),M (合并),S (字符串)
    I (信息),L (链接顺序),G (组),T (TLS),E (排除), X (未知)
    O (需要额外的操作系统处理) o (特定于操作系统),p (特定于处理器)
    
    程序标头:
    类型 Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
    EXIDX 0x008d80 0x402f8d80 0x402f8d80 0x0.0008万 0x0.0008万 R 0x4
    加载 0x0万 0x402f0000 0x402f0000 0x091c4 0x0ba90 RWE 0x8000
    
    段到段映射:
    段段段...
    00 arm.exidx
    01 .rseride.text .arm.exidx .data .bss .stack 

    装入程序头的对齐设置为0x8000 (32 KB),要装入的节的ELF文件偏移的至少15位与装入地址的最不重要的15位匹配。 我认为这是一种优化,它允许ELF加载程序(在本例中为CCS调试程序)尝试将ELF文件中的连续字节数组直接写入程序内存。 ELF文件以一个52字节的标头和两个32字节的程序标头开始,总计52 +(2*32)=116=0x74,它与 CCS调试器尝试写入的地址0x402F0074中最不重要的15位匹配。 因为在AM3352上,地址范围为 0x402F0000。 0x402F03FF已保留且无法写入,这说明了将程序加载到内存中的"对齐优化"失败的原因。

    通过添加选项"-z max-page-size=0x400",GCC链接器已更改,以将加载程序标题的对齐从默认0x8000减少到0x400字节。 通过该更改,CCS 7.1 调试器可以成功地将bootloader.out文件加载到内存中。 添加max-page-size选项不会更改生成的二进制MLO文件,只会在ELF文件中加载Program Header,因为该文件阻止CCS调试器将bootloader.out文件加载到内存中。

    不确定CCS调试器中决定如何将ELF文件内容加载到内存的加载程序是否应不受加载程序标头对齐导致尝试使用无法访问的内存的情况的影响。

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

    对于ELF输出,所有调试程序(不仅仅是CCS调试程序)始终使用ELF程序头将段加载到目标。

    这不是调试器采用的优化。 这在ELF规范中定义。

    如果链接程序给出无效的段表,我们将写入错误的地址。

    在这种情况下,程序头指定

    程序标题:
     键入          Offset  VirtAddr  PhysAddr  FileSiz MemSiz Flg Align
     EXIDX         0x008d80 0x402f8d80 0x402f8d80 0x0.0008万 0x0.0008万 R  0x4
     加载          0x0万 0x402f0000 0x402f0000 0x091c4 0x0ba90 RWE 0x8000

    我们将可装入段从文件偏移0加载到0x402f000,文件大小为0x91c4,memsize 0xba90。

    CCS将永远不会将ELF标头(位于文件偏移0x0处)写入内存,因此CCS将ELF标头的大小添加到文件偏移和加载地址。

    因此,我们将写入从   文件偏移0x74开始的内存地址0x402f0074 (0x91c4-0x74)字节的数据。

    由于此段的内存大小 大于 该段的文件大小,因此我们将内存区域从0x402f91c4填充到0x402fba90。

    据我所见,我们正在执行 ELF 标题中指定的操作。

    我不认为这是CCS错误。

    这 看起来 像是gcc链接程序错误或链接程序使用问题。

    此致,

    雷蒙德   

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

    [QUETE USER="Raymond Pang,]对于ELF输出,所有调试程序(不仅仅是CCS调试程序)都始终使用ELF程序标头将数据段加载到目标。

    这不是调试器采用的优化。 这在ELF规范中定义。[/QUET]感谢您对ELF程序标题的使用方式所做的说明。 我确认IAR嵌入式工作台ARM中的调试器在使用ELF程序头将段加载到目标时的行为方式与CCS调试器相同。

    这 看起来 像是gcc链接 器错误或链接器使用问题。

    随CCS 7.1 提供的gcc-arm-none-eabi-4_9-2015q3链接器的默认最大页大小为0x8000,当查看一些示例Cortex-M和Cortex-A目标的SYS/BIOS程序时,示例页大小中没有覆盖默认脚本。

    现在,要了解GCC ARM链接器的行为,只需为 需要写入内存区域(其中起始地址或大小不与默认最大页大小32 KB对齐)的任何程序设置max-page-size链接器选项。