[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