作者descent (「雄辩是银,沉默是金」)
看板ASM
标题Re: [问题] 程式载入记忆体问题
时间Mon May 21 21:33:51 2018
这个东西不是很好说明, 原理大概是这样:
只讨论 c 语言放在 .data section 中的变数。
int i=5;
void f1()
{
}
i 会放在 .data section, 假如在执行档中的位址是 0x100,
但是你放在 flash 中的 0x100 的话, i 就变成唯读的, 当你用
i=10 的时候, 是无法写入的。
该怎麽办?
放到可以读写的记忆体位置, 假设是 0xa100 好了。
那我怎麽作到 a 是 0x100 又是 0xa100 呢?
在 c 语言编译的时候, 必须让 i = 10 改成 (*)0xa100 = 10;
而放在 flash 时, i 要是 0x100。
linker script 就是在做这件事情。
再来就是程式在开始执行之前, 需要把 0x100 的 i 复制到 0xa100 上。
很抱歉说得很模糊, 有程式码来配合会比较容易理解。
https://github.com/descent/stm32f4_prog/blob/master/led/stm32.ld
.data : AT (_etext)
{
_data = .;
*(.data .data.*)
_edata = .;
} > SRAM
https://github.com/descent/stm32f4_prog/blob/master/led/stm32.h
ref: ResetISR
不过不好意思, 没有更简化的程式来帮助你理解, 因为要能正确运作 C,
需要的不只是这段。
而麻烦的事情在於怎麽完成这段程式码, 各个平台有所不同, 这是
cortex m stm32 系列的作法。
而我的作法是 gnu toolchain 的作法, 如果你用不同的开发工具, 细节可能不同,
但基本原理都是一样的。
※ 引述《wei115 (ㄎㄎ)》之铭言:
: 在没有作业系统的装置上(我用的是STM32F104)
: 假使我的程式指令放在只读的ROM上
: 那我在执行时,要怎麽
: 把可读可写的变数和堆叠丢到RAM上?
: 看了一些资料,好像写连结脚本可以解决?
: 但想想不是阿,连结脚本只是指定哪些资料要放在ROM上,哪些资料要放在RAM上
: 他没有实际把资料作搬移的工作
: 开机时会要把函式丢到记忆体上并设定堆叠暂存器(以便函式呼叫)
: 并且要把可读可写的区段搬移到记忆体上
: 所以编译器有加入实际搬移的code?让我在我的程式执行前做好这些工作?
: 有没有相关资料或关键字可供参考,谢谢
--
纸上得来终觉浅,绝知此事要躬行。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 117.19.102.23
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/ASM/M.1526909641.A.A7D.html
1F:推 wei115: 感谢回文,我可能要再消化一下.... 05/22 23:40
2F:推 wei115: linker script我对它功能的理解是他会把那些区段要放在记 05/23 01:03
3F:→ wei115: 忆体中的那个位置和读写属性的「资料」写进目标文件,但 05/23 01:03
4F:→ wei115: 不会实际去做分配,难道其实linker script也会把实际上分 05/23 01:03
5F:→ wei115: 配的指令也把他加入目标文件吗? 05/23 01:03
我以前看的找不到了, 这2篇给你参考:
https://www.crifan.com/detailed_lma_load_memory_address_and_vma_virtual_memory_address/
https://blog.csdn.net/redredbird/article/details/5986035https://blog.csdn.net/redredbird/article/details/5986035
※ 编辑: descent (101.10.66.40), 05/23/2018 20:37:48