Re: [问题] 程式加载内存问题

楼主: descent (“雄辩是银,沉默是金”)   2018-05-21 21:33:51
这个东西不是很好说明, 原理大概是这样:
只讨论 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?让我在我的程式执行前做好这些工作?
: 有没有相关资料或关键字可供参考,谢谢
作者: wei115 (ㄎㄎ)   2018-05-22 23:40:00
感谢回文,我可能要再消化一下....linker script我对它功能的理解是他会把那些区段要放在内存中的那个位置和读写属性的“资料”写进目标文件,但不会实际去做分配,难道其实linker script也会把实际上分配的指令也把他加入目标文件吗?

Links booklink

Contact Us: admin [ a t ] ucptt.com