<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.4.5" />
<title>Low-Level Start on ARM</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
border: 1px solid red;
*/
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
tt {
color: navy;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
font-family: sans-serif;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
div.sectionbody {
font-family: serif;
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
pre {
padding: 0;
margin: 0;
}
span#author {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
font-family: sans-serif;
}
div#footer {
font-family: sans-serif;
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
div#footer-text {
float: left;
padding-bottom: 0.5em;
}
div#footer-badges {
float: right;
padding-bottom: 0.5em;
}
div#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.5em;
margin-bottom: 2.5em;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid silver;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid silver;
background: #f4f4f4;
padding: 0.5em;
}
div.quoteblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock {
padding-left: 2.0em;
margin-right: 10%;
}
div.verseblock > div.content {
white-space: pre;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 2px solid silver;
}
div.exampleblock > div.content {
border-left: 2px solid silver;
padding: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead {
font-family: sans-serif;
font-weight: bold;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
@media print {
div#footer-badges { display: none; }
}
div#toctitle {
color: #527bbd;
font-family: sans-serif;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */
div.sidebar-content {
background: #ffffee;
border: 1px solid silver;
padding: 0.5em;
}
div.sidebar-title, div.image-title {
color: #527bbd;
font-family: sans-serif;
font-weight: bold;
margin-top: 0.0em;
margin-bottom: 0.5em;
}
div.listingblock div.content {
border: 1px solid silver;
background: #f4f4f4;
padding: 0.5em;
}
div.quoteblock-attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock-content {
white-space: pre;
}
div.verseblock-attribution {
padding-top: 0.75em;
text-align: left;
}
div.exampleblock-content {
border-left: 2px solid silver;
padding-left: 0.5em;
}
/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
</head>
<body>
<div id="header">
<h1>Low-Level Start on ARM</h1>
</div>
<h2 id="_memory_map">Memory Map</h2>
<div class="sectionbody">
<div class="paragraph"><p>ARM controllers typically have quite a scattered memory map. Smaller systems may have several disconnected on-chip
memory regions. The linker command file infrastructure available for ARM board support packages (BSP) allows a flexible
usage of memory regions. A BSP requires usually three linker command files which use the INCLUDE directive to provide a
single set of definitions</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
the basic linker command file <em>linkcmds.base</em>,
</p>
</li>
<li>
<p>
the architecture specific linker command file <em>linkcmds.armv4</em> or <em>linkcmds.armv7m</em>,
</p>
</li>
<li>
<p>
the BSP specific linker command file <em>linkcmds.bsp_name</em>.
</p>
</li>
</ol></div>
<div class="paragraph"><p>The configure macro <em>RTEMS_BSP_LINKCMDS</em> will copy <em>linkcmds.bsp_name</em> to <em>linkcmds</em> during the BSP configuration. It
will be installed it into the BSP specific installation path. This path will be added to the GCC search path via the
<em>-B</em> option and the linker will use this file instead of its default file.</p></div>
<div class="paragraph"><p>The BSP specific linker command file defines the distribution of physically available memory regions and the
architecture. It may override default values used by the more general files.</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="hsides"
cellspacing="0" cellpadding="4">
<caption class="title">Region Definitions</caption>
<col width="25%" />
<col width="75%" />
<thead>
<tr>
<th align="left" valign="top"> Region </th>
<th align="left" valign="top"> Usage</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">REGION_START</p></td>
<td align="left" valign="top"><p class="table">low-level start code and data</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_VECTOR</p></td>
<td align="left" valign="top"><p class="table">mode stacks; vector table if <em>bsp_vector_table_in_start_section</em> symbol is not defined</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_TEXT</p></td>
<td align="left" valign="top"><p class="table">text sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_TEXT_LOAD</p></td>
<td align="left" valign="top"><p class="table">load region for text sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_RODATA</p></td>
<td align="left" valign="top"><p class="table">read-only data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_RODATA_LOAD</p></td>
<td align="left" valign="top"><p class="table">load region for read-only data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_DATA</p></td>
<td align="left" valign="top"><p class="table">read-write data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_DATA_LOAD</p></td>
<td align="left" valign="top"><p class="table">load region for read-write data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_FAST_TEXT</p></td>
<td align="left" valign="top"><p class="table">fast text section</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_FAST_TEXT_LOAD</p></td>
<td align="left" valign="top"><p class="table">load region for fast text section</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_FAST_DATA</p></td>
<td align="left" valign="top"><p class="table">fast data section</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_FAST_DATA_LOAD</p></td>
<td align="left" valign="top"><p class="table">load region for fast data section</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_BSS</p></td>
<td align="left" valign="top"><p class="table">zero-initialized read-write data section</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_WORK</p></td>
<td align="left" valign="top"><p class="table">RTEMS work space and C program heap</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">REGION_STACK</p></td>
<td align="left" valign="top"><p class="table">optional region for thread stacks (may be of zero size)</p></td>
</tr>
</tbody>
</table>
</div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="hsides"
cellspacing="0" cellpadding="4">
<caption class="title">Potentially BSP Specific Symbols</caption>
<col width="16%" />
<col width="16%" />
<col width="16%" />
<col width="50%" />
<thead>
<tr>
<th align="left" valign="top"> Symbol </th>
<th align="left" valign="top"> ARMv4 Default </th>
<th align="left" valign="top"> ARMv7-M Default </th>
<th align="left" valign="top"> Usage</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">bsp_section_robarrier_align</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">barrier alignment between text and read-only data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_section_rwbarrier_align</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">barrier alignment between read-only and read-write data sections</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_align</p></td>
<td align="left" valign="top"><p class="table">8</p></td>
<td align="left" valign="top"><p class="table">8</p></td>
<td align="left" valign="top"><p class="table">stack alignment</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_abt_size</p></td>
<td align="left" valign="top"><p class="table">128</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">abort mode stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_fiq_size</p></td>
<td align="left" valign="top"><p class="table">128</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">fast interrupt mode stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_irq_size</p></td>
<td align="left" valign="top"><p class="table">512</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">interrupt mode stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_svc_size</p></td>
<td align="left" valign="top"><p class="table">512</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">supervisor mode stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_und_size</p></td>
<td align="left" valign="top"><p class="table">128</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">undefined mode stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_stack_main_size</p></td>
<td align="left" valign="top"><p class="table">0</p></td>
<td align="left" valign="top"><p class="table">4096</p></td>
<td align="left" valign="top"><p class="table">main stack size</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_processor_count</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">1</p></td>
<td align="left" valign="top"><p class="table">the processor count of the system in SMP configurations</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">bsp_vector_table_in_start_section</p></td>
<td align="left" valign="top"><p class="table">undefined</p></td>
<td align="left" valign="top"><p class="table">undefined</p></td>
<td align="left" valign="top"><p class="table">indicates if the vector table remains in the start section</p></td>
</tr>
</tbody>
</table>
</div>
<h3 id="_example_with_mmu">Example with MMU</h3><div style="clear:left"></div>
<div class="paragraph"><p>This example is used on an ARM Cortex-A processor based BSP. The ARM controller with a memory management unit (MMU)
need 16KiB to store the translation table (<em>bsp_translation_table_base</em>). This system has only one physical memory
region, e.g. a DDR2 SDRAM. The interrupt and abort mode stacks sizes are increased (<em>bsp_stack_irq_size</em> and
<em>bsp_stack_abt_size</em>). A read-write barrier of 1MiB is introduced to separate the read-write from the read-only
sections (<em>bsp_section_rwbarrier_align</em>). This helps to set up a read-only protection with the MMU which uses a page
size of 1MiB. Since the start region (<em>REGION_START</em>) is mapped to 0x0 and resides in a writeable memory (e.g. it is
not a flash memory) we can use the vector table used for exception processing in the start section during the whole
system lifetime (<em>bsp_vector_table_in_start_section</em>). Since this is used on a SMP configuration, the processor count
is set to reserve enough stack space for all mode stacks (<em>bsp_processor_count</em>).</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>MEMORY {
RAM : ORIGIN = 0x00000000, LENGTH = 256M - 16k
RAM_MMU : ORIGIN = 0x0fffc000, LENGTH = 16k
}
REGION_ALIAS ("REGION_START", RAM);
REGION_ALIAS ("REGION_VECTOR", RAM);
REGION_ALIAS ("REGION_TEXT", RAM);
REGION_ALIAS ("REGION_TEXT_LOAD", RAM);
REGION_ALIAS ("REGION_RODATA", RAM);
REGION_ALIAS ("REGION_RODATA_LOAD", RAM);
REGION_ALIAS ("REGION_DATA", RAM);
REGION_ALIAS ("REGION_DATA_LOAD", RAM);
REGION_ALIAS ("REGION_FAST_TEXT", RAM);
REGION_ALIAS ("REGION_FAST_TEXT_LOAD", RAM);
REGION_ALIAS ("REGION_FAST_DATA", RAM);
REGION_ALIAS ("REGION_FAST_DATA_LOAD", RAM);
REGION_ALIAS ("REGION_BSS", RAM);
REGION_ALIAS ("REGION_WORK", RAM);
REGION_ALIAS ("REGION_STACK", RAM);
bsp_stack_irq_size = DEFINED (bsp_stack_irq_size) ? bsp_stack_irq_size : 4096;
bsp_stack_abt_size = DEFINED (bsp_stack_abt_size) ? bsp_stack_abt_size : 1024;
bsp_section_rwbarrier_align = DEFINED (bsp_section_rwbarrier_align) ? bsp_section_rwbarrier_align : 1M;
bsp_vector_table_in_start_section = 1;
bsp_translation_table_base = ORIGIN (RAM_MMU);
bsp_processor_count = DEFINED (bsp_processor_count) ? bsp_processor_count : 4;
INCLUDE linkcmds.armv4</tt></pre>
</div></div>
<h3 id="_example_without_mmu">Example without MMU</h3><div style="clear:left"></div>
<div class="paragraph"><p>This example is used on an ARM7TDMI based BSP. The external flash memory provides regions used for low-level BSP start
and the load regions of other sections. The internal SRAM provides the regions for the vector table and mode stacks,
the fast text section and the thread stacks. The internal USB peripheral RAM provides a region for the fast data
section. The text, read-only data, read-write data and the work space are located in the external SDRAM.</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>MEMORY {
RAM_INT : ORIGIN = 0x40000000, LENGTH = 64k
RAM_USB : ORIGIN = 0x7fd00000, LENGTH = 16k
RAM_EXT : ORIGIN = 0xa0400000, LENGTH = 4M
ROM_BOOT : ORIGIN = 0x81000000, LENGTH = 16k
ROM_EXT : ORIGIN = 0x81010000, LENGTH = 2M - 64k
}
REGION_ALIAS ("REGION_START", ROM_BOOT);
REGION_ALIAS ("REGION_VECTOR", RAM_INT);
REGION_ALIAS ("REGION_TEXT", RAM_EXT);
REGION_ALIAS ("REGION_TEXT_LOAD", ROM_EXT);
REGION_ALIAS ("REGION_RODATA", RAM_EXT);
REGION_ALIAS ("REGION_RODATA_LOAD", ROM_EXT);
REGION_ALIAS ("REGION_DATA", RAM_EXT);
REGION_ALIAS ("REGION_DATA_LOAD", ROM_EXT);
REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT);
REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_BOOT);
REGION_ALIAS ("REGION_FAST_DATA", RAM_USB);
REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_BOOT);
REGION_ALIAS ("REGION_BSS", RAM_EXT);
REGION_ALIAS ("REGION_WORK", RAM_EXT);
REGION_ALIAS ("REGION_STACK", RAM_INT);
INCLUDE linkcmds.armv4</tt></pre>
</div></div>
</div>
<h2 id="_low_level_bsp_start">Low-Level BSP Start</h2>
<div class="sectionbody">
<div class="paragraph"><p>The BSP entry symbol is <em>_start</em>. The boot process must jump to this symbol to initiate the low-level BSP start which
will hopefully end up in a running RTEMS application. At this point the start region must be initialized and
accessible. Since the first instructions of the start code contain only program counter relative references it is
possible to run this code with an address offset (e.g. the boot flash is mapped to a special memory region in boot
mode). The first stage boot loader on systems with a MMU and cache should</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
disable the MMU,
</p>
</li>
<li>
<p>
flush and invalidate the caches,
</p>
</li>
<li>
<p>
disable the cache,
</p>
</li>
<li>
<p>
invalidate the branch predictor.
</p>
</li>
</ol></div>
<div class="paragraph"><p>The low-level start performs the following steps:</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
The mode stacks are initialized.
</p>
</li>
<li>
<p>
The Neon and VFP unit is enabled if necessary.
</p>
</li>
<li>
<p>
Branch to <em>bsp_start_hook_0</em>. This hook should perform the following actions:
</p>
<div class="ulist"><ul>
<li>
<p>
Set up the PLL.
</p>
</li>
<li>
<p>
Make the start memory accessible on its intended location.
</p>
</li>
<li>
<p>
Additional start memory initialization steps, e.g. change flash access parameter from default boot values to
optimized values.
</p>
</li>
</ul></div>
</li>
<li>
<p>
The hook returns and the start code runs now on its intended location. The vector table is copied to its final
destination if necessary.
</p>
</li>
<li>
<p>
Branch to <em>bsp_start_hook_1</em>. This hook should perform the following actions:
</p>
<div class="ulist"><ul>
<li>
<p>
Set final memory mappings, e.g. change from boot to normal memory map.
</p>
</li>
<li>
<p>
Initialize memory used by other sections.
</p>
</li>
<li>
<p>
Initialize MMU and cache.
</p>
</li>
<li>
<p>
Copy the sections from its load to the runtime areas with <em>bsp_start_copy_sections</em>.
</p>
</li>
<li>
<p>
Clear the BSS section (zero-initialized read-write data) with <em>bsp_start_clear_bss</em>.
</p>
</li>
</ul></div>
</li>
<li>
<p>
The hook returns and the start code calls <em>boot_card</em>. This function will not return.
</p>
</li>
</ol></div>
<div class="paragraph"><p>Depending on the system the start hooks must only use code and data that resides in the start region. For this purpose
a <em>bsp_start_memcpy</em> function is provided. This memory copy variant executes from the stack and may be used to
initialize memory attributes of the currently running code.</p></div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2013-06-18 11:44:28 CEST
</div>
</div>
</body>
</html>