mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-07-24 01:19:44 +08:00
Elaborate RTEMS libbsd initialization
This commit is contained in:
parent
a3d2498e49
commit
8a4f070701
137
libbsd.txt
137
libbsd.txt
@ -261,20 +261,135 @@ Generating into /home/joel/newbsd/git/libbsd-8.2
|
|||||||
The script may also be used to generate a diff in either forward or reverse
|
The script may also be used to generate a diff in either forward or reverse
|
||||||
direction.
|
direction.
|
||||||
|
|
||||||
== Initialization of RTEMS Libbsd
|
== Initialization of RTEMS libbsd
|
||||||
|
|
||||||
The initialization of the RTEMS Libbsd is based on the FreeBSD SYSINIT
|
The initialization of the RTEMS libbsd is based on the FreeBSD SYSINIT(9)
|
||||||
infrastructure. This is simply because we are initializing a subset of
|
infrastructure. The key to initializing a system is to ensure that the desired
|
||||||
FreeBSD. For details refer to http://www.freebsd.org/cgi/man.cgi?query=SYSINIT&sektion=9&apropos=0&manpath=FreeBSD+9-current
|
device drivers are explicitly pulled into the linked application. This plus
|
||||||
|
linking against the libbsd library will pull in the necessary FreeBSD
|
||||||
|
infrastructure.
|
||||||
|
|
||||||
The key to initializing a system is to ensure that the desired device
|
The FreeBSD kernel is not a library like the RTEMS kernel. It is a bunch of
|
||||||
drivers are explicitly pulled into the linked application. This plus
|
object files linked together. If we have a library, then creating the
|
||||||
linking against the Libsd library will pull in the necessary FreeBSD
|
executable is simple. We begin with a start symbol and recursively resolve all
|
||||||
infrastructure. The SYSINIT structures are automatically built at link
|
references. With a bunch of object files linked together we need a different
|
||||||
time and the various initialization routines will thus be executed in'
|
mechanism. Most object files don't know each other. Lets say we have a driver
|
||||||
the correct order.
|
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!
|
||||||
|
|
||||||
XXX This needs more details.
|
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:
|
||||||
|
|
||||||
|
[listing]
|
||||||
|
----
|
||||||
|
.robsdsets : {
|
||||||
|
_bsd__start_set_modmetadata_set = .;
|
||||||
|
*(_bsd_set_modmetadata_set);
|
||||||
|
_bsd__stop_set_modmetadata_set = .;
|
||||||
|
_bsd__start_set_sysctl_set = .;
|
||||||
|
*(_bsd_set_sysctl_set);
|
||||||
|
_bsd__stop_set_sysctl_set = .;
|
||||||
|
} > REGION_RODATA AT > REGION_RODATA_LOAD
|
||||||
|
|
||||||
|
.rwbsdsets : {
|
||||||
|
_bsd__start_set_sysinit_set = .;
|
||||||
|
*(_bsd_set_sysinit_set);
|
||||||
|
_bsd__stop_set_sysinit_set = .;
|
||||||
|
} > REGION_DATA AT > REGION_DATA_LOAD
|
||||||
|
----
|
||||||
|
|
||||||
|
Here you can see, that these 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":
|
||||||
|
|
||||||
|
[listing]
|
||||||
|
----
|
||||||
|
#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) \
|
||||||
|
}; \
|
||||||
|
DATA_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)
|
||||||
|
#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
|
||||||
|
|
||||||
|
The devices form a tree with the Nexus device at a high-level. This Nexus
|
||||||
|
device is architecture specific in FreeBSD. In RTEMS we have our own Nexus
|
||||||
|
device, see "rtems-bsd-nexus.c". It uses a table to add child devices:
|
||||||
|
|
||||||
|
[listing]
|
||||||
|
----
|
||||||
|
const char *const _bsd_nexus_devices [] = {
|
||||||
|
#ifdef NEED_USB_OHCI
|
||||||
|
"ohci",
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_USB_EHCI
|
||||||
|
"ehci",
|
||||||
|
#endif
|
||||||
|
#ifdef NEED_SDHC
|
||||||
|
"sdhci",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
----
|
||||||
|
|
||||||
|
This table must be provided by the application.
|
||||||
|
|
||||||
=== SYSCTL_NODE Example
|
=== SYSCTL_NODE Example
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user