After porting FreeBSD’s PRU driver to rtems-libbsd, I encountered a problem concerning the init process. The PRU driver needs TI’s prcm module to be loaded when initialising itself. However the current rtems-libbsd init process doesn’t allow me to sort that dependency. So I had to investigate the whole process, since I don’t have JTAG . );
Linking the drivers.
In FreeBSD Modules are registered using the DRIVER_MODUL macro. This macro hands down all its information via a macro chain and some structs containing additional information. The DRIVER_MODULE is defined in bus.h and is actually a call of EARLY_DRIVER_MODULE_ORDERED with static order (SI_ORDER_MIDDLE) and pass level (BUS_PASS_DEFAULT). All data concerning the driver is stored in two structs and the module is forwarded to DECLARE_MODULE in module.h. The last macro of this chain is SYSINIT.
The init process
When using rtems with rtems-libbsd the whole libBSD init process get triggered by rtems_bsd_initialize() in rtems-kernel-init.c. This functions sets parameters for the BSD library and calls mi_startup() from init_main.c. This function iterates over the objects, linked by SYSINIT, and executes a bubble sort on them. After this the modules are ordered by subsystem and in their subsystem they are ordered by si-order. All objects are called in order with their defined function and data here. Focusing on driver modules this function is module_register_init() in kern_module.c. This function retrieves the data stored in additional structs during linking and uses the MOD_EVENT macro. This macro calls the modules event handler and hands threw the mod itself and its arguments. For bus related modules as our drivers are the handler refers to driver_module_handler in subr_bush.c. Here all bus devices are registered for activation.
I am currently investigating this topic. My guess is that the loop attaching devices to the bus does not run over the fdt multiple times as stated int he FreeBSD manual. UPDATE: LibBSD does indeed run over fdt only once. But after trying to add another run over fdt I discovered that all drivers are registered with the same pass level, which definitely shouldn’t be the case. The method calling a fdt pass for a pass level is called here.