[libbsd 20/22] libbsd.txt: Move initialization details
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon May 23 14:33:43 UTC 2022
---
CONTRIBUTING.rst | 139 ++++++++++++++++++++++++++++++++++++++++++++
libbsd.txt | 147 -----------------------------------------------
2 files changed, 139 insertions(+), 147 deletions(-)
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index c1268121..99c778f6 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -453,3 +453,142 @@ the priority inheritance protocol.
* `SYSINIT(9) <http://www.freebsd.org/cgi/man.cgi?query=sysinit&sektion=9>`_: A framework for dynamic kernel initialization
* `TASKQUEUE(9) <http://www.freebsd.org/cgi/man.cgi?query=taskqueue&sektion=9>`_: Asynchronous task execution
* `UMA(9) <http://www.freebsd.org/cgi/man.cgi?query=uma&sektion=9>`_: General-purpose kernel object allocator
+
+LibBSD Initialization Details
+=============================
+
+The initialization of LibBSD is based on the FreeBSD
+`SYSINIT(9) <http://www.freebsd.org/cgi/man.cgi?query=sysinit&sektion=9>`_
+infrastructure. The key to initializing a system is to ensure that the desired
+device drivers are explicitly pulled into the linked application. This plus
+linking against the LibBSD (``libbsd.a``) will pull in the necessary FreeBSD
+infrastructure.
+
+The FreeBSD kernel is not a library like the RTEMS kernel. It is a bunch of
+object files linked together. If we have a library, then creating the
+executable is simple. We begin with a start symbol and recursively resolve all
+references. With a bunch of object files linked together we need a different
+mechanism. Most object files don't know each other. Lets say we have a driver
+module. The rest of the system has no references to this driver module. The
+driver module needs a way to tell the rest of the system: Hey, kernel I am
+here, please use my services!
+
+This registration of independent components is performed by SYSINIT(9) and
+specializations
+
+The SYSINIT(9) uses some global data structures that are placed in a certain
+section. In the linker command file we need this:
+
+.. code-block:: none
+
+ .rtemsroset : {
+ KEEP (*(SORT(.rtemsroset.*)))
+ }
+
+ .rtemsrwset : {
+ KEEP (*(SORT(.rtemsrwset.*)))
+ }
+
+This results for example in this executable layout:
+
+.. code-block:: none
+
+ [...]
+ *(SORT(.rtemsroset.*))
+ .rtemsroset.bsd.modmetadata_set.begin
+ 0x000000000025fe00 0x0 libbsd.a(rtems-bsd-init.o)
+ 0x000000000025fe00 _bsd__start_set_modmetadata_set
+ .rtemsroset.bsd.modmetadata_set.content
+ 0x000000000025fe00 0x8 libbsd.a(rtems-bsd-nexus.o)
+ .rtemsroset.bsd.modmetadata_set.content
+ 0x000000000025fe08 0x4 libbsd.a(kern_module.o)
+ [...]
+ .rtemsroset.bsd.modmetadata_set.content
+ 0x000000000025fe68 0x4 libbsd.a(mii.o)
+ .rtemsroset.bsd.modmetadata_set.content
+ 0x000000000025fe6c 0x4 libbsd.a(mii_bitbang.o)
+ .rtemsroset.bsd.modmetadata_set.end
+ 0x000000000025fe70 0x0 libbsd.a(rtems-bsd-init.o)
+ 0x000000000025fe70 _bsd__stop_set_modmetadata_set
+ [...]
+ .rtemsrwset 0x000000000030bad0 0x290
+ *(SORT(.rtemsrwset.*))
+ .rtemsrwset.bsd.sysinit_set.begin
+ 0x000000000030bad0 0x0 libbsd.a(rtems-bsd-init.o)
+ 0x000000000030bad0 _bsd__start_set_sysinit_set
+ .rtemsrwset.bsd.sysinit_set.content
+ 0x000000000030bad0 0x4 libbsd.a(rtems-bsd-nexus.o)
+ .rtemsrwset.bsd.sysinit_set.content
+ 0x000000000030bad4 0x8 libbsd.a(rtems-bsd-thread.o)
+ .rtemsrwset.bsd.sysinit_set.content
+ 0x000000000030badc 0x4 libbsd.a(init_main.o)
+ [...]
+ .rtemsrwset.bsd.sysinit_set.content
+ 0x000000000030bd54 0x4 libbsd.a(frag6.o)
+ .rtemsrwset.bsd.sysinit_set.content
+ 0x000000000030bd58 0x8 libbsd.a(uipc_accf.o)
+ .rtemsrwset.bsd.sysinit_set.end
+ 0x000000000030bd60 0x0 libbsd.a(rtems-bsd-init.o)
+ 0x000000000030bd60 _bsd__stop_set_sysinit_set
+ [...]
+
+Here you can see, that some global data structures are collected into
+continuous memory areas. This memory area can be identified by start and stop
+symbols. This constructs a table of uniform items.
+
+The low level FreeBSD code calls at some time during the initialization the
+mi_startup() function (machine independent startup). This function will sort
+the SYSINIT(9) set and call handler functions which perform further
+initialization. The last step is the scheduler invocation.
+
+The SYSINIT(9) routines are run in ``mi_startup()`` which is called by
+``rtems_bsd_initialize()``. This is also explained in "The Design and
+Implementation of the FreeBSD Operating System" section 14.3 "Kernel
+Initialization".
+
+In RTEMS, we have a library and not a bunch of object files. Thus we need a
+way to pull-in the desired services out of the libbsd. Here the
+``rtems-bsd-sysinit.h`` comes into play. The SYSINIT(9) macros have been
+modified and extended for RTEMS in ``<sys/kernel.h>``:
+
+.. code-block:: none
+
+ #ifndef __rtems__
+ #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
+ static struct sysinit uniquifier ## _sys_init = { \
+ subsystem, \
+ order, \
+ func, \
+ (ident) \
+ }; \
+ DATA_SET(sysinit_set,uniquifier ## _sys_init)
+ #else /* __rtems__ */
+ #define SYSINIT_ENTRY_NAME(uniquifier) \
+ _bsd_ ## uniquifier ## _sys_init
+ #define SYSINIT_REFERENCE_NAME(uniquifier) \
+ _bsd_ ## uniquifier ## _sys_init_ref
+ #define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
+ struct sysinit SYSINIT_ENTRY_NAME(uniquifier) = { \
+ subsystem, \
+ order, \
+ func, \
+ (ident) \
+ }; \
+ RWDATA_SET(sysinit_set,SYSINIT_ENTRY_NAME(uniquifier))
+ #define SYSINIT_REFERENCE(uniquifier) \
+ extern struct sysinit SYSINIT_ENTRY_NAME(uniquifier); \
+ static struct sysinit const * const \
+ SYSINIT_REFERENCE_NAME(uniquifier) __used \
+ = &SYSINIT_ENTRY_NAME(uniquifier)
+ #define SYSINIT_MODULE_REFERENCE(mod) \
+ SYSINIT_REFERENCE(mod ## module)
+ #define SYSINIT_DRIVER_REFERENCE(driver, bus) \
+ SYSINIT_MODULE_REFERENCE(driver ## _ ## bus)
+ #define SYSINIT_DOMAIN_REFERENCE(dom) \
+ SYSINIT_REFERENCE(domain_add_ ## dom)
+ #endif /* __rtems__ */
+
+Here you see that the SYSINIT(9) entries are no longer static. The
+``*_REFERENCE()`` macros will create references to the corresponding modules
+which are later resolved by the linker. The application has to provide an
+object file with references to all required FreeBSD modules.
diff --git a/libbsd.txt b/libbsd.txt
index cd6c8dae..33033c4c 100644
--- a/libbsd.txt
+++ b/libbsd.txt
@@ -104,153 +104,6 @@ be addressed.
- The ISA drivers require more BSD infrastructure to be addressed. This was
outside the scope of the initial porting effort.
-== FreeBSD Source
-
-You should be able to rely on FreebSD manual pages and documentation
-for details on the code itself.
-
-== BSD Library Source
-
-== Initialization of the BSD Library
-
-The initialization of the BSD library is based on the FreeBSD SYSINIT(9)
-infrastructure. The key to initializing a system is to ensure that the desired
-device drivers are explicitly pulled into the linked application. This plus
-linking against the BSD library (`libbsd.a`) will pull in the necessary FreeBSD
-infrastructure.
-
-The FreeBSD kernel is not a library like the RTEMS kernel. It is a bunch of
-object files linked together. If we have a library, then creating the
-executable is simple. We begin with a start symbol and recursively resolve all
-references. With a bunch of object files linked together we need a different
-mechanism. Most object files don't know each other. Lets say we have a driver
-module. The rest of the system has no references to this driver module. The
-driver module needs a way to tell the rest of the system: Hey, kernel I am
-here, please use my services!
-
-This registration of independent components is performed by SYSINIT(9) and
-specializations:
-
-http://www.freebsd.org/cgi/man.cgi?query=SYSINIT
-
-The SYSINIT(9) uses some global data structures that are placed in a certain
-section. In the linker command file we need this:
-
--------------------------------------------------------------------------------
-.rtemsroset : {
- KEEP (*(SORT(.rtemsroset.*)))
-}
-
-.rtemsrwset : {
- KEEP (*(SORT(.rtemsrwset.*)))
-}
--------------------------------------------------------------------------------
-
-This results for example in this executable layout:
-
--------------------------------------------------------------------------------
-[...]
- *(SORT(.rtemsroset.*))
- .rtemsroset.bsd.modmetadata_set.begin
- 0x000000000025fe00 0x0 libbsd.a(rtems-bsd-init.o)
- 0x000000000025fe00 _bsd__start_set_modmetadata_set
- .rtemsroset.bsd.modmetadata_set.content
- 0x000000000025fe00 0x8 libbsd.a(rtems-bsd-nexus.o)
- .rtemsroset.bsd.modmetadata_set.content
- 0x000000000025fe08 0x4 libbsd.a(kern_module.o)
-[...]
- .rtemsroset.bsd.modmetadata_set.content
- 0x000000000025fe68 0x4 libbsd.a(mii.o)
- .rtemsroset.bsd.modmetadata_set.content
- 0x000000000025fe6c 0x4 libbsd.a(mii_bitbang.o)
- .rtemsroset.bsd.modmetadata_set.end
- 0x000000000025fe70 0x0 libbsd.a(rtems-bsd-init.o)
- 0x000000000025fe70 _bsd__stop_set_modmetadata_set
-[...]
-.rtemsrwset 0x000000000030bad0 0x290
- *(SORT(.rtemsrwset.*))
- .rtemsrwset.bsd.sysinit_set.begin
- 0x000000000030bad0 0x0 libbsd.a(rtems-bsd-init.o)
- 0x000000000030bad0 _bsd__start_set_sysinit_set
- .rtemsrwset.bsd.sysinit_set.content
- 0x000000000030bad0 0x4 libbsd.a(rtems-bsd-nexus.o)
- .rtemsrwset.bsd.sysinit_set.content
- 0x000000000030bad4 0x8 libbsd.a(rtems-bsd-thread.o)
- .rtemsrwset.bsd.sysinit_set.content
- 0x000000000030badc 0x4 libbsd.a(init_main.o)
-[...]
- .rtemsrwset.bsd.sysinit_set.content
- 0x000000000030bd54 0x4 libbsd.a(frag6.o)
- .rtemsrwset.bsd.sysinit_set.content
- 0x000000000030bd58 0x8 libbsd.a(uipc_accf.o)
- .rtemsrwset.bsd.sysinit_set.end
- 0x000000000030bd60 0x0 libbsd.a(rtems-bsd-init.o)
- 0x000000000030bd60 _bsd__stop_set_sysinit_set
-[...]
--------------------------------------------------------------------------------
-
-Here you can see, that some global data structures are collected into
-continuous memory areas. This memory area can be identified by start and stop
-symbols. This constructs a table of uniform items.
-
-The low level FreeBSD code calls at some time during the initialization the
-mi_startup() function (machine independent startup). This function will sort
-the SYSINIT(9) set and call handler functions which perform further
-initialization. The last step is the scheduler invocation.
-
-The SYSINIT(9) routines are run in mi_startup() which is called by
-rtems_bsd_initialize().
-
-This is also explained in "The Design and Implementation of the FreeBSD
-Operating System" section 14.3 "Kernel Initialization".
-
-In RTEMS we have a library and not a bunch of object files. Thus we need a way
-to pull-in the desired services out of the libbsd. Here the
-`rtems-bsd-sysinit.h` comes into play. The SYSINIT(9) macros have been
-modified and extended for RTEMS in `<sys/kernel.h>`:
-
--------------------------------------------------------------------------------
-#ifndef __rtems__
-#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
- static struct sysinit uniquifier ## _sys_init = { \
- subsystem, \
- order, \
- func, \
- (ident) \
- }; \
- DATA_SET(sysinit_set,uniquifier ## _sys_init)
-#else /* __rtems__ */
-#define SYSINIT_ENTRY_NAME(uniquifier) \
- _bsd_ ## uniquifier ## _sys_init
-#define SYSINIT_REFERENCE_NAME(uniquifier) \
- _bsd_ ## uniquifier ## _sys_init_ref
-#define C_SYSINIT(uniquifier, subsystem, order, func, ident) \
- struct sysinit SYSINIT_ENTRY_NAME(uniquifier) = { \
- subsystem, \
- order, \
- func, \
- (ident) \
- }; \
- RWDATA_SET(sysinit_set,SYSINIT_ENTRY_NAME(uniquifier))
-#define SYSINIT_REFERENCE(uniquifier) \
- extern struct sysinit SYSINIT_ENTRY_NAME(uniquifier); \
- static struct sysinit const * const \
- SYSINIT_REFERENCE_NAME(uniquifier) __used \
- = &SYSINIT_ENTRY_NAME(uniquifier)
-#define SYSINIT_MODULE_REFERENCE(mod) \
- SYSINIT_REFERENCE(mod ## module)
-#define SYSINIT_DRIVER_REFERENCE(driver, bus) \
- SYSINIT_MODULE_REFERENCE(driver ## _ ## bus)
-#define SYSINIT_DOMAIN_REFERENCE(dom) \
- SYSINIT_REFERENCE(domain_add_ ## dom)
-#endif /* __rtems__ */
--------------------------------------------------------------------------------
-
-Here you see that the SYSINIT(9) entries are no longer static. The
-\*_REFERENCE() macros will create references to the corresponding modules which
-are later resolved by the linker. The application has to provide an object
-file with references to all required FreeBSD modules.
-
The FreeBSD device model is quite elaborated (with follow-ups):
http://www.freebsd.org/cgi/man.cgi?query=driver
--
2.35.3
More information about the devel
mailing list