for (sipp = sysinit; *sipp; sipp++) {
尽管sysinit框架已经在《FreeBSD开发者手册》中有所描述,我还是在这里讨论一下其内部原理。每个系统初始化对象(sysinit对象)通过调用宏建立。让我们以announce sysinit对象为例。这个对象打印版权信息:sys/kern/init_main.c:
/* ... 省略 ... */
/* 调用函数 */
(*((*sipp)->func))((*sipp)->udata);
/* ... 省略 ... */
}
static void
print_CADdr_t(void *data __unused)
{
printf("%s", (char *)data);
}
SYSINIT(announce, SI_SUB_COPYRIGHT, SI_ORDER_FIRST, print_caddr_t, copyright)
这个对象的子系统标识是SI_SUB_COPYRIGHT(0x0800001),数值刚好排在SI_SUB_CONSOLE(0x0800000)后面。所以,版权信息将在控制台初始化之后就被很早的打印出来。
让我们看一看宏SYSINIT()到底做了些什么。它展开成宏C_SYSINIT()。宏C_SYSINIT()然后展开成一个静态结构struct sysinit。结构里申明里调用了另一个宏DATA_SET:/usr/include/sys/kernel.h:
#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);
#define SYSINIT(uniquifier, subsystem, order, func, ident)
C_SYSINIT(uniquifier, subsystem, order,
(sysinit_cfunc_t)(sysinit_nfunc_t)func, (void *)ident)
标签: