在做底层开发的时候,我们经常会关注到内存映射的问题,今天我们讨论的就是STMP3770内存映射方面话题,并且会结合.map文档一起来看看。
首先,我们来看一张STMP3770的内存映射图,如下
从图上可以看到,STMP3770是32位的SoC,内存映射地址总共是4G;最低的512KB是On-Chip SRAM,最高的64KB是On-Chip ROM; 0x8000000-0x800FFFFF是外设地址空间。系统刚开机,会直接跳到On-Chip ROM,完成各种基本的硬件初始化。
下面,我们一起来看看编译器产生的.map文件的组成,
最开头的部分,是 编译器的版本/Link日期/Host OS
Link Date: Sat Aug 08 11:32:59 2015
Host OS: GHS_WIN32
Version: ELXR 4.0 (c) 1998-2003 Green Hills Software Build: Nov 8 2005
接下来,是 Image Summary,包含各个section起始地址和大小
Section Base Size(hex) Size(dec) SecOffs
.ocram.cbrw.start 00000000 00000000 0 0000480
.vectors 00000000 00000400 1024 0000480
.ocram.pagetables 00000400 00001000 4096 0000880
再下面,是 Module Summary,各个Module包含的section及其起始地址和大小
Origin+Size Section Module
000e7a04+000074 .text crt0.o
00114ca8+000204 .text ui_task.o
00001400+00002c .data ui_task.o
00002e60+003090 .bss ui_task.o
再接着,是 Global Symbols (sorted numerically):以地址高低为序,列出不同地址对应的Symbols(Symbols包括 变量,函数,标志等)
.vectors 00000004 undef_handler
.vectors 00000008 swi_handler
.vectors 0000000c prefetch_handler
.vectors 00000010 data_handler
.vectors 00000014 reserve_handler
.vectors 00000018 irq_handler
.vectors 0000001c fiq_handler
。。。
.data 00001400 ui_name
.data 00001404 ui_timer_name
.data 00001414 g_BitmapCache
.data 0000142c g_FontCache32px
.data 00001444 g_FontCache13px。。。
.ocram.bss 00002e48 g_pAsfPrivData
.bss 00002e60 g_bUIInitFlag
.bss 00002e64 g_CacheTempResourceIds
.bss 00002e68 g_CacheTempHandle
.bss 00002e6c g_tx_queue_ui
.bss 00002ea4 g_ui_thread
.bss 00002f40 g_u32UiStack
。。。
.ocram.rodata 000285ac g_wNumMedia
.ocram.rodata 000285b0 g_fsDriveAssociations
.ocram.text 000285b8 ddi_icoll_RegisterIrqHandler
.ocram.text 00028616 ddi_icoll_RegisterFiqHandler
.syscall 00033dd8 __dotsyscall
.interfunc 00033ddc __ghsThumbBLR6
.interfunc 00033dde __ghsThumbBLR7
。。。
.fixaddr 00033de8 __ghsbegin_fixaddr
.fixaddr 00033e38 __ghsend_fixaddr
.fixtype 00033e38 __ghsbegin_fixtype
.ocram.cbrw.end 00033e4c __ghsbegin_ocram_cbrw_end
.ocram.ncnb.start 00034000 __ghsbegin_ocram_ncnb_start
.ocram.data.ncnb 00034000 hw_uartapp_DmaRxDesc
.ocram.data.ncnb 0003402c hw_uartapp_DmaTxDesc
。。。
.bss.ncnb 00034f44 dma_transfer
.bss.ncnb 00034f54 slave_dma_transfer
.ocram.ncnb.end 00034f64 __ghsbegin_ocram_ncnb_end
。。。
.init.text 000e7a04 _start
.init.text 000e7a0c _start_T
.init.text 000e7a78 main
.init.text 000e7a88 tx_application_define
.init.text 000e7a9c setup_irq_subsystem
。。。
.pageable.32.text 00136d36 cmi_dai_GetStorMediaType
.pageable.32.text 00136d82 cmi_dai_IsRamlistHandle
.pageable.32.text 00136d9e cmi_dai_IsMediaHandleValid
最后, 是 Global Cross Reference:函数/变量在不同obj之间相互呼叫/引用的关系(待验证确认)
Bt.o和被其他obj交叉呼叫引用的位置,例子如下(bt.o的函数有被其他obj交叉引用如下,后面的数字代表位置,每一个数字累加一次)
Bt bt.o 12990c 12a038 12a360 12a668 12a6b4
12a98c 12acbc 12c5d4 12d374 12d4e8
evt.o 115bc0 115f64 116298 1166d4 11708c
1173d8 1176b4 117abc 117dd8 1189fc
11975c 119af0 119f70 11a314 11a618
11a990 11acc0 11b04c 11c160 11c500
11d708 11dacc
sys.o 11e574 11ecb4
leds.o 11f3ec
dec.o 125ffc
bcode.o 126e90 127238 127564 127bdc 127f44
1282c4 1285a8 1291a0
updBtFw.o 12dbe0
cdcfilter.o 133cd4
btTestMode.o 134070
函数InitManyKeys在bt.o和bcode.o定义和被呼叫的位置,例子如下(InitManyKeys()被bt.o定义和引用的次数为6次,被bcode.o引用的次数为1次)
InitManyKeys__3CBtFv bt.o 129262 129458 129fb4 12a08c 12a11e 12a1dc
bcode.o 127e0e
下面,我们把Image Summary部分所有内容列出来,如下,大家可以对照上面的memory map表格,看看不同的section在4G空间的哪个位置
Image Summary
Section Base Size(hex) Size(dec) SecOffs
.ocram.cbrw.start 00000000 00000000 0 0000480
.vectors 00000000 00000400 1024 0000480
.ocram.pagetables 00000400 00001000 4096 0000880
.multi.debugger.tables 00001400 00000000 0 0000880
.ocram.data 00001400 00000000 0 0000880
.data 00001400 00001a50 6736 0000880
.ocram.bss 00002e50 00000004 4 00022d0
.bss 00002e60 000247d8 149464 00022dc
.sdram.bss 00027638 00000000 0 00022dc
.ocram.free_mem 00027638 00000800 2048 00022dc
.stack 00027e38 00000400 1024 00022dc
.free_mem 00028238 00000004 4 00022dc
.heap 0002823c 00000004 4 00022dc
.ocram.rodata 00028240 00000378 888 00022dc
.ocram.text 000285b8 0000b820 47136 0002654
.syscall 00033dd8 00000004 4 000de74
.intercall 00033ddc 00000000 0 000de78
.interfunc 00033ddc 0000000a 10 000de78
.fixaddr 00033de8 00000050 80 000de84
.fixtype 00033e38 00000014 20 000ded4
.ocram.cbrw.end 00033e4c 00000000 0 000dee8
.ocram.ncnb.start 00034000 00000000 0 000e09c
.ocram.data.ncnb 00034000 00000954 2388 000e09c
.data.ncnb 00034954 00000000 0 000e09c
.ocram.bss.ncnb 00034960 000003e0 992 000e0a8
.bss.ncnb 00034d40 00000224 548 000e0a8
.ocram.ncnb.end 00034f64 00000000 0 000e0a8
.vmi.ocram.paging.area.start 00035000 0004b000 307200 000e144
.vmi.ocram.paging.area.end 00080000 00000000 0 000e144
.paging_init_memory_start 000e7000 00000000 0 000e144
.init.text 000e7000 0001364a 79434 000e144
.init.rodata 000fa64c 00000fd4 4052 0021790
.init.data 000fb620 00000000 0 0022764
.init.bss 000fb620 0000004c 76 0022764
.secinfo 000fb66c 0000006c 108 0022764
.paging_init_memory_end 000fb6d8 00000927 2343 00227d0
.pageable.start 00100000 00000000 0 00227d0
.vmi.pageable.1.rotextdata.start 00100000 00000000 0 00227d0
.pageable.1.text 00100000 00000000 0 00227d0
.pageable.1.rodata 00100000 00000000 0 00227d0
.vmi.pageable.1.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.2.rotextdata.start 00100000 00000000 0 00227d0
.pageable.2.text 00100000 00000000 0 00227d0
.pageable.2.rodata 00100000 00000000 0 00227d0
.vmi.pageable.2.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.3.rotextdata.start 00100000 00000000 0 00227d0
.pageable.3.text 00100000 00000000 0 00227d0
.pageable.3.rodata 00100000 00000000 0 00227d0
.vmi.pageable.3.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.4.rotextdata.start 00100000 00000000 0 00227d0
.pageable.4.text 00100000 00000000 0 00227d0
.pageable.4.rodata 00100000 00000000 0 00227d0
.vmi.pageable.4.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.5.rotextdata.start 00100000 00000000 0 00227d0
.pageable.5.text 00100000 00000000 0 00227d0
.pageable.5.rodata 00100000 00000000 0 00227d0
.vmi.pageable.5.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.6.rotextdata.start 00100000 00000000 0 00227d0
.pageable.6.text 00100000 00000000 0 00227d0
.pageable.6.rodata 00100000 00000000 0 00227d0
.vmi.pageable.6.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.7.rotextdata.start 00100000 00000000 0 00227d0
.pageable.7.text 00100000 00000000 0 00227d0
.pageable.7.rodata 00100000 00000000 0 00227d0
.vmi.pageable.7.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.8.rotextdata.start 00100000 00000000 0 00227d0
.pageable.8.text 00100000 00000000 0 00227d0
.pageable.8.rodata 00100000 00000000 0 00227d0
.vmi.pageable.8.rotextdata.end 00100000 00000000 0 00227d0
.vmi.pageable.9.rotextdata.start 00100000 00000000 0 00227d0
.pageable.9.text 00100000 00000038 56 00227d0
.pageable.9.rodata 00100038 00000000 0 0022808
.vmi.pageable.9.rotextdata.end 00100038 00000000 0 0022808
.vmi.pageable.10.rotextdata.start 00100038 00000000 0 0022808
.pageable.10.text 00100038 00001f3c 7996 0022808
.pageable.10.rodata 00101f74 00000000 0 0024744
.vmi.pageable.10.rotextdata.end 00101f74 00000000 0 0024744
.vmi.pageable.11.rotextdata.start 00102000 00000000 0 00247d0
.pageable.11.text 00102000 00000000 0 00247d0
.pageable.11.rodata 00102000 00000000 0 00247d0
.vmi.pageable.11.rotextdata.end 00102000 00000000 0 00247d0
.vmi.pageable.12.rotextdata.start 00102000 00000000 0 00247d0
.pageable.12.text 00102000 00002000 8192 00247d0
.pageable.12.rodata 00104000 00000000 0 00267d0
.vmi.pageable.12.rotextdata.end 00104000 00000000 0 00267d0
.vmi.pageable.13.rotextdata.start 00104000 00000000 0 00267d0
.pageable.13.text 00104000 00001220 4640 00267d0
.pageable.13.rodata 00105220 00000000 0 00279f0
.vmi.pageable.13.rotextdata.end 00105220 00000000 0 00279f0
.vmi.pageable.14.rotextdata.start 00106000 00000000 0 00279f0
.pageable.14.text 00106000 000005c4 1476 00279f0
.pageable.14.rodata 001065c4 00000000 0 0027fb4
.vmi.pageable.14.rotextdata.end 001065c4 00000000 0 0027fb4
.vmi.pageable.15.rotextdata.start 00107000 00000000 0 0027fb4
.pageable.15.text 00107000 00001548 5448 0027fb4
.pageable.15.rodata 00108548 00000000 0 00294fc
.vmi.pageable.15.rotextdata.end 00108548 00000000 0 00294fc
.vmi.pageable.16.rotextdata.start 00109000 00000000 0 00294fc
.pageable.16.text 00109000 00000000 0 00294fc
.pageable.16.rodata 00109000 00000000 0 00294fc
.vmi.pageable.16.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.17.rotextdata.start 00109000 00000000 0 00294fc
.pageable.17.text 00109000 00000000 0 00294fc
.pageable.17.rodata 00109000 00000000 0 00294fc
.vmi.pageable.17.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.18.rotextdata.start 00109000 00000000 0 00294fc
.pageable.18.text 00109000 00000000 0 00294fc
.pageable.18.rodata 00109000 00000000 0 00294fc
.vmi.pageable.18.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.19.rotextdata.start 00109000 00000000 0 00294fc
.pageable.19.text 00109000 00000000 0 00294fc
.pageable.19.rodata 00109000 00000000 0 00294fc
.vmi.pageable.19.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.20.rotextdata.start 00109000 00000000 0 00294fc
.pageable.20.text 00109000 00000000 0 00294fc
.pageable.20.rodata 00109000 00000000 0 00294fc
.vmi.pageable.20.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.21.rotextdata.start 00109000 00000000 0 00294fc
.pageable.21.text 00109000 00000000 0 00294fc
.pageable.21.rodata 00109000 00000000 0 00294fc
.vmi.pageable.21.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.22.rotextdata.start 00109000 00000000 0 00294fc
.pageable.22.text 00109000 00000000 0 00294fc
.pageable.22.rodata 00109000 00000000 0 00294fc
.vmi.pageable.22.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.23.rotextdata.start 00109000 00000000 0 00294fc
.pageable.23.text 00109000 00000000 0 00294fc
.pageable.23.rodata 00109000 00000000 0 00294fc
.vmi.pageable.23.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.24.rotextdata.start 00109000 00000000 0 00294fc
.pageable.24.text 00109000 00000000 0 00294fc
.pageable.24.rodata 00109000 00000000 0 00294fc
.vmi.pageable.24.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.25.rotextdata.start 00109000 00000000 0 00294fc
.pageable.25.text 00109000 00000000 0 00294fc
.pageable.25.rodata 00109000 00000000 0 00294fc
.vmi.pageable.25.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.26.rotextdata.start 00109000 00000000 0 00294fc
.pageable.26.text 00109000 00000000 0 00294fc
.pageable.26.rodata 00109000 00000000 0 00294fc
.vmi.pageable.26.rotextdata.end 00109000 00000000 0 00294fc
.vmi.pageable.27.rotextdata.start 00109000 00000000 0 00294fc
.pageable.27.text 00109000 00000a34 2612 00294fc
.pageable.27.rodata 00109a34 00000000 0 0029f30
.vmi.pageable.27.rotextdata.end 00109a34 00000000 0 0029f30
.vmi.pageable.28.rotextdata.start 0010a000 00000000 0 0029f30
.pageable.28.text 0010a000 00000474 1140 0029f30
.pageable.28.rodata 0010a474 00000000 0 002a3a4
.vmi.pageable.28.rotextdata.end 0010a474 00000000 0 002a3a4
.vmi.pageable.29.rotextdata.start 0010b000 00000000 0 002a3a4
.pageable.29.text 0010b000 00000000 0 002a3a4
.pageable.29.rodata 0010b000 00000000 0 002a3a4
.vmi.pageable.29.rotextdata.end 0010b000 00000000 0 002a3a4
.vmi.pageable.30.rotextdata.start 0010b000 00000000 0 002a3a4
.pageable.30.text 0010b000 00000000 0 002a3a4
.pageable.30.rodata 0010b000 00000000 0 002a3a4
.vmi.pageable.30.rotextdata.end 0010b000 00000000 0 002a3a4
.vmi.pageable.31.rotextdata.start 0010b000 00000000 0 002a3a4
.pageable.31.text 0010b000 00000000 0 002a3a4
.pageable.31.rodata 0010b000 00000000 0 002a3a4
.vmi.pageable.31.rotextdata.end 0010b000 00000000 0 002a3a4
.vmi.pageable.32.rotextdata.start 0010b000 00000000 0 002a3a4
.pageable.32.text 0010b000 00050040 327744 002a3a4
.pageable.32.rodata 0015b040 0002f140 192832 007a3e4
.vmi.pageable.32.rotextdata.end 0018a180 00000000 0 00a9524
.pageable.test1 0018b000 00000000 0 00a9524
.ocram.pageable.test1 0018b000 00000000 0 00a9524
.pageable.test2 0018b000 00000000 0 00a9524
.ocram.pageable.test2 0018b000 00000000 0 00a9524
.pageable.test3 0018b000 00000000 0 00a9524
.ocram.pageable.test3 0018b000 00000000 0 00a9524
.pageable.test4 0018b000 00000000 0 00a9524
.ocram.pageable.test4 0018b000 00000000 0 00a9524
.pageable.end 0018b000 00000000 0 00a9524
.sdram.debugmem.start 40000000 00000000 0 00a9524
.sdram.no_pagetables 40000000 00000000 0 00a9524
.sdram.debugmem.end 40000000 00000000 0 00a9524
.sdram.data 40000000 00000000 0 00a9524
下面,我们举例解析module summay部分的内容
1. .text: 代码段,存放在ROM区
.data: 已初始数据段,存放在RAM区
.bss:未初始数据段,存放在RAM区
Origin+Size Section Module
00114ca8+000204 .text ui_task.o
00001400+00002c .data ui_task.o
00002e60+003090 .bss ui_task.o
2. .text: 代码段,存放在ROM区
.rodata: 只读数据段,存放在ROM区(const修饰的变量存放在rodata段)
.bss:未初始数据段,存放在RAM区
Origin+Size Section Module
00114fd0+0008c0 .text gpio.o
0015ace4+00004c .rodata gpio.o
00006118+000001 .bss gpio.o
3. .bss:未初始数据段,存放在RAM区
.ocram.text: 代码段,指定放在RAM区(代码定义如下 #pragma ghs section text=".ocram.text")
.init.text: 代码段,指定放在RAM的init区段,代码定义如下
__INIT_TEXT void basic_os_init(void *threadx_avail_mem)
{}
#define __INIT_TEXT __attribute__((section(".init.text"))
Origin+Size Section Module
00015570+000004 .bss basic_os_init.o
000333a0+00000a .ocram.text basic_os_init.o
000f9cf0+000070 .init.text basic_os_init.o
4. .sdram.bss:未初始数据段,指定放在RAM区
.sdram.text:代码段,指定放在ROM区
.sdram.rodata:只读数据段,指定放在ROM区
Origin+Size Section Module
00002e48+000004 .sdram.bss cmi_metadata_asf_parser.o
0015aa8c+00001c .sdram.text cmi_metadata_asf_parser.o
00189bb4+000020 .sdram.rodata cmi_metadata_asf_parser.o
如何确认不同的section是在RAM还是ROM
首先,去map file的”Image Summay”查询是否有这个section的关键词
如,section ”.text”,在”Image Summay”中无法查到,则其位于ROM中。
如, “.init.text”,在”Image Summay”中可以查到如下信息,
" .init.text 000e7000 0001364a 79434 000e144"
然后,查询”Figure 2 Physical Memory Map”,确定地址”000e7000”位于RAM区
小结
一般二进制可执行文件包含以下部分
text段
text段存放代码,一般保存在ROM区域
也可以强制指定某些代码至RAM区域,如.ocram.text段
data段
data段存放初始化的数据,保存在RAM区域
rodata段
rodata段存放只读数据,一般保存在ROM区域
const修饰词指定的变量保存在rodata段
也可以强制指定只读代码保存至RAM区域,如.ocram.rodata段
bss段
bss段存放未被初始化的数据,保存在RAM区域
扩展知识
系统刚开机,一般都是跳到0x00地址开始执行的,如何通过连接器将代码的起始地址设为0x00?请参考下面的Make file
objs := head.o init.o main.o interrupt.o
KernelSched.bin: $(objs)
arm-none-linux-gnueabi-ld -Ttext 0x00000000 -o KernelSched_elf $^
arm-none-linux-gnueabi-objcopy -O binary -S KernelSched_elf $@
arm-none-linux-gnueabi-objdump -D -m arm KernelSched_elf > KernelSched.dis
%.o:%.c
arm-none-linux-gnueabi-gcc -Wall -c -o $@ $<
%.o:%.S
arm-none-linux-gnueabi-gcc -Wall -c -o $@ $<
clean:
rm -f KernelSched.bin KernelSched_elf KernelSched.dis *.o
Reference
STMP3770_Datasheet_v1.10.pdf
text, data and bss: Code and Data Size Explained
ad162-cpucodeoutputdebug
osdramDS3070playerplayer.map
https://github.com/GuangweiJiang/diy_kernel/blob/master/01_TaskSwitch/Makefile