0% found this document useful (0 votes)
22 views54 pages

Embedded Systems: Memory Management H. Cass e 2022

The document discusses memory management in embedded systems, detailing the memory hierarchy, types of memory (ROM, SRAM, DRAM, EEPROM), and their characteristics. It also covers binary formats such as ELF and linker scripts essential for control code and data placement. The document provides examples of memory structures and interconnects in modern microcontrollers, specifically using STM32 as a case study.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views54 pages

Embedded Systems: Memory Management H. Cass e 2022

The document discusses memory management in embedded systems, detailing the memory hierarchy, types of memory (ROM, SRAM, DRAM, EEPROM), and their characteristics. It also covers binary formats such as ELF and linker scripts essential for control code and data placement. The document provides examples of memory structures and interconnects in modern microcontrollers, specifically using STM32 as a case study.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

Embedded Systems

Memory Management

H. Cassé
2022
Introduction

Embedded system memories:


▶ linear address space
▶ contains ROM, RAM, I/O
▶ no or very few protection
▶ often no virtual memory
Control code/data placement:
▶ binary format – ELF
▶ linker script – ld

Introduction 2/54
Outline

1 Introduction

2 Memory hierarchy

3 Binary Format

4 Linker Scripts

5 Conclusion

Memory hierarchy 3/54


Modern microcontroler/System-On-Chip

Core 0 Core 1 Core 2

Interconnect

flash SRAM DRAM I/O

Memory hierarchy 4/54


Memory Structure

Memory cell.
Decoder

Ak..n−1 Read (R/W = 1)


1 when CS = 1
2 row Ak..n−1 copied to
Selector
...

3 word A0..k−1 selected


⇒ D0..m
A0..k−1 Selector R/W 4 ACK ← 1

D0..m
Memory hierarchy 5/54
ROM
Read Only Memory

Required to boot the microcontroller! (firmware)


▶ Mask ROM (programmed at built time) – NOR
implementation
V CC
V CC

SEL SEL
1 GN D 0
▶ Programmable ROM – one shot
based on fuse: cooled down ⇒ 1, ok ⇒ 0
▶ Erasable PROM – MOSFET + floating gate
Erased by UV exposition.
▶ Electrically EPROM
▶ EEPROM – byte-grain writing, slow (parameters)
▶ flash – page-grain writing, fast (code + data)

Memory hierarchy 6/54


EEPROM
Electrivally Erasable Programmable ROM

Field-effect transistor – state lost when power off

field-effect transistor with floating-gate (preserving state)

EEPROM (field electron emission), flash (hot-carrier injection)

Memory hierarchy 7/54


SRAM
Static Random-Access Memory

cell = D latch (delay latch)


D D
CP Dt Qt+1
D
D latch Q 0 X Qt
R/W CP 1 0 0
SEL 1 1 1

fast – same technology as microcontroler


expensive – ∼20 transistors

Memory hierarchy 8/54


DRAM
Dynamic Random-Access Memory

read
1 set SEL to 1
cell = transistor + capacitor 2 capacitor emptied to D
D 3 bit ⇒ bus
SEL
4 capacitor reloaded from
selector
write
cost = 1 transistor + 1 1 set SEL to 1
capacitor 2 empty the capacitor
speed = slow, variable 3 record but from D
technology ̸= processor leakage ⇒ need for refresh
the capacitor regularly ⇒
slow down read/write.
Memory hierarchy 9/54
To sump up

Type tread twrite Cost Use


EEPROM fast slow cheap config.
flash slow very slow cheap firmware/code
SRAM very fast very fast expensive stack/global
DRAM slow/irreg slow/irreg. very cheap data

For DRAM:
taccess time to get/set word
tcycle time before next operation
+ tref resh

EEPROM, flash, SRAM – in controller


DRAM – in a different die

Memory hierarchy 10/54


Example: STM32 address space

0x4000 0000-0xAFFF FFFF I/O


0x2001 C000-0x2001 FFFF 16 KB SRAM2
0x2000 0000-0x2001 BFFF 112 KB SRAM1
0x1FFF 0000-0x1FFF 77FF 30 KB System Memory
0x0800 0000-0x080F FFFF 512 KB Flash memory
0x0000 0000-0x000F FFFF Alias flash/SRAM1

Memory hierarchy 11/54


Interconnect: bus (parallel)

Properties:
▶ word size: 16b, 32b, 64b
▶ 1 bus ↔ n cores
▶ 1 bus ↔ n memory
▶ 1 request/time
▶ arbitration (round-robin,
priority)

Work:
1 core acquire the bus Control: CLK, DSEL, RD/WR,
2 put the address (+ data – ACK
store)
Access:
3 wait for acknowledge (read
data – load) ▶ single – 1 access → 1 word
4 core release the bus ▶ burst – 1 access → 1 block
Memory hierarchy 12/54
How memories are connected?

Control
Data
Address
A31..n

Decoder An−1..0

SEL

SRAM

Example: STM32 SRAM1


Address: 0x2000 0000-0x2001 BFFF – 112 KB n = 14 (0xB = 0b1011)
SEL = A31 .A30 .A29 .A28 . ... .A16 .A15 .A14

Memory hierarchy 13/54


Interconnect: crossbar/matrix

Structure:
▶ masters: core
▶ slaves: memory
▶ 1 master → 1 slave
▶ arbitration if n cores → flash
same slave Core 0
SRAM
Work: Core 1
DRAM
1 core require access to Core 2
slave IO
2 for aqcuisition
3 put address (+ data)
4 wait for acknowledge
5 release
Memory hierarchythe slave 14/54
Interconnect: grid (close future)

Massively parallel machines:


▶ interconnect network
(hyper/grid) Core Core Core
▶ 1 core ↔ port
▶ memory in cores
▶ memory at some ports Core Core Core

▶ 1 access = 1 packet
sent
Core Core Core
▶ path in the grid

Memory hierarchy 15/54


STM32 Example

Memory hierarchy 16/54


DMA
Direct Memory Access

DM A1 , DM A2
▶ 8 streams + priority
▶ connected to 8 channels
▶ data size: 1B, 2B, 4B
▶ increment
▶ FIFO 16B – direct/burst, reload threshold, circular
▶ P → M , M → P , M → M (DM A1 )

Memory hierarchy 17/54


Example 1: getting ADC values

IN0
IN1 ADC DR int t[3];
ADC1 DM A2 SRAM
IN4

Core
IRQ DM A2 ST RM 0

Connected to stream 0, channel 0 of DM A2 :


DMA2 S0PAR = ( u i n t 3 2 t )&ADC2 DR ;
DMA2 S0M0AR = ( u i n t 3 2 t ) t ;
DMA2 S0NDTR = 3 ;
DMA2 S0CR = DMA CHAN0 | DMA MSIZE WORD | DMA PSIZE WORD | DMA MINC
| DMA DIR P2M | DMA PFCTRL | DMA EN | DMA TCIE ;
DMA2 LIFCR = DMA TCIF0 ;

ADC SQR1 = 3 << 2 0 ;


ADC SQR3 = ( 0 << 0 ) | ( 1 << 5 ) | ( 4 << 1 0 ) ;
ADC CR2 &= ˜ADC DMA ; /∗ s e t 1 : e n a b l e ∗/
ADC CR2 |= ADC DMA ;
ADC CR1 = ADC SWSTART ; /∗ s t a r t ADC ∗/
Memory hierarchy 18/54
Example 2: playing values on the DAC

T IM 4 T RGO
T IM4 DAC DM A1 SRAM
DAC DHR12R1

DAC OU T1

DAC1 connected to DM A1 , stream 5, channel 7:


DMA1 S5PAR = ( u i n t 3 2 t )&DAC DHR12R1 ;
DMA1 S5M0AR = ( u i n t 3 2 t ) t ;
DMA1 S5NDTR = 1 0 2 4 ;
DMA1 S5CR = DMA CHAN7 | DMA MSIZE WORD | DMA PSIZE WORD | DMA MINC
| DMA DIR M2P | DMA PFCTRL | DMA EN | DMA MBURST 4 ;
DMA1 S5FCR = DMA SFCR DMDIS | DMA SFCR FTHFULL ;

DAC CR = DAC DMAEN1 | DAC TEN1 | DAC EN1 | DAC TSEL TRGO4 ;

Memory hierarchy 19/54


Outline

1 Introduction

2 Memory hierarchy

3 Binary Format

4 Linker Scripts

5 Conclusion

Binary Format 20/54


Memory Map Model

0x0000 0000
functions, switch tables
R-X Code exception tables

Read-Only
R-- Data
const global variables, strings

RW- Data non-const/static/global variables

dynamic memory
RW- Heap (malloc)
brk

SP
RW- Stack local variables, saved context
0xFFFF FFFF

Binary Format 21/54


ELF
Executable and Linking Format

Objectives (basically for Unix System-V):


▶ executable fast load,
▶ adapted to OS
▶ multi-architecture support
▶ static & dynamic linking
▶ kernel + embedded code

Alternatives:
▶ COFF (Common Object File Format) – PE-COFF
(Windows)
▶ universal binary (fat binary) – Apple
▶ .class Java byte-code
Binary Format 22/54
ELF Structure

Header:
0x7F ELF
file class, data encoding
type (object, exec, ...)
Linking Execution machine (x86, ARM, etc)
header header format version
program table program table entry point
section 1 segment 1 program headers offset
section 2 section headers offset
section 3 segment 2 flags (machine dependent)
section 4
header size
... ...
program header size
section table section table
program header number
section header size
section header number
string table index

Binary Format 23/54


Example

$ r e a d e l f −h e x 1 . e l f
Magic : 7 f 45 4 c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class : ELF32
Data : 2 ’ s complement , l i t t l e e n d i a n
Version : 1 ( current )
OS/ ABI : UNIX − System V
ABI v e r s i o n : 0
Type : EXEC ( e x e c u t a b l e )
Machine : ARM
Version : 0 x1
Entry point address : 0 x8000415
Program h e a d e r o f f s e t : 52 ( b y t e s i n t h e f i l e )
S e c t i o n h e a d e r o f f s e t : 176212 ( b y t e s i n t h e f i l e )
Flags : 0 x5000400 , V e r s i o n 5 EABI , hard−f l o a t ABI
Header s i z e : 52 ( b y t e s )
Program h e a d e r s i z e : 32 ( o c t e t s )
Program h e a d e r number : 2
Section header s i z e : 40 ( o c t e t s )
S e c t i o n h e d e r number : 19
String table index : 18

Binary Format 24/54


Executing a program

entry Code Program header:


type
Header
RO Data offset
virtual address
Data physical address
Segment 1
file size
Segment 2 memory size
Segment 3 flags (RWX)
alignment
Stack

For data, file size ≤ memory size:


▶ file size: initialized data (stored in file)
▶ memory size - file size: unitialized data (set to 0)

Binary Format 25/54


Example

$ r e a d e l f −l ex1 . e l f

ELF f i l e t y p e i s EXEC ( e x e c u t a b l e )
E n t r y p o i n t 0 x8000415
T h e r e a r e 2 program h e a d e r s a t o f f s e t 52

Program headers :
Type Offset V i r t Addr Phys . Addr F i . S i z e Me . S i z e F l a g s A l i g n m e n t
LOAD 0 x010000 0 x08000000 0 x08000000 0 x 0 0 c 9 0 0 x 0 0 c 9 0 R X 0 x10000
LOAD 0 x020000 0 x20000000 0 x 0 8 0 0 0 c 9 0 0 x00000 0 x00408 RW 0 x10000

M a t c h i n g s e c t i o n / se gm en t :
S e c t i o n s o f s eg men t . . .
00 . text
01 . data . bss . stack

Binary Format 26/54


Example: Linux program – x86 64

Type Offset V i r t . Addr Phys . Addr


File size Memory s i z e Flags Alignment
PHDR 0 x0000000000000040 0 x0000000000000040 0 x0000000000000040
0 x00000000000002d8 0 x00000000000002d8 R 0 x8
INTERP 0 x0000000000000318 0 x0000000000000318 0 x0000000000000318
0 x000000000000001c 0 x000000000000001c R 0 x1
[ I n t e r p r e t e r : / l i b 6 4 / l d−l i n u x −x86 −64. s o . 2 ]
LOAD 0 x0000000000000000 0 x0000000000000000 0 x0000000000000000
0 x0000000000001cf8 0 x0000000000001cf8 R 0 x1000
LOAD 0 x0000000000002000 0 x0000000000002000 0 x0000000000002000
0 x00000000000095d1 0 x00000000000095d1 R X 0 x1000
LOAD 0 x000000000000c000 0 x000000000000c000 0 x000000000000c000
0 x00000000000040e0 0 x00000000000040e0 R 0 x1000
LOAD 0 x0000000000010970 0 x0000000000011970 0 x0000000000011970
0 x0000000000000710 0 x00000000000008d0 RW 0 x1000
DYNAMIC 0 x0000000000010b98 0 x0000000000011b98 0 x0000000000011b98
0 x00000000000001f0 0 x00000000000001f0 RW 0 x8
NOTE 0 x0000000000000338 0 x0000000000000338 0 x0000000000000338
0 x0000000000000020 0 x0000000000000020 R 0 x8
NOTE 0 x0000000000000358 0 x0000000000000358 0 x0000000000000358
0 x0000000000000044 0 x0000000000000044 R 0 x4
GNU PROPERTY 0 x0000000000000338 0 x0000000000000338 0 x0000000000000338
0 x0000000000000020 0 x0000000000000020 R 0 x8
GNU EH FRAME 0 x000000000000e070 0 x000000000000e070 0 x000000000000e070
0 x0000000000000544 0 x0000000000000544 R 0 x4
GNU STACK 0 x0000000000000000 0 x0000000000000000 0 x0000000000000000
0 x0000000000000000 0 x0000000000000000 RW 0 x10
Binary Format 0 x 0 0 0 0 0 0 0 0 0 0 0 1 0 9 7 0 0 x 0 0 0 0 0 0 0 0 0 0 0 1 1 9 7 0
GNU RELRO 0 x 0 0 0 0 0 0 0 0 0 0 0 1 27/54
1970
0 x0000000000000690 0 x0000000000000690 R 0 x1
Sections

Section header:
Logical view: name
▶ .text – code type
▶ .rodata – read-only flags
address
data offset
▶ .data – initialized data size
▶ .bss – unitialized data link (section)
▶ .strtab – string table info
▶ .symtab – symbol table alignment
entry size
▶ .rel.XXX – relocation
▶ .debug – debugging type: PROGBITS, SYMTAB, STRTAB.
flags: WRITE, ALLOC, EXECINSTR.

Binary Format 28/54


Example

$ r e a d e l f −S e x 1 . e l f
T h e r e a r e 19 s e c t i o n h e a d e r s , b e g i n n i n g a t o f f s e t a d d r e s s 0 x2b054 :

Section header :
[ Nr ] Nom Type Addr Offset Size ES F l . LN I n f A l
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] . text PROGBITS 08000000 010000 000 c90 00 AX 0 0 4
[ 2] . data PROGBITS 20000000 020000 000000 00 WA 0 0 1
[ 3] . bss NOBITS 20000000 020000 000008 00 WA 0 0 4
[ 4] . stack NOBITS 20000008 020000 000400 00 WA 0 0 1
[ 5] . debug info PROGBITS 00000000 020000 001071 00 0 0 1
[ 6] . debug abbrev PROGBITS 00000000 021071 0006 e2 00 0 0 1
[ 7] . debug loc PROGBITS 00000000 021753 00101 b 00 0 0 1
[11] . debug line PROGBITS 00000000 0241 a0 000 f 2 b 00 0 0 1
[12] . debug str PROGBITS 00000000 0250 cb 0055 d3 01 MS 0 0 1
[ 1 3 ] . comment PROGBITS 00000000 02 a 6 9 e 000059 01 MS 0 0 1
[ 1 4 ] .ARM. a t t r i b u t e s ARM ATTR 00000000 02 a 6 f 7 000034 00 0 0 1
[ 1 5 ] . debug frame PROGBITS 00000000 02 a 7 2 c 000258 00 0 0 4
[ 1 6 ] . symtab SYMTAB 00000000 02 a984 000470 10 17 46 4
[17] . strtab STRTAB 00000000 02 a d f 4 00019 e 00 0 0 1
[18] . shstrtab STRTAB 00000000 02 a f 9 2 0000 b f 00 0 0 1

Binary Format 29/54


Building an object

file.c
stdio.h
#include <stdio.h> ...
... printf(const char *, ...);
printf(”ok!”); ...
... extern int errno;
x = errno; ...
...

file.o/.symtab
cc -c main 296 FUNC GLOBAL DEFAULT 14
printf 0 NOTYPE GLOBAL DEFAULT UND
errno 0 NOTYPE GLOBAL DEFAULT UND
...
0x224 BL ???
file.o/.rel.text
... 0x224 .text printf R ARM CALL 0
0x330 .text errno R ARM ABS32 0
0x330 ADR R3, ???;
...
file.o/.text
Binary Format 30/54
Linking into an executable

file.o executable
... 0x1000 ...
0x224 BL ??? cc/ld 0x1224 BL 2048
... ...
0x330 ADR R3, ??? 0x1330 ADR R3, 250C
... ...
0x2000 ...
0x224 .text printf
0x2048 PUSH R0
0x330 .text errno
...
0x2500 ...
0x250C .int 0
printf.o error.o ...
... ...
0x48 PUSH R0 0x0C .int 0 ...
... ...
printf 0x48 FUNC errno 0x0C OBJECT

libc.a

Binary Format 31/54


Static link edition: algorithm

Data: Ω = {objects}, L = {libraries}


Result: A : object → address: executable objects
a ← base address; A ← {} ;
while Ω ̸= ∅ do
ω ← pop(Ω); Ω′ ← Ω′ @[ω];
A[ω] ← a; a ← a + size(ω);
foreach s ∈ symbols(ω) do
if ∃ω ′ ∈ (Ω ∪ Ω′ ) ∧ s ∈ ω ′ then
pass
else
if ∃ω ′ ∈ L ∧ s ∈ ω ′ then
Ω ← Ω ∪ {ω ′ }
else
error: cannot resolve symbol s
end
end
end
end

Binary Format 32/54


Example

$ r e a d e l f −s e x 1 . o
Num : V a l u e Type Link Scope Ndx Name
0 : 00000000 0 NOTYPE LOCAL DEFAULT UND
...
6 : 00000000 0 NOTYPE LOCAL DEFAULT 13 $d
7 : 00000000 0 NOTYPE LOCAL DEFAULT 14 $ t
8 : 00000104 0 NOTYPE LOCAL DEFAULT 14 $d
...
4 8 : 00000001 296 FUNC GLOBAL DEFAULT 14 main
4 9 : 00000000 0 NOTYPE GLOBAL DEFAULT UND t f p p r i n t f

$ r e a d e l f −r e x 1 . o
Relocation section ’ . r e l . text ’ t o f f s e t address 0 x764c c o n t a i n s 6 e n t r i e s :
Offset Info Type Sym v a l . Symbol name
00000008 0000310 a R ARM THM CALL 00000000 tfp printf
000000 a6 0000310 a R ARM THM CALL 00000000 tfp printf
000000 b0 0000310 a R ARM THM CALL 00000000 tfp printf
00000104 00000502 R ARM ABS32 00000000 . rodata . str1 .4
0000010 c 00000502 R ARM ABS32 00000000 . rodata . str1 .4
00000120 00000502 R ARM ABS32 00000000 . rodata . str1 .4

Binary Format 33/54


Dynamic Linking

Principle: libraries are resolved at execution time.


▶ Executable symbols resolved at execution time.
▶ Library address known at execution time.
▶ Library implementation may change (since static linkage).

OS Constraints:
▶ Most library read-only pages unchanged: process sharing.
▶ Data pages are local to each process.

Solution: dynamic library or shared library


▶ Compile with -fPIC (Position Independent Code).
▶ Linkage information in .dynamic, .dynsym.
▶ .text, .rodata shared between processes.
▶ .data duplicated in each process.
▶ .got (Global Offset Table) relocated data addresses duplicated.
▶ .plt (Procedure Linkage Table) relocated function addresses duplicated.

Binary Format 34/54


Example: libc.so

...
.data 0x10C .int 0
libc.so
...
...
.text 0x48 PUSH R0
...
printf 0x48 .text
errno 0x10C .data

0x3000 0x

0x2000 0x
.got 0x524 .word 0x310C 0x720 .word 0x610C
.plt 0x200 bl 0x2048 0x15C bl 0x5048
... ...
bl 0x200 bl 0x15C
... ...
ldr R3, [0x524] ldr R3, [0x720]
... ...

exo1.elf exo2.elf

Binary Format 35/54


Binary Tools

Linking:
▶ ld – static linker
▶ /lib/ld-linux.so – dynamic linker
▶ ldd – dynamic linking test

Managing binaries:
▶ readelf – comprehensive function to explore binaries.
▶ objdump – GCC target-independent exploration.
▶ objcpy – binary conversion.
▶ nm – target-independent symbol listing.
▶ ar/ranlib – static library builder.
▶ gcc -shared – dynamic library builder.
Binary Format 36/54
Controlling the code generation

Standard modifiers:
▶ extern – symbol defined in an external object,
▶ local static – local variable declared in .data,
▶ global static – symbol only visible in current object,
▶ const – put in .rodata.
Non-standard (GCC):
▶ attribute (aligned(size)) – alignment
▶ attribute (weak) – weak linkage
▶ attribute (section("SECTION")) – section selection

Binary Format 37/54


Outline

1 Introduction

2 Memory hierarchy

3 Binary Format

4 Linker Scripts

5 Conclusion

Linker Scripts 38/54


Why a linker script?

WIth OS + MMU (Linux, Windows):


▶ Address space is regular linear (virtual address space).
▶ Program starts at 0x0000 0000, libraries linked at run-time.
▶ OS protects program from hardware details.
▶ 1 method for linking.
Bare metal embeded system:
▶ Application has to adapt to the hardware.
▶ Application uses the particularities of the hardware.
▶ Lots of hardware event with the ISA and ABI.
▶ We have to adapt the compilation process to the hardware!
Adaptation versatility ⇒ script for long!
Linker Scripts 39/54
Labwork linker script
link.ld

data flash = .;
. d a t a : AT( d a t a f l a s h )
MEMORY { {
RAM ( xrw ) : vectab in ram = . ;
ORIGIN = 0 x20000000 , ∗(. vector table );
LENGTH = 128K data begin = . ;
FLASH ( r x ) : ∗ ( . d a t a ) ∗ ( . d a t a ∗)
ORIGIN = 0 x08000000 , . = ALIGN ( 4 ) ;
LENGTH = 1024K data end = . ;
} } > RAM
. bss :
ENTRY( h a n d l e r r e s e t ) {
SECTIONS { bss begin = . ;
∗(. bss )
. text : ∗ ( . b s s ∗)
{ . = ALIGN ( 4 ) ;
vectab begin = . ; bss end = . ;
KEEP ( ∗ ( . v e c t o r t a b l e ) ) } > RAM
vectab end = . ; s t a c k s i z e = 1024;
∗(. text ) s t a c k e n d = ORIGIN (RAM) + LENGTH(RAM) ;
∗ ( . t e x t ∗) stack begin = stack end − stack size ;
∗(. rodata ) . = stack begin ;
∗ ( . r o d a t a ∗) . stack :
. = ALIGN ( 4 ) ; {
} > FLASH . = . + stack size ;
} > RAM
}
Linker Scripts 40/54
Example script
How it works?

1 It configures the memory (SRAM, flash).


2 Entry point is address handler reset.
3 Put .vector table at the code start.
4 Put code in flash.
5 Put .data in flash but configured to be used in SRAM.
6 Put the stack at the memory end.
7 Defines symbols to be used by the program.

Linker Scripts 41/54


Memory Description

MEMORY {
name(access): ORIGIN=address, LENGTH=size
}

access combination of r, w and x.


address address expression (C-like).
size size expression (C-like), NK, NM, ...

Linker Scripts 42/54


Commands: sections

SECTIONS {
commands∗
}
name vaddr? option∗ {
output − command∗
} > memory ?

name one of .text, .data, ...


option AT(paddr) — ALIGN(size)
vaddr execution address
paddr storage address
memory as defined MEMORY description.
Linker Scripts 43/54
Output Commands

f ile pattern(section pattern∗ )

Patterns:
▶ Characters matching the same.
▶ * matches any sequence of characters.
▶ ? matches any character.
▶ [chars] set of characters.

Beware
▶ *(.data) *(.got) =
file1(.data) file2(data) ... file1(.got) file2(.got) ...
▶ *(.data *.got) =
file1(.data) file1(.got) file2(.data) file2(.got) ...

Linker Scripts 44/54


Commands: address assignment

identif ier = expression ;


Also +=, -=, ...

identif ier:
▶ Defined by assignment.
▶ Program symbol (read-only).
▶ – location counter
(incremented each time a section is added)

expression:
▶ C-style expressions,
▶ constants with K and M,
▶ ALIGN(alignment), ALIGN(address, alignment)
▶ ADDR(section), SIZEOF(section), ALIGNOF(section),
▶ LENGTH(memopry), ORIGIN(memory)
▶ MAX(e1 , e2 ), MIN(e1 , e2 )

Linker Scripts 45/54


Command: other

Content generation output commands:


▶ BYTE(value) – 8-bit
▶ SHORT(value) – 16-bit
▶ LONG(value) – 32-bit
▶ QUAD(value) – 64-bit
▶ FILL(value) – filling (alignment, sized section)

Other commands:
▶ ENTRY(symbol) – set program entry
▶ SEARCH DIR(path) – add path for library lookup
▶ INPUT(path1 , path2 , ...) – add objects
▶ STARTUP(apth) – as input but link first
▶ EXTERN(symbol1 ...) – force linking

Linker Scripts 46/54


Example: startup time

SRAM

0x2000 0000
.data specification:
flash . d a t a : AT( d a t a f l a s h )
SRAM initialization {
vectab in ram = . ;
vector table ∗(. vector table );
data begin = . ;
∗ ( . d a t a ) ∗ ( . d a t a ∗)
void handle reset { ... } . = ALIGN ( 4 ) ;
data end = . ;
0x0800 0000
} > RAM

flash
Memory alias remap:
SYSCFG MEMRMP = 0 b11 ;
vector table
handle reset
0x0000 0000

Linker Scripts 47/54


Example: SRAM initialization

SRAM SRAMglobal variables


vector table
0x2000 0000 0x2000 0000

flash flash
SRAM initialization SRAM initialization
vector table vector table

void handle reset { ... } void handle reset { ... }

0x0800 0000 0x0800 0000

flash SRAM

...
vector table vector table
handle reset handle reset
0x0000 0000 0x0000 0000

Linker Scripts 48/54


Example: SRAM initialization code

link.ld:
. d a t a : AT( d a t a f l a s h )
{
vectab in ram = . ;
∗(. vector table );
data begin = . ;
∗ ( . d a t a ) ∗ ( . d a t a ∗)
. = ALIGN ( 4 ) ;
data end = . ;
} > RAM

Initalization of global variables:


extern uint32 t data flash ;
extern uint32 t data begin ;
extern uint32 t data end ;

u i n t 3 2 t ∗p = & d a t a f l a s h ;
u i n t 3 2 t ∗q = & d a t a b e g i n ;
while (q < & data end )
∗q++ = ∗p++;

Linker Scripts 49/54


Exercise: initialize the BSS

.bss = unitialized global variables (in fact initialized to 0).

link.ld:
. bss :
{
bss begin = . ;
∗(. bss )
∗ ( . b s s ∗)
. = ALIGN ( 4 ) ;
bss end = . ;
} > RAM

? Write the C code to initialize .bss.

Linker Scripts 50/54


Exercise

A good way to check if an SEE has not damaged the flash


memory is to compute a checksum (words composing are
XORed), to store in the flash and to recompute this checksum
from time to time and to compare it with the initial one. If they
are different, flash memory has been altered and some
emergency procedure has to be performed.

1 Provide the link.ld part supporting the code in the flash


with the checksum word (32-bit) – it is firsly initialized to
0 and will be updated thereafter.
2 Write the function uint32 t checksum() that computes the
checksum of the flash.
Linker Scripts 51/54
Exercise

This embedded application is made of modules that are


represented by code, data and a specific datastructure declared
in its own section .mod:
typedef struct {
c h a r name [ 1 6 ] ;
uint32 t id ;
uint32 t version ;
v o i d (∗ i n i t ) ( s t r u c t m o d u l e t ∗m) ;
void ∗data ;
} module t ;

These section are grouped together in a section named .mod.


1 Write the linker script part that builds .mod.
2 Write the function void init modules () that initializes the modules
by calling the function pointer init of the data structure.
Linker Scripts 52/54
Outline

1 Introduction

2 Memory hierarchy

3 Binary Format

4 Linker Scripts

5 Conclusion

Conclusion 53/54
Conclusion

In this course:
▶ hardware memory organization and bus,
▶ binary format (ELF) and processing,
▶ linker script required to support new hardware.
To go further,
▶ take a look to the STM32 handbook (available on
Moodle),
▶ stay update with new memory types (NVMe for example),
▶ play with binary tools (special help with dynamic libraries).

Conclusion 54/54

You might also like