source: rtems/doc/bsp_howto/init.t @ 37030e3

Last change on this file since 37030e3 was 37030e3, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 9, 2015 at 7:05:57 AM

bsps: Call bsp_work_area_initialize() early

Call bsp_work_area_initialize() before bsp_start(). This allows
bsp_start() to use malloc() etc. which is beneficial for systems with a
plug-and-play hardware enumeration.

Update #2408.

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