dfu.ld
1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/* DFU transfers can serve two purposes:
* - Transfering RAM data between the machine and the host, e.g. Python scripts
* - Upgrading the flash memory to perform a software update
*
* The second case raises a huge issue: code cannot be executed from memory that
* is being modified. We're solving this issue by copying the DFU code in RAM.
*
* This linker script will generate some code that expects to be executed from a
* fixed address in RAM. The corresponding instructions will be embedded in the
* main Epsilon ELF file, and copied to that address before execution.
*
* This address needs to live in RAM, and needs to be temporarily overwriteable
* when the program is being run. Epsilon has a large stack to allow deeply
* recursive code to run. But when doing DFU transfers it is safe to assume we
* will need very little stack space. We're therefore using the topmost 8K of
* the stack reserved by Epsilon.
*
* Last but not least, we'll want to jump to a known entry point when running
* the DFU code (namely, Ion::USB::Device::Calculator::Poll). We're simply
* making sure this is the first symbol output. */
EPSILON_STACK_END = 0x20000000 + 256K - 32K;
MEMORY {
RAM_BUFFER (rw) : ORIGIN = EPSILON_STACK_END, LENGTH = 8K
}
SECTIONS {
.text : {
. = ALIGN(4);
KEEP(*(.text._ZN3Ion3USB6Device10Calculator12PollAndResetEb))
*(.text)
*(.text.*)
} >RAM_BUFFER
.rodata : {
*(.rodata)
*(.rodata.*)
} >RAM_BUFFER
/DISCARD/ : {
/* For now, we do not need .bss and .data sections. This allows us to simply
* skip any rt0-style initialization and jump straight into the PollAndReset
* routine. */
*(.bss)
*(.bss.*)
*(.data)
*(.data.*)
}
}