查看: 2645|回复: 1

从文件角度看Cortex-M开发(5) - 映射文件

[复制链接]
  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3920

    主题

    7538

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39928
    最后登录
    2025-8-20
    发表于 2020-8-31 11:30:38 | 显示全部楼层 |阅读模式
    从文件角度看Cortex-M开发(5) - 映射文件


    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家讲的是嵌入式开发里的map文件。


    第四节课里,痞子衡给大家介绍了第一种output文件-relocatable文件,本文继续给大家讲project生成的第二种output文件-map文件,map文件记录了很多重要的信息,这对于后续调试有很大帮助。


    文件关系:链接文件(.icf) + 工程文件(.ewp) + 可重定向文件(.o/.a) -> 映射文件(.map)


    痞子衡在第四节课可重定向文件(.o/.a)里分析object文件里的symbol list时讲到由于object文件并没有经过链接,所以所有symbol地址信息是无效的(待分配的),而map文件就是所有relocatable文件经过链接器统一链接后生成的记录链接信息的文件,map文件里可以查到所有symbol在存储器中具体分配地址。话不多说,让我们直接开启map文件分析之旅,以第三节课工程文件(.ewp)里demo工程为例。


    一、解析map文件
    在IAR软件选项设置options->Linker->List里选中Generate linker map file,编译链接demo工程可在D:\myProject\bsp\builds\demo\Release\List路径下得到demo.map文件。让我们从头到尾逐一分析里面内容:


    1.1 工程文件信息
    map文件里第一部分信息记录的是工程文件相关信息,包括工程使用的软件版本,工程编译时间,工程文件目录,工程文件生成文件信息。
    1. ###############################################################################
    2. #
    3. # IAR ELF Linker V8.11.2.13589/W32 for ARM                12/Jan/2018  17:37:39
    4. # Copyright 2007-2017 IAR Systems AB.
    5. #
    6. #    Output file  =  D:\myProject\bsp\builds\demo\Release\Exe\demo.elf
    7. #    Map file     =  D:\myProject\bsp\builds\demo\Release\List\demo.map
    8. #    Command line =
    9. #        -f C:\Users\Baoge\AppData\Local\Temp\EW5D86.tmp
    10. #        (D:\myProject\bsp\builds\demo\Release\Obj\main.o
    11. #        D:\myProject\bsp\builds\demo\Release\Obj\reset.o
    12. #        D:\myProject\bsp\builds\demo\Release\Obj\startup.o
    13. #        D:\myProject\bsp\builds\demo\Release\Obj\startup_MKL25Z4.o
    14. #        D:\myProject\bsp\builds\demo\Release\Obj\system_MKL25Z4.o
    15. #        D:\myProject\bsp\builds\demo\Release\Obj\task.o -o
    16. #        D:\myProject\bsp\builds\demo\Release\Exe\demo.elf --map
    17. #        D:\myProject\bsp\builds\demo\Release\List\demo.map --config
    18. #        D:\myProject\bsp\builds\demo/../../linker/iar/KL25Z128xxx4_flash.icf
    19. #        --entry Reset_Handler --inline --vfe --text_out locale)
    20. #
    21. ###############################################################################
    复制代码
    1.2 系统库使用信息
    map文件里第二部分信息记录的是工程系统库使用情况,由于task.c里调用了malloc()、free()等HEAP相关操作的API,所以自然我们在编译链接工程时会使用到HEAP相关系统库,这里告诉我们用的是DLib里的DLMalloc,而DLMalloc有很多种不同的HEAP实现策略,我们可在options->General Options->Library Option 2->Heap selection指定具体策略,由于demo工程选的是Automatic,也就是让IDE自动选择,这里告诉我们最终用的策略是advanced heap。
    1. *******************************************************************************
    2. *** RUNTIME MODEL ATTRIBUTES
    3. ***

    4. CppFlavor       = *
    5. __Heap_Handler  = DLMalloc
    6. __SystemLibrary = DLib
    7. __dlib_version  = 6


    8. *******************************************************************************
    9. *** HEAP SELECTION
    10. ***

    11. The advanced heap was selected because the application calls memory
    12. allocation functions outside of system library functions, and there
    13. are calls to deallocation functions in the application.
    复制代码
    1.3 各object中Section放置信息
    从map文件第三部分开始,就进入非常有用的信息环节了。第一个重要信息就是section放置信息。我们在第四节课可重定向文件(.o/.a)里分析过单个relocatable文件task.o,task.o里各个基本section都有,但是都并没有分配有效地址,而这里列出了所有relocatable文件统一存储和地址分配信息,从这里我们可以看到,链接器在整合各section的时候,都是以object文件为单位的,这意味着同一个object文件里的同一个section里的对象(变量/函数)在存储空间里的位置也是靠在一起的。


    另外一个有意思的信息是在第二节课链接文件(.icf)里,我们一共有四句block放置语句,在这里section也被分成了四个block:A0,P1,P2,P3。IDE给每个block重命名了,这些重命名的信息将会在第六节课可执行文件(.out/.elf)里被提到。
    1. *******************************************************************************
    2. *** PLACEMENT SUMMARY
    3. ***

    4. define block Vectors with alignment = 256 { ro section .intvec };
    5. "A0":  place at start of [0x00000000-0x0001ffff] { block Vectors };
    6. define block CodeRelocate { section .textrw_init };
    7. define block ApplicationFlash { ro, block CodeRelocate };
    8. "P1":  place in [from 0x00000000 to 0x0001ffff] { block ApplicationFlash };
    9. define block CodeRelocateRam { section .textrw };
    10. define block HEAP with size = 1K, alignment = 8 { };
    11. define block ApplicationRam { rw, block CodeRelocateRam, block HEAP };
    12. "P2":  place in [from 0x10002000 to 0x1000ffff] { block ApplicationRam };
    13. define block CSTACK with size = 8K, alignment = 8 { };
    14. "P3":  place in [from 0x10000000 to 0x10001fff] { block CSTACK };
    15. initialize manually with packing = copy, complex ranges { section .data };
    16. initialize manually with packing = copy, complex ranges { section .textrw };

    17.   Section                Kind        Address    Size  Object
    18.   -------                ----        -------    ----  ------
    19. "A0":                                           0x40
    20.   Vectors                         0x00000000    0x40  <Block>
    21.     .intvec              ro code  0x00000000    0x40  startup_MKL25Z4.o [1]
    22.                                 - 0x00000040    0x40

    23. "P1":                                         0x1a3c
    24.   ApplicationFlash                0x00000040  0x1a3c  <Block>
    25.     .noinit              ro code  0x00000040    0x58  reset.o [1]
    26.     .rodata              const    0x00000098     0x4  main.o [1]
    27.     Veneer               ro code  0x0000009c    0x10  - Linker created -
    28.     .text                ro code  0x000000ac    0x20  main.o [1]
    29.     .text                ro code  0x000000cc    0x58  task.o [1]
    30.     .text                ro code  0x00000124  0x16f8  dlmalloc.o [3]
    31.     .text                ro code  0x0000181c    0x50  ABImemset.o [4]
    32.     .text                ro code  0x0000186c    0x5c  ABImemcpy.o [4]
    33.     .text                ro code  0x000018c8     0x8  heaptramp0.o [3]
    34.     .text                ro code  0x000018d0     0xa  abort.o [3]
    35.     .text                ro code  0x000018da     0x2  startup_MKL25Z4.o [1]
    36.     .text                ro code  0x000018dc    0x2c  xgetmemchunk.o [3]
    37.     .text                ro code  0x00001908     0xc  XXexit.o [4]
    38.     .text                ro code  0x00001914    0x90  startup.o [1]
    39.     .text                ro code  0x000019a4     0xc  system_MKL25Z4.o [1]
    40.     .text                ro code  0x000019b0    0x1a  cmain.o [4]
    41.     .text                ro code  0x000019ca     0x2  startup_MKL25Z4.o [1]
    42.     .text                ro code  0x000019cc    0x28  data_init.o [4]
    43.     .text                ro code  0x000019f4     0x8  exit.o [3]
    44.     .text                ro code  0x000019fc     0xa  cexit.o [4]
    45.     .text                ro code  0x00001a06     0x2  startup_MKL25Z4.o [1]
    46.     CodeRelocate                  0x00001a08    0x10  <Block>
    47.       Initializer bytes  const    0x00001a08    0x10  <for CodeRelocateRam-1>
    48.     .data_init                    0x00001a18     0x4  <Block>
    49.       Initializer bytes  const    0x00001a18     0x4  <for .data-1>
    50.     .text                ro code  0x00001a1c     0x2  startup_MKL25Z4.o [1]
    51.     .text                ro code  0x00001a1e     0x2  startup_MKL25Z4.o [1]
    52.     .text                ro code  0x00001a20     0xc  cstartup_M.o [4]
    53.     .text                ro code  0x00001a2c    0x40  zero_init3.o [4]
    54.     .iar.init_table      const    0x00001a6c    0x10  - Linker created -
    55.     .rodata              const    0x00001a7c     0x0  zero_init3.o [4]
    56.                                 - 0x00001a7c  0x1a3c

    57. "P3":                                         0x2000
    58.   CSTACK                          0x10000000  0x2000  <Block>
    59.     CSTACK               uninit   0x10000000  0x2000  <Block tail>
    60.                                 - 0x10002000  0x2000

    61. "P2":                                          0x620
    62.   ApplicationRam                  0x10002000   0x620  <Block>
    63.     CodeRelocateRam               0x10002000    0x10  <Block>
    64.       CodeRelocateRam-1           0x10002000    0x10  <Init block>
    65.         .textrw          inited   0x10002000    0x10  task.o [1]
    66.     .data                         0x10002010     0x4  <Block>
    67.       .data-1                     0x10002010     0x4  <Init block>
    68.         .data            inited   0x10002010     0x4  task.o [1]
    69.     .bss                          0x10002014   0x208  <Block>
    70.       .bss               zero     0x10002014     0x4  task.o [1]
    71.       .bss               zero     0x10002018    0x10  task.o [1]
    72.       .bss               zero     0x10002028    0x18  dlmalloc.o [3]
    73.       .bss               zero     0x10002040   0x1d8  dlmalloc.o [3]
    74.       .bss               zero     0x10002218     0x4  xgetmemchunk.o [3]
    75.     .noinit              uninit   0x1000221c     0x4  task.o [1]
    76.     HEAP                          0x10002220   0x400  <Block>
    77.       HEAP               uninit   0x10002220   0x400  <Block tail>
    78.                                 - 0x10002620   0x620
    复制代码
    1.4 系统初始化表信息
    map文件第四部分列出了经由系统初始化的表,这里只有bss段(即代码中所有仅定义但没有赋初值的全局变量),由于SRAM中数据存有一定不确定性,所以系统必须要在启动时将bss段内所有数据全部清零,以保证程序能正常运行。
    1. *******************************************************************************
    2. *** INIT TABLE
    3. ***

    4.           Address     Size
    5.           -------     ----
    6. Zero (__iar_zero_init3)
    7.     1 destination range, total size 0x208:
    8.           0x10002014  0x208
    复制代码
    1.5 各object文件所占存储资源信息
    map文件第五部分会列出各object文件所占存储资源具体信息,有了这部分信息,我们便知道工程具体是哪个object文件(功能模块)占用资源最多,如果有代码size方面优化的需求,可以选择占用资源较多的object文件里的代码进行针对性地优化。
    1. *******************************************************************************
    2. *** MODULE SUMMARY
    3. ***

    4.     Module             ro code  rw code  ro data  rw data
    5.     ------             -------  -------  -------  -------
    6. D:\myProject\bsp\builds\demo\Release\Obj: [1]
    7.     main.o                  32                 4
    8.     reset.o                 88
    9.     startup.o              144
    10.     startup_MKL25Z4.o       74
    11.     system_MKL25Z4.o        12
    12.     task.o                  88       16       20       28
    13.     -----------------------------------------------------
    14.     Total:                 438       16       24       28

    15. command line: [2]
    16.     -----------------------------------------------------
    17.     Total:

    18. dl6M_tln.a: [3]
    19.     abort.o                 10
    20.     dlmalloc.o           5 880                        496
    21.     exit.o                   8
    22.     heaptramp0.o             8
    23.     xgetmemchunk.o          44                          4
    24.     -----------------------------------------------------
    25.     Total:               5 950                        500

    26. rt6M_tl.a: [4]
    27.     ABImemcpy.o             92
    28.     ABImemset.o             80
    29.     XXexit.o                12
    30.     cexit.o                 10
    31.     cmain.o                 26
    32.     cstartup_M.o            12
    33.     data_init.o             40
    34.     zero_init3.o            64
    35.     -----------------------------------------------------
    36.     Total:                 336

    37.     Linker created          16                16    9 216
    38. ---------------------------------------------------------
    39.     Grand Total:         6 740       16       40    9 744
    复制代码
    1.6 各object具体分配信息
    map文件第六部分记录的是各object文件里的具体对象(变量,函数等)在存储空间里的具体分配,这里的信息对于调试来说非常重要。平时调试时我们除了单步执行、打断点之外,还会配合看内存的实时情况,有时候因为编译器优化的原因,从代码角度看不出逻辑问题(比如我们给变量s_variable0赋值为1),但是内存里(0x10002014)却并没有被更新为1,这时候工程肯定是有问题的,定位到了具体问题,然后我们再考虑解决问题的方法。
    1. *******************************************************************************
    2. *** ENTRY LIST
    3. ***

    4. Entry                      Address   Size  Type      Object
    5. -----                      -------   ----  ----      ------
    6. .bss$Base              0x10002014          --   Gb  - Linker created -
    7. .bss$Limit             0x1000221c          --   Gb  - Linker created -
    8. .data$Base             0x10002010          --   Gb  - Linker created -
    9. .data$Limit            0x10002014          --   Gb  - Linker created -
    10. .data_init$Base        0x00001a18          --   Gb  - Linker created -
    11. .data_init$Limit       0x00001a1c          --   Gb  - Linker created -
    12. .iar.init_table$Base   0x00001a6c          --   Gb  - Linker created -
    13. .iar.init_table$Limit  0x00001a7c          --   Gb  - Linker created -
    14. ?main                   0x000019b1         Code  Gb  cmain.o [4]
    15. ApplicationFlash$Base  0x00000040          --   Gb  - Linker created -
    16. ApplicationFlash$Limit
    17.                         0x00001a7c          --   Gb  - Linker created -
    18. ApplicationRam$Base    0x10002000          --   Gb  - Linker created -
    19. ApplicationRam$Limit   0x10002620          --   Gb  - Linker created -
    20. CSTACK$Base            0x10000000          --   Gb  - Linker created -
    21. CSTACK$Limit           0x10002000          --   Gb  - Linker created -
    22. CodeRelocate$Base      0x00001a08          --   Gb  - Linker created -
    23. CodeRelocate$Limit     0x00001a18          --   Gb  - Linker created -
    24. CodeRelocateRam$Base   0x10002000          --   Gb  - Linker created -
    25. CodeRelocateRam$Limit  0x10002010          --   Gb  - Linker created -
    26. HEAP$Base              0x10002220          --   Gb  - Linker created -
    27. HEAP$Limit             0x10002620          --   Gb  - Linker created -
    28. Region$Table$Base     0x00001a6c          --   Gb  - Linker created -
    29. Region$Table$Limit    0x00001a7c          --   Gb  - Linker created -
    30. Reset_Handler           0x00000041         Code  Gb  reset.o [1]
    31. SystemInit              0x000019a5    0xc  Code  Gb  system_MKL25Z4.o [1]
    32. Vectors$Base           0x00000000          --   Gb  - Linker created -
    33. Vectors$Limit          0x00000040          --   Gb  - Linker created -
    34. __Vectors_End           0x00000040         Data  Gb  startup_MKL25Z4.o [1]
    35. __aeabi_memcpy          0x0000186d         Code  Gb  ABImemcpy.o [4]
    36. __aeabi_memcpy4         0x00001895         Code  Wk  ABImemcpy.o [4]
    37. __aeabi_memset          0x0000181d         Code  Gb  ABImemset.o [4]
    38. __cmain                 0x000019b1         Code  Gb  cmain.o [4]
    39. __data_GetMemChunk      0x000018dd   0x2c  Code  Gb  xgetmemchunk.o [3]
    40. __data_GetMemChunk::start
    41.                         0x10002218    0x4  Data  Lc  xgetmemchunk.o [3]
    42. __exit                  0x00001909         Code  Gb  XXexit.o [4]
    43. __iar_Memset4_word      0x0000183d         Code  Gb  ABImemset.o [4]
    44. __iar_Memset_word       0x00001829         Code  Gb  ABImemset.o [4]
    45. __iar_data_init3        0x000019cd   0x28  Code  Gb  data_init.o [4]
    46. __iar_dlfree            0x00001271  0x5a4  Code  Gb  dlmalloc.o [3]
    47. __iar_dlmalloc          0x00000f77  0x2f6  Code  Gb  dlmalloc.o [3]
    48. __iar_program_start     0x00001a21         Code  Gb  cstartup_M.o [4]
    49. __iar_systems$module {Abs}
    50.                         0x00000001         Data  Gb  command line/config [2]
    51. __iar_zero_init3        0x00001a2d   0x40  Code  Gb  zero_init3.o [4]
    52. __vector_table          0x00000000         Data  Gb  startup_MKL25Z4.o [1]
    53. _call_main              0x000019bd         Code  Gb  cmain.o [4]
    54. _exit                   0x000019fd         Code  Gb  cexit.o [4]
    55. _gm_                    0x10002040  0x1d8  Data  Lc  dlmalloc.o [3]
    56. _main                   0x000019c7         Code  Gb  cmain.o [4]
    57. abort                   0x000018d1    0xa  Code  Gb  abort.o [3]
    58. add_segment             0x00000539  0x208  Code  Lc  dlmalloc.o [3]
    59. exit                    0x000019f5    0x8  Code  Gb  exit.o [3]
    60. free                    0x000018c9    0x8  Code  Gb  heaptramp0.o [3]
    61. heap_task               0x000000db   0x3c  Code  Gb  task.o [1]
    62. init_data_bss           0x00001915   0x54  Code  Gb  startup.o [1]
    63. init_interrupts         0x00001969   0x12  Code  Gb  startup.o [1]
    64. init_mparams            0x00000145   0x2a  Code  Lc  dlmalloc.o [3]
    65. init_top                0x0000016f   0x38  Code  Lc  dlmalloc.o [3]
    66. main                    0x000000ad   0x20  Code  Gb  main.o [1]
    67. mparams                 0x10002028   0x18  Data  Lc  dlmalloc.o [3]
    68. n_variable1             0x1000221c    0x4  Data  Gb  task.o [1]
    69. normal_task             0x000000cd    0xe  Code  Gb  task.o [1]
    70. prepend_alloc           0x000001b5  0x384  Code  Lc  dlmalloc.o [3]
    71. ram_task                0x10002001   0x10  Code  Gb  task.o [1]
    72. s_array                 0x10002018   0x10  Data  Lc  task.o [1]
    73. s_constant              0x00000098    0x4  Data  Gb  main.o [1]
    74. s_variable0             0x10002014    0x4  Data  Lc  task.o [1]
    75. s_variable2             0x10002010    0x4  Data  Lc  task.o [1]
    76. segment_holding         0x00000125   0x20  Code  Lc  dlmalloc.o [3]
    77. sys_alloc               0x00000749  0x16c  Code  Lc  dlmalloc.o [3]
    78. sys_trim                0x000008b5   0x6a  Code  Lc  dlmalloc.o [3]
    79. tmalloc_large           0x00000931  0x3fe  Code  Lc  dlmalloc.o [3]
    80. tmalloc_small           0x00000d35  0x242  Code  Lc  dlmalloc.o [3]

    81. [1] = D:\myProject\bsp\builds\demo\Release\Obj
    82. [2] = command line
    83. [3] = dl6M_tln.a
    84. [4] = rt6M_tl.a
    复制代码
    1.7 image占用存储资源信息
    map文件第七部分会给出整个工程占用存储资源情况的总结,这里我们可以看到工程占用ROM资源6780bytes,RAM资源9760bytes,所以我们在选择芯片时必须保证ROM(FLASH),RAM要大于工程所需。
    1. 6 740 bytes of readonly  code memory
    2.      16 bytes of readwrite code memory
    3.      40 bytes of readonly  data memory
    4.   9 744 bytes of readwrite data memory
    复制代码
    二、代码对象与section的关系
    痞子衡在第二节课链接文件(.icf)里的讲过section的概念,并且列出了IAR系统里默认的各section的含义。经过上面对map文件的分析,现在让我们直接用demo工程里的main.c和task.c源文件来实例分析section:
    1.png





    qiandao qiandao
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2021-7-5 15:45
  • 签到天数: 664 天

    连续签到: 1 天

    [LV.9]以坛为家II

    42

    主题

    1594

    帖子

    19

    金牌会员

    Rank: 6Rank: 6

    积分
    5626
    最后登录
    2021-12-22
    发表于 2020-8-31 16:49:00 | 显示全部楼层
    报告 管管:
    第四节课  似乎没有啊?  请费心?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-21 07:32 , Processed in 0.090682 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表