1 | @c |
---|
2 | @c COPYRIGHT (c) 1988-1998. |
---|
3 | @c On-Line Applications Research Corporation (OAR). |
---|
4 | @c All rights reserved. |
---|
5 | @c |
---|
6 | @c $Id$ |
---|
7 | @c |
---|
8 | |
---|
9 | @chapter Initialization Code |
---|
10 | |
---|
11 | @section Introduction |
---|
12 | |
---|
13 | The initialization code is the first piece of code executed when there's a |
---|
14 | reset/reboot. Its purpose is to initialize the board for the application. |
---|
15 | This chapter contains a narrative description of the initialization |
---|
16 | process followed by a description of each of the files and routines |
---|
17 | commonly found in the BSP related to initialization. The remainder of |
---|
18 | this chapter covers special issues which require attention such |
---|
19 | as interrupt vector table and chip select initialization. |
---|
20 | |
---|
21 | Most of the examples in this chapter will be based on the gen68340 BSP |
---|
22 | initialization code. Like most BSPs, the initialization for this |
---|
23 | BSP is divided into two subdirectories under the BSP source directory. |
---|
24 | The gen68340 BSP source code is in the following directory: |
---|
25 | |
---|
26 | @example |
---|
27 | c/src/lib/libbsp/m68k/gen68340 |
---|
28 | @end example |
---|
29 | |
---|
30 | The following source code files are in this subdirectory. |
---|
31 | |
---|
32 | @itemize @bullet |
---|
33 | |
---|
34 | @item @code{start340}: assembly language code which contains early |
---|
35 | initialization routines |
---|
36 | |
---|
37 | @item @code{startup}: C code with higher level routines (RTEMS |
---|
38 | initialization related) |
---|
39 | |
---|
40 | @end itemize |
---|
41 | |
---|
42 | @b{NOTE:} The directory @code{start340} is simply named @code{start} or |
---|
43 | start followed by a BSP designation. |
---|
44 | |
---|
45 | In the @code{start340} directory are two source files. The file |
---|
46 | @code{startfor340only.s} is the simpler of these files as it only has |
---|
47 | initialization code for a MC68340 board. The file @code{start340.s} |
---|
48 | contains initialization for a 68349 based board as well. |
---|
49 | |
---|
50 | @section Required Global Variables |
---|
51 | |
---|
52 | Although not strictly part of initialization, there are a few global |
---|
53 | variables assumed to exist by many support components. These |
---|
54 | global variables are usually declared in the file @code{startup/bspstart.c} |
---|
55 | that provides most of the BSP specific initialization. The following is |
---|
56 | a list of these global variables: |
---|
57 | |
---|
58 | @itemize @bullet |
---|
59 | @item @code{BSP_Configuration} is the BSP's writable copy of the RTEMS |
---|
60 | Configuration Table. |
---|
61 | |
---|
62 | @item @code{Cpu_table} is the RTEMS CPU Dependent Information Table. |
---|
63 | |
---|
64 | @item @code{bsp_isr_level} is the interrupt level that is set at |
---|
65 | system startup. It will be restored when the executive returns |
---|
66 | control to the BSP. |
---|
67 | |
---|
68 | @end itemize |
---|
69 | |
---|
70 | @section Board Initialization |
---|
71 | |
---|
72 | This section describes the steps an application goes through from the |
---|
73 | time the first BSP code is executed until the first application task |
---|
74 | executes. The routines invoked during this will be discussed and |
---|
75 | their location in the RTEMS source tree pointed out. |
---|
76 | |
---|
77 | @subsection Start Code - Assembly Language Initialization |
---|
78 | |
---|
79 | The assembly language code in the directory @code{start} is |
---|
80 | the first part of the application to execute. It is |
---|
81 | responsible for initializing the processor and board enough to execute |
---|
82 | the rest of the BSP. This includes: |
---|
83 | |
---|
84 | @itemize @bullet |
---|
85 | @item initializing the stack |
---|
86 | @item zeroing out the uninitialized data section @code{.bss} |
---|
87 | @item disabling external interrupts |
---|
88 | @item copy the initialized data from ROM to RAM |
---|
89 | @end itemize |
---|
90 | |
---|
91 | The general rule of thumb is that the |
---|
92 | start code in assembly should do the minimum necessary to allow C code |
---|
93 | to execute to complete the initialization sequence. |
---|
94 | |
---|
95 | The initial assembly language start code completes its execution by |
---|
96 | invoking the shared routine @code{boot_card()}. |
---|
97 | |
---|
98 | @subsection boot_card() - Boot the Card |
---|
99 | |
---|
100 | The @code{boot_card()} is the first C code invoked. Most of the BSPs |
---|
101 | use the same shared version of @code{boot_card()} which is located in |
---|
102 | the following file: |
---|
103 | |
---|
104 | @example |
---|
105 | c/src/lib/libbsp/shared/main.c |
---|
106 | @end example |
---|
107 | |
---|
108 | The @code{boot_card()} routine performs the following functions: |
---|
109 | |
---|
110 | @itemize @bullet |
---|
111 | |
---|
112 | @item initializes the shared fields of the CPU Configuration Table |
---|
113 | (variable name @code{Cpu_table}) to a default state, |
---|
114 | |
---|
115 | @item copies the application's RTEMS Configuration Table |
---|
116 | (variable name @code{Configuration}) to the BSP's Configuration |
---|
117 | Table (variable name @code{BSP_Configuration}) so it can be modified |
---|
118 | as necessary without copying the original table, |
---|
119 | |
---|
120 | @item invokes the BSP specific routine @code{bsp_start()}, |
---|
121 | |
---|
122 | @item invokes the RTEMS directive @code{rtems_initialize_executive_early()} |
---|
123 | to initialize the executive, C Library, and all device drivers but |
---|
124 | return without initiating multitasking or enabling interrupts, |
---|
125 | |
---|
126 | @item invokes the shared @code{main()} in the same file as |
---|
127 | @code{boot_card()} which does not return until the |
---|
128 | @code{rtems_shutdown_executive} directive is called, and |
---|
129 | |
---|
130 | @item invokes the BSP specific routine @code{bsp_cleanup()} to perform |
---|
131 | any necessary board specific shutdown actions. |
---|
132 | |
---|
133 | @end itemize |
---|
134 | |
---|
135 | It is important to note that the executive and much of the |
---|
136 | support environment must be initialized before invoking @code{main()}. |
---|
137 | |
---|
138 | @subsection bsp_start() - BSP Specific Initialization |
---|
139 | |
---|
140 | This is the first BSP specific C routine to execute during system |
---|
141 | initialization. This routine often performs required fundamental |
---|
142 | hardware initialization such as setting bus controller registers |
---|
143 | that do not have a direct impact on whether or not C code can execute. |
---|
144 | The source code for this routine is usually found in the following |
---|
145 | file: |
---|
146 | |
---|
147 | @example |
---|
148 | c/src/lib/libbsp/CPU/BSP/startup/bspstart.c |
---|
149 | @end example |
---|
150 | |
---|
151 | This routine is also responsible for overriding the default settings |
---|
152 | in the CPU Configuration Table and setting port specific entries |
---|
153 | in this table. This may include increasing the maximum number |
---|
154 | of some types of RTEMS system objects to reflect the needs of |
---|
155 | the BSP and the base set of device drivers. This routine will |
---|
156 | typically also install routines for one or more of the following |
---|
157 | initialization hooks: |
---|
158 | |
---|
159 | @itemize @bullet |
---|
160 | @item BSP Pretasking Hook |
---|
161 | @item BSP Predriver Hook |
---|
162 | @item BSP Postdriver Hook |
---|
163 | @end itemize |
---|
164 | |
---|
165 | One of the most important functions performed by this routine |
---|
166 | is determining where the RTEMS Executive Work Space is to be |
---|
167 | located in memory. All RTEMS objects and task stacks will be |
---|
168 | allocated from this Workspace. The RTEMS Workspace is distinct |
---|
169 | from the application heap used for @code{malloc()}. |
---|
170 | |
---|
171 | Many BSPs place this area at the end of RAM although this is |
---|
172 | certainly not a requirement. |
---|
173 | |
---|
174 | After completing execution, this routine returns to the |
---|
175 | @code{boot_card()} routine. |
---|
176 | |
---|
177 | @subsection main() - C Main |
---|
178 | |
---|
179 | This routine is the C main entry point. This is a special routine |
---|
180 | and the GNU Compiler Suite treats it as such. The GNU C Compiler |
---|
181 | recognizes @code{main()} and automatically inserts a call to the |
---|
182 | compiler run-time support routine @code{__main()} as the first |
---|
183 | code executed in @code{main()}. |
---|
184 | |
---|
185 | The routine @code{__main()} initializes the compiler's basic run-time |
---|
186 | support library and, most importantly, invokes the C++ global |
---|
187 | constructors. |
---|
188 | |
---|
189 | The precise placement of when @code{main()} is invoked in the |
---|
190 | RTEMS initialization sequence insures that C Library and non-blocking |
---|
191 | calls can be made in global C++ constructors. |
---|
192 | |
---|
193 | The shared implementation of this routine is located in the following file: |
---|
194 | |
---|
195 | @example |
---|
196 | c/src/lib/libbsp/shared/main.c |
---|
197 | @end example |
---|
198 | |
---|
199 | In addition to the implicit invocation of @code{__main}, this |
---|
200 | routine performs some explicit initialization. This routine |
---|
201 | sets the variable @code{rtems_progname} and initiates |
---|
202 | multitasking via a call to the RTEMS directive |
---|
203 | @code{rtems_initialize_executive_late}. It is important to note |
---|
204 | that the executive does not return to this routine until the |
---|
205 | RTEMS directive @code{rtems_shutdown_executive} is invoked. |
---|
206 | |
---|
207 | The RTEMS initialization procedure is described in the @b{Initialization |
---|
208 | Manager} chapter of the @b{RTEMS Application C User's Guide}. |
---|
209 | Please refer to that manual for more information. |
---|
210 | |
---|
211 | @subsection RTEMS Pretasking Callback |
---|
212 | |
---|
213 | The @code{pretasking_hook} entry in the RTEMS CPU Configuration |
---|
214 | Table may be the address of a user provided routine that is |
---|
215 | invoked once RTEMS API initialization is complete but before interrupts |
---|
216 | and tasking are enabled. No tasks -- not even the IDLE task -- have |
---|
217 | been created when this hook is invoked. The pretasking hook is optional. |
---|
218 | |
---|
219 | Although optional, most of the RTEMS BSPs provide a pretasking hook |
---|
220 | callback. This routine is usually called @code{bsp_pretasking_hook} |
---|
221 | and is found in the file: |
---|
222 | |
---|
223 | @example |
---|
224 | c/src/lib/libbsp/CPU/BSP/startup/bspstart.c |
---|
225 | @end example |
---|
226 | |
---|
227 | The @code{bsp_pretasking_hook()} routine is the appropriate place to |
---|
228 | initialize any support components which depend on the RTEMS APIs. |
---|
229 | Most BSPs set the debug level for the system and initialize the |
---|
230 | RTEMS C Library support in their |
---|
231 | implementation of @code{bsp_pretasking_hook()}. This initialization |
---|
232 | includes the application heap used by the @code{malloc} family |
---|
233 | of routines as well as the reentrancy support for the C Library. |
---|
234 | |
---|
235 | The routine @code{bsp_libc_init} routine invoked from the |
---|
236 | @code{bsp_pretasking_hook()} routine is passed the starting |
---|
237 | address, length, and growth amount passed to @code{sbrk}. |
---|
238 | This "sbrk amount" is only used if the heap runs out of |
---|
239 | memory. In this case, the RTEMS malloc implementation will |
---|
240 | invoked @code{sbrk} to obtain more memory. See |
---|
241 | @ref{Miscellaneous Support Files sbrk() Implementation} for more details. |
---|
242 | |
---|
243 | @subsection RTEMS Predriver Callback |
---|
244 | |
---|
245 | The @code{predriver_hook} entry in the RTEMS CPU Configuration |
---|
246 | Table may be the address of a user provided routine that is |
---|
247 | is invoked immediately before the the device drivers and MPCI |
---|
248 | are initialized. RTEMS |
---|
249 | initialization is complete but interrupts and tasking are disabled. |
---|
250 | This field may be NULL to indicate that the hook is not utilized. |
---|
251 | |
---|
252 | Most BSPs do not use this callback. |
---|
253 | |
---|
254 | @subsection Device Driver Initialization |
---|
255 | |
---|
256 | At this point in the initialization sequence, the initialization |
---|
257 | routines for all of the device drivers specified in the Device |
---|
258 | Driver Table are invoked. The initialization routines are invoked |
---|
259 | in the order they appear in the Device Driver Table. |
---|
260 | |
---|
261 | The Driver Address Table is part of the RTEMS Configuration Table. It |
---|
262 | defines device drivers entry points (initialization, open, close, read, |
---|
263 | write, and control). For more information about this table, please |
---|
264 | refer to the @b{Configuring a System} chapter in the |
---|
265 | @b{RTEMS Application C User's Guide}. |
---|
266 | |
---|
267 | The RTEMS initialization procedure calls the initialization function for |
---|
268 | every driver defined in the RTEMS Configuration Table (this allows |
---|
269 | one to include only the drivers needed by the application). |
---|
270 | |
---|
271 | All these primitives have a major and a minor number as arguments: |
---|
272 | |
---|
273 | @itemize @bullet |
---|
274 | |
---|
275 | @item the major number refers to the driver type, |
---|
276 | |
---|
277 | @item the minor number is used to control two peripherals with the same |
---|
278 | driver (for instance, we define only one major number for the serial |
---|
279 | driver, but two minor numbers for channel A and B if there are two |
---|
280 | channels in the UART). |
---|
281 | |
---|
282 | @end itemize |
---|
283 | |
---|
284 | @subsection RTEMS Postdriver Callback |
---|
285 | |
---|
286 | The @code{postdriver_hook} entry in the RTEMS CPU Configuration |
---|
287 | Table may be the address of a user provided routine that is |
---|
288 | invoked immediately after the the device drivers and MPCI are initialized. |
---|
289 | Interrupts and tasking are disabled. The postdriver hook is optional. |
---|
290 | |
---|
291 | Although optional, most of the RTEMS BSPs provide a postdriver hook |
---|
292 | callback. This routine is usually called @code{bsp_postdriver_hook} |
---|
293 | and is found in the file: |
---|
294 | |
---|
295 | @example |
---|
296 | c/src/lib/libbsp/CPU/BSP/startup/bsppost.c |
---|
297 | @end example |
---|
298 | |
---|
299 | The @code{bsp_postdriver_hook()} routine is the appropriate place to |
---|
300 | perform initialization that must be performed before the first task |
---|
301 | executes but requires that a device driver be initialized. The |
---|
302 | shared implementation of the postdriver hook opens the default |
---|
303 | standard in, out, and error files and associates them with |
---|
304 | @code{/dev/console}. |
---|
305 | |
---|
306 | @section The Interrupt Vector Table |
---|
307 | |
---|
308 | The Interrupt Vector Table is called different things on different |
---|
309 | processor families but the basic functionality is the same. Each |
---|
310 | entry in the Table corresponds to the handler routine for a particular |
---|
311 | interrupt source. When an interrupt from that source occurs, the |
---|
312 | specified handler routine is invoked. Some context information is |
---|
313 | saved by the processor automatically when this happens. RTEMS saves |
---|
314 | enough context information so that an interrupt service routine |
---|
315 | can be implemented in a high level language. |
---|
316 | |
---|
317 | On some processors, the Interrupt Vector Table is at a fixed address. If |
---|
318 | this address is in RAM, then usually the BSP only has to initialize |
---|
319 | it to contain pointers to default handlers. If the table is in ROM, |
---|
320 | then the application developer will have to take special steps to |
---|
321 | fill in the table. |
---|
322 | |
---|
323 | If the base address of the Interrupt Vector Table can be dynamically |
---|
324 | changed to an arbitrary address, then the RTEMS port to that processor |
---|
325 | family will usually allocate its own table and install it. For example, |
---|
326 | on some members of the Motorola MC68xxx family, the Vector Base Register |
---|
327 | (@code{vbr}) contains this base address. |
---|
328 | |
---|
329 | @subsection Interrupt Vector Table on the gen68340 BSP |
---|
330 | |
---|
331 | The gen68340 BSP provides a default Interrupt Vector Table in the |
---|
332 | file @code{$BSP_ROOT/start340/start340.s}. After the @code{entry} |
---|
333 | label is the definition of space reserved for the table of |
---|
334 | interrupts vectors. This space is assigned the symbolic name |
---|
335 | of @code{__uhoh} in the @code{gen68340} BSP. |
---|
336 | |
---|
337 | At @code{__uhoh} label is the default interrupt handler routine. This |
---|
338 | routine is only called when an unexpected interrupts is raised. One can |
---|
339 | add their own routine there (in that case there's a call to a routine - |
---|
340 | $BSP_ROOT/startup/dumpanic.c - that prints which address caused the |
---|
341 | interrupt and the contents of the registers, stack, etc.), but this should |
---|
342 | not return. |
---|
343 | |
---|
344 | @section Chip Select Initialization |
---|
345 | |
---|
346 | When the microprocessor accesses a memory area, address decoding is |
---|
347 | handled by an address decoder, so that the microprocessor knows which |
---|
348 | memory chip(s) to access. The following figure illustrates this: |
---|
349 | |
---|
350 | @example |
---|
351 | @group |
---|
352 | +-------------------+ |
---|
353 | ------------| | |
---|
354 | ------------| |------------ |
---|
355 | ------------| Address |------------ |
---|
356 | ------------| Decoder |------------ |
---|
357 | ------------| |------------ |
---|
358 | ------------| | |
---|
359 | +-------------------+ |
---|
360 | CPU Bus Chip Select |
---|
361 | @end group |
---|
362 | @end example |
---|
363 | |
---|
364 | |
---|
365 | The Chip Select registers must be programmed such that they match |
---|
366 | the @code{linkcmds} settings. In the gen68340 BSP, ROM and RAM |
---|
367 | addresses can be found in both the @code{linkcmds} and initialization |
---|
368 | code, but this is not a great way to do this. It is better to |
---|
369 | define addresses in the linker script. |
---|
370 | |
---|
371 | @section Integrated Processor Registers Initialization |
---|
372 | |
---|
373 | The CPUs used in many embedded systems are highly complex devices |
---|
374 | with multiple peripherals on the CPU itself. For these devices, |
---|
375 | there are always some specific integrated processor registers |
---|
376 | that must be initialized. Refer to the processors' manuals for |
---|
377 | details on these registers and be VERY careful programming them. |
---|
378 | |
---|
379 | @section Data Section Recopy |
---|
380 | |
---|
381 | The next initialization part can be found in |
---|
382 | @code{$BSP340_ROOT/start340/init68340.c}. First the Interrupt |
---|
383 | Vector Table is copied into RAM, then the data section recopy is initiated |
---|
384 | (_CopyDataClearBSSAndStart in @code{$BSP340_ROOT/start340/startfor340only.s}). |
---|
385 | |
---|
386 | This code performs the following actions: |
---|
387 | |
---|
388 | @itemize @bullet |
---|
389 | |
---|
390 | @item copies the .data section from ROM to its location reserved in RAM |
---|
391 | (see @ref{Linker Script Initialized Data} for more details about this copy), |
---|
392 | |
---|
393 | @item clear @code{.bss} section (all the non-initialized |
---|
394 | data will take value 0). |
---|
395 | |
---|
396 | @end itemize |
---|
397 | |
---|
398 | @section RTEMS-Specific Initialization |
---|
399 | |
---|
400 | @section The RTEMS configuration table |
---|
401 | |
---|
402 | The RTEMS configuration table contains the maximum number of objects RTEMS |
---|
403 | can handle during the application (e.g. maximum number of tasks, |
---|
404 | semaphores, etc.). It's used to allocate the size for the RTEMS inner data |
---|
405 | structures. |
---|
406 | |
---|
407 | The RTEMS configuration table is application dependent, which means that |
---|
408 | one has to provide one per application. It is usually defined |
---|
409 | by defining macros and including the header file @code{<confdefs.h>}. |
---|
410 | In simple applications such as the tests provided with RTEMS, it is |
---|
411 | commonly found in the main module of the application. For more complex |
---|
412 | applications, it may be in a file by itself. |
---|
413 | |
---|
414 | The header file @code{<confdefs.h>} defines a constant table named |
---|
415 | @code{Configuration}. It is common practice for the BSP to copy |
---|
416 | this table into a modifiable copy named @code{BSP_Configuration}. |
---|
417 | This copy of the table is modified to define the base address of the |
---|
418 | RTEMS Executive Workspace as well as to reflect any BSP and |
---|
419 | device driver requirements not automatically handled by the application. |
---|
420 | |
---|
421 | For more information on the RTEMS Configuration Table, refer to the |
---|
422 | @b{RTEMS Application C User's Guide}. |
---|
423 | |
---|