source: rtems-docs/bsp_howto/initilization_code.rst @ a1c7180

4.115
Last change on this file since a1c7180 was 6d7a4d2, checked in by Chris Johns <chrisj@…>, on 06/17/16 at 05:05:41

Update the BSP howto.

Closes #2590.

  • Property mode set to 100644
File size: 17.0 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. COMMENT: COPYRIGHT (c) 1988-2008.
4.. COMMENT: On-Line Applications Research Corporation (OAR).
5.. COMMENT: All rights reserved.
6
7Initialization Code
8###################
9
10Introduction
11============
12
13The initialization code is the first piece of code executed when there's a
14reset/reboot. Its purpose is to initialize the board for the application.  This
15chapter contains a narrative description of the initialization process followed
16by a description of each of the files and routines commonly found in the BSP
17related to initialization.  The remainder of this chapter covers special issues
18which require attention such as interrupt vector table and chip select
19initialization.
20
21Most of the examples in this chapter will be based on the SPARC/ERC32 and
22m68k/gen68340 BSP initialization code.  Like most BSPs, the initialization for
23these BSP is divided into two subdirectories under the BSP source directory.
24The BSP source code for these BSPs is in the following directories:
25
26.. code:: c
27
28    c/src/lib/libbsp/m68k/gen68340
29    c/src/lib/libbsp/sparc/erc32
30
31Both BSPs contain startup code written in assembly language and C.  The
32gen68340 BSP has its early initialization start code in the ``start340``
33subdirectory and its C startup code in the ``startup`` directory.  In the
34``start340`` directory are two source files.  The file ``startfor340only.s`` is
35the simpler of these files as it only has initialization code for a MC68340
36board.  The file ``start340.s`` contains initialization for a 68349 based board
37as well.
38
39Similarly, the ERC32 BSP has startup code written in assembly language and C.
40However, this BSP shares this code with other SPARC BSPs.  Thus the
41``Makefile.am`` explicitly references the following files for this
42functionality.
43
44.. code:: c
45
46    ../../sparc/shared/start.S
47
48.. note::
49
50   In most BSPs, the directory named ``start340`` in the gen68340 BSP would be
51   simply named ``start`` or start followed by a BSP designation.
52
53Required Global Variables
54=========================
55
56Although not strictly part of initialization, there are a few global variables
57assumed to exist by reusable device drivers.  These global variables should
58only defined by the BSP when using one of these device drivers.
59
60The BSP author probably should be aware of the ``Configuration`` Table
61structure generated by ``<rtems/confdefs.h>`` during debug but should not
62explicitly reference it in the source code.  There are helper routines provided
63by RTEMS to access individual fields.
64
65In older RTEMS versions, the BSP included a number of required global
66variables.  We have made every attempt to eliminate these in the interest of
67simplicity.
68
69Board Initialization
70====================
71
72This section describes the steps an application goes through from the time the
73first BSP code is executed until the first application task executes.
74
75The initialization flows from assembly language start code to the shared
76``bootcard.c`` framework then through the C Library, RTEMS, device driver
77initialization phases, and the context switch to the first application task.
78After this, the application executes until it calls ``exit``,
79``rtems_shutdown_executive``, or some other normal termination initiating
80routine and a fatal system state is reached.  The optional
81``bsp_fatal_extension`` initial extension can perform BSP specific system
82termination.
83
84The routines invoked during this will be discussed and their location in the
85RTEMS source tree pointed out as we discuss each.
86
87Start Code - Assembly Language Initialization
88---------------------------------------------
89
90The assembly language code in the directory ``start`` is the first part of the
91application to execute.  It is responsible for initializing the processor and
92board enough to execute the rest of the BSP.  This includes:
93
94- initializing the stack
95
96- zeroing out the uninitialized data section ``.bss``
97
98- disabling external interrupts
99
100- copy the initialized data from ROM to RAM
101
102The general rule of thumb is that the start code in assembly should do the
103minimum necessary to allow C code to execute to complete the initialization
104sequence.
105
106The initial assembly language start code completes its execution by invoking
107the shared routine ``boot_card()``.
108
109The label (symbolic name) associated with the starting address of the program
110is typically called ``start``.  The start object file is the first object file
111linked into the program image so it is ensured that the start code is at offset
1120 in the ``.text`` section.  It is the responsibility of the linker script in
113conjunction with the compiler specifications file to put the start code in the
114correct location in the application image.
115
116boot_card() - Boot the Card
117---------------------------
118
119The ``boot_card()`` is the first C code invoked.  This file is the core
120component in the RTEMS BSP Initialization Framework and provides the proper
121sequencing of initialization steps for the BSP, RTEMS and device drivers. All
122BSPs use the same shared version of ``boot_card()`` which is located in the
123following file:
124
125.. code:: c
126
127    c/src/lib/libbsp/shared/bootcard.c
128
129The ``boot_card()`` routine performs the following functions:
130
131- It disables processor interrupts.
132
133- It sets the command line argument variables
134  for later use by the application.
135
136- It invokes the BSP specific routine ``bsp_work_area_initialize()`` which is
137  supposed to initialize the RTEMS Workspace and the C Program Heap.  Usually
138  the default implementation in ``c/src/lib/libbsp/shared/bspgetworkarea.c``
139  should be sufficient.  Custom implementations can use
140  ``bsp_work_area_initialize_default()`` or
141  ``bsp_work_area_initialize_with_table()`` available as inline functions
142  from``#include <bsp/bootcard.h>``.
143
144- It invokes the BSP specific routine ``bsp_start()`` which is written in C and
145  thus able to perform more advanced initialization.  Often MMU, bus and
146  interrupt controller initialization occurs here.  Since the RTEMS Workspace
147  and the C Program Heap was already initialized by
148  ``bsp_work_area_initialize()``, this routine may use ``malloc()``, etc.
149
150- It invokes the RTEMS directive ``rtems_initialize_data_structures()`` to
151  initialize the RTEMS executive to a state where objects can be created but
152  tasking is not enabled.
153
154- It invokes the BSP specific routine ``bsp_libc_init()`` to initialize the C
155  Library.  Usually the default implementation in
156  ``c/src/lib/libbsp/shared/bsplibc.c`` should be sufficient.
157
158- It invokes the RTEMS directive ``rtems_initialize_before_drivers()`` to
159  initialize the MPCI Server thread in a multiprocessor configuration and
160  execute API specific extensions.
161
162- It invokes the BSP specific routine ``bsp_predriver_hook``. For most BSPs,
163  the implementation of this routine does nothing.
164
165- It invokes the RTEMS directive ``rtems_initialize_device_drivers()`` to
166  initialize the statically configured set of device drivers in the order they
167  were specified in the Configuration Table.
168
169- It invokes the BSP specific routine ``bsp_postdriver_hook``. For
170  most BSPs, the implementation of this routine does nothing.  However, some
171  BSPs use this hook and perform some initialization which must be done at
172  this point in the initialization sequence.  This is the last opportunity
173  for the BSP to insert BSP specific code into the initialization sequence.
174
175- It invokes the RTEMS directive ``rtems_initialize_start_multitasking()``
176  which initiates multitasking and performs a context switch to the first user
177  application task and may enable interrupts as a side-effect of that context
178  switch.  The context switch saves the executing context.  The application
179  runs now.  The directive ``rtems_shutdown_executive()`` will return to the
180  saved context.  The ``exit()`` function will use this directive.  After a
181  return to the saved context a fatal system state is reached.  The fatal
182  source is ``RTEMS_FATAL_SOURCE_EXIT`` with a fatal code set to the value
183  passed to rtems_shutdown_executive().  The enabling of interrupts during the
184  first context switch is often the source for fatal errors during BSP
185  development because the BSP did not clear and/or disable all interrupt
186  sources and a spurious interrupt will occur.  When in the context of the
187  first task but before its body has been entered, any C++ Global Constructors
188  will be invoked.
189
190That's it.  We just went through the entire sequence.
191
192bsp_work_area_initialize() - BSP Specific Work Area Initialization
193------------------------------------------------------------------
194
195This is the first BSP specific C routine to execute during system
196initialization.  It must initialize the support for allocating memory from the
197C Program Heap and RTEMS Workspace commonly referred to as the work areas.
198Many BSPs place the work areas at the end of RAM although this is certainly not
199a requirement.  Usually the default implementation
200in:file:`c/src/lib/libbsp/shared/bspgetworkarea.c` should be sufficient.
201Custom implementations can use ``bsp_work_area_initialize_default()``
202or``bsp_work_area_initialize_with_table()`` available as inline functions from
203``#include <bsp/bootcard.h>``.
204
205bsp_start() - BSP Specific Initialization
206-----------------------------------------
207
208This is the second BSP specific C routine to execute during system
209initialization.  It is called right after ``bsp_work_area_initialize()``.  The
210``bsp_start()`` routine often performs required fundamental hardware
211initialization such as setting bus controller registers that do not have a
212direct impact on whether or not C code can execute.  The interrupt controllers
213are usually initialized here.  The source code for this routine is usually
214found in the file :file:`c/src/lib/libbsp/${CPU}/${BSP}/startup/bspstart.c`.
215It is not allowed to create any operating system objects, e.g. RTEMS
216semaphores.
217
218After completing execution, this routine returns to the ``boot_card()``
219routine.  In case of errors, the initialization should be terminated via
220``bsp_fatal()``.
221
222bsp_predriver_hook() - BSP Specific Predriver Hook
223--------------------------------------------------
224
225The ``bsp_predriver_hook()`` method is the BSP specific routine that is invoked
226immediately before the the device drivers are initialized. RTEMS initialization
227is complete but interrupts and tasking are disabled.
228
229The BSP may use the shared version of this routine which is empty.  Most BSPs
230do not provide a specific implementation of this callback.
231
232Device Driver Initialization
233----------------------------
234
235At this point in the initialization sequence, the initialization routines for
236all of the device drivers specified in the Device Driver Table are invoked.
237The initialization routines are invoked in the order they appear in the Device
238Driver Table.
239
240The Driver Address Table is part of the RTEMS Configuration Table. It defines
241device drivers entry points (initialization, open, close, read, write, and
242control). For more information about this table, please refer to the
243*Configuring a System* chapter in the *RTEMS Application C User's Guide*.
244
245The RTEMS initialization procedure calls the initialization function for every
246driver defined in the RTEMS Configuration Table (this allows one to include
247only the drivers needed by the application).
248
249All these primitives have a major and a minor number as arguments:
250
251- the major number refers to the driver type,
252
253- the minor number is used to control two peripherals with the same driver (for
254  instance, we define only one major number for the serial driver, but two
255  minor numbers for channel A and B if there are two channels in the UART).
256
257RTEMS Postdriver Callback
258-------------------------
259
260The ``bsp_postdriver_hook()`` BSP specific routine is invoked immediately after
261the the device drivers and MPCI are initialized.  Interrupts and tasking are
262disabled.
263
264Most BSPs use the shared implementation of this routine which is responsible
265for opening the device ``/dev/console`` for standard input, output and error if
266the application has configured the Console Device Driver.  This file is located
267at:
268
269.. code:: c
270
271    c/src/lib/libbsp/shared/bsppost.c
272
273The Interrupt Vector Table
274==========================
275
276The Interrupt Vector Table is called different things on different processor
277families but the basic functionality is the same.  Each entry in the Table
278corresponds to the handler routine for a particular interrupt source.  When an
279interrupt from that source occurs, the specified handler routine is invoked.
280Some context information is saved by the processor automatically when this
281happens.  RTEMS saves enough context information so that an interrupt service
282routine can be implemented in a high level language.
283
284On some processors, the Interrupt Vector Table is at a fixed address.  If this
285address is in RAM, then usually the BSP only has to initialize it to contain
286pointers to default handlers.  If the table is in ROM, then the application
287developer will have to take special steps to fill in the table.
288
289If the base address of the Interrupt Vector Table can be dynamically changed to
290an arbitrary address, then the RTEMS port to that processor family will usually
291allocate its own table and install it.  For example, on some members of the
292Motorola MC68xxx family, the Vector Base Register (``vbr``) contains this base
293address.
294
295Interrupt Vector Table on the gen68340 BSP
296------------------------------------------
297
298The gen68340 BSP provides a default Interrupt Vector Table in the file
299``$BSP_ROOT/start340/start340.s``.  After the ``entry`` label is the definition
300of space reserved for the table of interrupts vectors.  This space is assigned
301the symbolic name of ``__uhoh`` in the ``gen68340`` BSP.
302
303At ``__uhoh`` label is the default interrupt handler routine. This routine is
304only called when an unexpected interrupts is raised.  One can add their own
305routine there (in that case there's a call to a routine -
306$BSP_ROOT/startup/dumpanic.c - that prints which address caused the interrupt
307and the contents of the registers, stack, etc.), but this should not return.
308
309Chip Select Initialization
310==========================
311
312When the microprocessor accesses a memory area, address decoding is handled by
313an address decoder, so that the microprocessor knows which memory chip(s) to
314access.  The following figure illustrates this:
315
316.. code::
317
318    +-------------------+
319    ------------|                   |
320    ------------|                   |------------
321    ------------|      Address      |------------
322    ------------|      Decoder      |------------
323    ------------|                   |------------
324    ------------|                   |
325    +-------------------+
326    CPU Bus                           Chip Select
327
328The Chip Select registers must be programmed such that they match the
329``linkcmds`` settings. In the gen68340 BSP, ROM and RAM addresses can be found
330in both the ``linkcmds`` and initialization code, but this is not a great way
331to do this.  It is better to define addresses in the linker script.
332
333Integrated Processor Registers Initialization
334=============================================
335
336The CPUs used in many embedded systems are highly complex devices with multiple
337peripherals on the CPU itself.  For these devices, there are always some
338specific integrated processor registers that must be initialized.  Refer to the
339processors' manuals for details on these registers and be VERY careful
340programming them.
341
342Data Section Recopy
343===================
344
345The next initialization part can be found in
346``$BSP340_ROOT/start340/init68340.c``. First the Interrupt Vector Table is
347copied into RAM, then the data section recopy is initiated
348(``_CopyDataClearBSSAndStart`` in ``$BSP340_ROOT/start340/startfor340only.s``).
349
350This code performs the following actions:
351
352- copies the .data section from ROM to its location reserved in RAM (see
353  `Initialized Data`_ for more details about this copy),
354
355- clear ``.bss`` section (all the non-initialized data will take value 0).
356
357The RTEMS Configuration Table
358=============================
359
360The RTEMS configuration table contains the maximum number of objects RTEMS can
361handle during the application (e.g. maximum number of tasks, semaphores,
362etc.). It's used to allocate the size for the RTEMS inner data structures.
363
364The RTEMS configuration table is application dependent, which means that one
365has to provide one per application. It is usually defined by defining macros
366and including the header file ``<rtems/confdefs.h>``.  In simple applications
367such as the tests provided with RTEMS, it is commonly found in the main module
368of the application.  For more complex applications, it may be in a file by
369itself.
370
371The header file ``<rtems/confdefs.h>`` defines a constant table named
372``Configuration``.  With RTEMS 4.8 and older, it was accepted practice for the
373BSP to copy this table into a modifiable copy named ``BSP_Configuration``.
374This copy of the table was modified to define the base address of the RTEMS
375Executive Workspace as well as to reflect any BSP and device driver
376requirements not automatically handled by the application.  In 4.9 and newer,
377we have eliminated the BSP copies of the configuration tables and are making
378efforts to make the configuration information generated by
379``<rtems/confdefs.h>`` constant and read only.
380
381For more information on the RTEMS Configuration Table, refer to the *RTEMS
382Application C User's Guide*.
Note: See TracBrowser for help on using the repository browser.