Changeset 8a4f070 in rtems-libbsd for libbsd.txt
- Timestamp:
- 04/16/12 10:23:55 (12 years ago)
- Branches:
- 4.11, 5, 5-freebsd-12, 6-freebsd-12, freebsd-9.3, master
- Children:
- 362782e
- Parents:
- a3d2498
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libbsd.txt
ra3d2498 r8a4f070 262 262 direction. 263 263 264 == Initialization of RTEMS Libbsd 265 266 The initialization of the RTEMS Libbsd is based on the FreeBSD SYSINIT 267 infrastructure. This is simply because we are initializing a subset of 268 FreeBSD. For details refer to http://www.freebsd.org/cgi/man.cgi?query=SYSINIT&sektion=9&apropos=0&manpath=FreeBSD+9-current 269 270 The key to initializing a system is to ensure that the desired device 271 drivers are explicitly pulled into the linked application. This plus 272 linking against the Libsd library will pull in the necessary FreeBSD 273 infrastructure. The SYSINIT structures are automatically built at link 274 time and the various initialization routines will thus be executed in' 275 the correct order. 276 277 XXX This needs more details. 264 == Initialization of RTEMS libbsd 265 266 The initialization of the RTEMS libbsd is based on the FreeBSD SYSINIT(9) 267 infrastructure. The key to initializing a system is to ensure that the desired 268 device drivers are explicitly pulled into the linked application. This plus 269 linking against the libbsd library will pull in the necessary FreeBSD 270 infrastructure. 271 272 The FreeBSD kernel is not a library like the RTEMS kernel. It is a bunch of 273 object files linked together. If we have a library, then creating the 274 executable is simple. We begin with a start symbol and recursively resolve all 275 references. With a bunch of object files linked together we need a different 276 mechanism. Most object files don't know each other. Lets say we have a driver 277 module. The rest of the system has no references to this driver module. The 278 driver module needs a way to tell the rest of the system: Hey, kernel I am 279 here, please use my services! 280 281 This registration of independent components is performed by SYSINIT(9) and 282 specializations: 283 284 http://www.freebsd.org/cgi/man.cgi?query=SYSINIT 285 286 The SYSINIT(9) uses some global data structures that are placed in a certain 287 section. In the linker command file we need this: 288 289 [listing] 290 ---- 291 .robsdsets : { 292 _bsd__start_set_modmetadata_set = .; 293 *(_bsd_set_modmetadata_set); 294 _bsd__stop_set_modmetadata_set = .; 295 _bsd__start_set_sysctl_set = .; 296 *(_bsd_set_sysctl_set); 297 _bsd__stop_set_sysctl_set = .; 298 } > REGION_RODATA AT > REGION_RODATA_LOAD 299 300 .rwbsdsets : { 301 _bsd__start_set_sysinit_set = .; 302 *(_bsd_set_sysinit_set); 303 _bsd__stop_set_sysinit_set = .; 304 } > REGION_DATA AT > REGION_DATA_LOAD 305 ---- 306 307 Here you can see, that these global data structures are collected into 308 continuous memory areas. This memory area can be identified by start and stop 309 symbols. This constructs a table of uniform items. 310 311 The low level FreeBSD code calls at some time during the initialization the 312 mi_startup() function (machine independent startup). This function will sort 313 the SYSINIT(9) set and call handler functions which perform further 314 initialization. The last step is the scheduler invocation. 315 316 The SYSINIT(9) routines are run in mi_startup() which is called by 317 rtems_bsd_initialize(). 318 319 This is also explained in "The Design and Implementation of the FreeBSD 320 Operating System" section 14.3 "Kernel Initialization". 321 322 In RTEMS we have a library and not a bunch of object files. Thus we need a way 323 to pull-in the desired services out of the libbsd. Here the 324 "rtems-bsd-sysinit.h" comes into play. The SYSINIT(9) macros have been 325 modified and extended for RTEMS in "sys/kernel.h": 326 327 [listing] 328 ---- 329 #ifndef __rtems__ 330 #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ 331 static struct sysinit uniquifier ## _sys_init = { \ 332 subsystem, \ 333 order, \ 334 func, \ 335 (ident) \ 336 }; \ 337 DATA_SET(sysinit_set,uniquifier ## _sys_init) 338 #else /* __rtems__ */ 339 #define SYSINIT_ENTRY_NAME(uniquifier) \ 340 _bsd_ ## uniquifier ## _sys_init 341 #define SYSINIT_REFERENCE_NAME(uniquifier) \ 342 _bsd_ ## uniquifier ## _sys_init_ref 343 #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \ 344 struct sysinit SYSINIT_ENTRY_NAME(uniquifier) = { \ 345 subsystem, \ 346 order, \ 347 func, \ 348 (ident) \ 349 }; \ 350 DATA_SET(sysinit_set,SYSINIT_ENTRY_NAME(uniquifier)) 351 #define SYSINIT_REFERENCE(uniquifier) \ 352 extern struct sysinit SYSINIT_ENTRY_NAME(uniquifier); \ 353 static struct sysinit const * const \ 354 SYSINIT_REFERENCE_NAME(uniquifier) __used \ 355 = &SYSINIT_ENTRY_NAME(uniquifier) 356 #define SYSINIT_MODULE_REFERENCE(mod) \ 357 SYSINIT_REFERENCE(mod ## module) 358 #define SYSINIT_DRIVER_REFERENCE(driver, bus) \ 359 SYSINIT_MODULE_REFERENCE(driver ## _ ## bus) 360 #endif /* __rtems__ */ 361 ---- 362 363 Here you see that the SYSINIT(9) entries are no longer static. The 364 *_REFERENCE() macros will create references to the corresponding modules which 365 are later resolved by the linker. The application has to provide an object 366 file with references to all required FreeBSD modules. 367 368 The FreeBSD device model is quite elaborated (with follow-ups): 369 370 http://www.freebsd.org/cgi/man.cgi?query=driver 371 372 The devices form a tree with the Nexus device at a high-level. This Nexus 373 device is architecture specific in FreeBSD. In RTEMS we have our own Nexus 374 device, see "rtems-bsd-nexus.c". It uses a table to add child devices: 375 376 [listing] 377 ---- 378 const char *const _bsd_nexus_devices [] = { 379 #ifdef NEED_USB_OHCI 380 "ohci", 381 #endif 382 #ifdef NEED_USB_EHCI 383 "ehci", 384 #endif 385 #ifdef NEED_SDHC 386 "sdhci", 387 #endif 388 NULL 389 }; 390 ---- 391 392 This table must be provided by the application. 278 393 279 394 === SYSCTL_NODE Example
Note: See TracChangeset
for help on using the changeset viewer.