tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Modularizing net80211 (was: link_set info needed)

On Sat, 28 Apr 2012, Paul Goyette wrote:

How about another alternative?

Rather than using .ctor/dtor for _MODULE mode, and a link-set for the built-in mode, we could extend the modinfo_t structure to include two new members:

        char *mi_ctor_section, *mi_dtor_section

Then the module's code can continue to use the link_set paradigm, and the module loader can use the names provided rather than hard-coding ".ctor" and ".dtor". And that means that (this part of) the module doesn't need to be aware of whether it is built-in or not.

This would also mean that net80211 module no longer needs its own code to process the __link_set_foreach(), since the module loader would take care of this automatically?

Of course, this would definitely require a kernel version bump, since module_t would be changing. And I would propose we use a MODULE_NEW declaration, and redefine MODULE to specify NULL values for the two new members.

/* Module header structure. */
typedef struct modinfo {
       u_int           mi_version;
       modclass_t      mi_class;
       int             (*mi_modcmd)(modcmd_t, void *);
       const char      *mi_name;
       const char      *mi_required;
       const char      *mi_ctor_section;
       const char      *mi_dtor_section;
} const modinfo_t;


* Per-module linkage.  Loadable modules have a `link_set_modules' section
* containing only one entry, pointing to the module's modinfo_t record.
* For the kernel, `link_set_modules' can contain multiple entries and
* records all modules built into the kernel at link time.
#define MODULE(class, name, required)                           \
        MODULE_NEW(class, name, required, NULL, NULL)

#define MODULE_NEW(class, name, required, ctor, dtor)           \
static int name##_modcmd(modcmd_t, void *);                     \
static const modinfo_t name##_modinfo = {                       \
       .mi_version = __NetBSD_Version__,                       \
       .mi_class = (class),                                    \
       .mi_modcmd = name##_modcmd,                             \
       .mi_name = #name,                                       \
       .mi_required = (required),                              \
       .mi_ctor_section = ctor,                                \
       .mi_dtor_section = dtor                                 \
};                                                              \

Unfortunately, this approach doesn't work for built-in modules.

For built-in modules, we don't (seem to) have a list of the kernel's program sections, and the module's mod->mod_kobj is NULL. So we can't use the section table to get the start address or size of the section. We do have the start/end symbols that __link_set_foreach() uses to enumerate the members.

For non-built-in modules (whether loaded by boot loader, or later from the file system), we have the section info (it's in the kobj->ko_progtab member), but we don't seem to get the start/end symbols. (Perhaps this could be resolved with some crt*.o type magic, but it appears that the user-land crt stuff is GPL'd so not suitable for kernel use?)

So it seems that we just can't get a single mechanism to work for all modules regardless of source (built-in, boot, or filesys).

| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| Customer Service | FA29 0E3B 35AF E8AE 6651 | paul at    |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at |
| Kernel Developer |                          | pgoyette at  |

Home | Main Index | Thread Index | Old Index