zyp000 发表于 2012-4-8 20:50:29

请教一下scatter文件

本帖最后由 zyp000 于 2012-4-8 22:58 编辑

初学ARM,请教一下scatter文件。

先求教下加载时域和运行时域。
我的理解如下,不知道对否?
加载时域:就是代码段实际存储的物理位置。所以一个域只能有一个加载地址。
运行时域:代码段认为自己所运行的位置。一个域内不同的段对应不同的运行地址,所以一个域可以有多个运行地址。

再请问下:
LR_ROM1 0x00000000 0x00100000{    ; load region size_region
ER_ROM1 0x00000000 0x00100000{; load address = execution address
   *.o(RESET, +First)                              
   *(InRoot$$Sections)      
   .ANY (+RO)
}
RW_RAM1 0x30000000 0x04000000{; RW data
   main.o(+RO)                     
   .ANY (+RW +ZI)
}
RW_IRAM 0x40000000 0x1000{
   .ANY (+RW +ZI)
}
}
1.*.o(RESET, +First) ;我的源代码只有S3C2440.s和main.c,当把这行改为S3C2440.o(RESET, +First),链接失败,请教下是为什么?
2.*(InRoot$$Sections) ;这行所代表的意思是什么呢?
3.main.o(+RO) ;main是个流水灯程序,加上这行后程序是在SDRAM里面跑的,但是我程序里并没有从Flash搬运代码到SDRAM中的操作,想请问下,是在连接时自动生成这些代码么?

cxg1987 发表于 2012-4-9 15:20:43

前面两个貌似在MDK的帮助里面可以找到,具体忘记了。
第三个,编译器提供一个__main的函数负责装载,装载后跳转回main()函数执行代码;如果你的主函数名不是main()的话,那么你必须自己写代码搬运装载的程序。
注意到启动代码里面有以下几行:
          IMPORT__main
                LDR   R0, =__main
                BX      R0

zyp000 发表于 2012-4-9 16:22:38

cxg1987 发表于 2012-4-9 15:20 static/image/common/back.gif
前面两个貌似在MDK的帮助里面可以找到,具体忘记了。
第三个,编译器提供一个__main的函数负责装载,装载后 ...

也就是说程序中使用了main()函数以后,所有的RO/RW/ZI段,都会被自动装载到scatter文件里所规定的运行时地址处么?
另外,假设我有两个源文件 scr1.o , scr2.o ,它们的运行时是相对独立的,彼此没有依赖关系,那么可否,在scatter文件里为它们规定好不同的运行时地址,然后用MMU,把这两个不同的运行时地址映射到相同的物理地址(SDRAM中)上,然后编写一个常驻SDRAM的代码,用于在scr1.o和scr2.o之间的切换。

McuPlayer 发表于 2012-4-9 16:30:46

*.o(RESET, +First)
是要求RESET段必须在起始位置

zyp000 发表于 2012-4-9 16:38:05

McuPlayer 发表于 2012-4-9 16:30 static/image/common/back.gif
*.o(RESET, +First)
是要求RESET段必须在起始位置

恩,这个我知道,我的疑问是,为什么不能用具体的名字去代替“ * ”,呵呵。

fyboy 发表于 2012-4-9 18:24:26

可以吧,应该是文件名不要变,只要把.c换成.o就行了

dr2001 发表于 2012-4-9 20:05:06

For 1L:
理解基本没问题。具体描述在MDK的编译器手册中有详尽描述,ARM网站上也可以获得相关手册。
1、可以不用*.o,但是文件名要齐全完整,注意大小写。
2、InRoot$$Section是RVCT自动生成的段名,命名规则忘记了,在手册里有写的。
3、搬运问题参考RVCT手册,C运行库的初始化章节。RVCT/MDK会根据Scatter自动插入初始化搬运的代码,甚至支持压缩数据。使用的前提就是调用__main进入main函数。会有搬运,初始化C运行库,堆等一系列操作的。

加载域就是二进制代码在开始运行的初始状态下的内存布局(初始化之前);运行域是完成初始化后,代码和数据的内存布局。(初始化完成,用户代码开始运行之前,可以猛快糙的理解为进入main之前。)
这两个东西的实质,就是链接时,如果用到绝对地址,链接器进行地址分配和地址赋值的依据。初始化代码用加载域的绝对地址;正常用户代码用运行域的绝对地址。

For 3L
正确的初始化结果,就是RO/RW的数据从加载域的地址正确的变换为运行域的地址。注意,这里没说复制,也就是说用MMU搞地址映射也是可以的(MDK默认的初始化代码是复制,但是自己初始化可以不用。)。ZI是初始化代码直接清零,无附加操作。

.o是相对地址文件,没有绝对地址的,不链接不能直接用。对于MMU映射,只要地址对了就没问题。

zyp000 发表于 2012-4-10 19:03:07

dr2001 发表于 2012-4-9 20:05 static/image/common/back.gif
For 1L:
理解基本没问题。具体描述在MDK的编译器手册中有详尽描述,ARM网站上也可以获得相关手册。
1、可 ...

十分感谢啊,我在揣摩揣摩。
页: [1]
查看完整版本: 请教一下scatter文件