Date: Mon, 31 Mar 1997 10:32:21 -0700 (MST) From: Terry Lambert <terry@lambert.org> To: dfr@nlsystems.com (Doug Rabson) Cc: terry@lambert.org, current@freebsd.org Subject: Re: A new Kernel Module System Message-ID: <199703311732.KAA09669@phaeton.artisoft.com> In-Reply-To: <Pine.BSF.3.95q.970331102908.534G-100000@kipper.nlsystems.com> from "Doug Rabson" at Mar 31, 97 11:10:35 am
next in thread | previous in thread | raw e-mail | index | archive | help
> > SYSINIT() is an image-global link-time configuration mechanism. It > > must be implemented on top of something other than linker sets for > > this to be an achievable goal. Since this was one of the design > > considerations for SYSINIT(), this should be relatively trivial to > > do. Once this is one, the SYSINIT() becomes an actual function > > call reference, not a linker set reference, and the conditional > > compilation issues for static vs. dynamic modules simply go away. > > The linker set for a dynamically loaded module would be local to the > object file containing the module. Look at the implementation of C++ > constructors in userland shared libraries. When the shlib is linked, the > linker sets are aggregated. When it is loaded, the linker calls init code > in the lib which uses the set. SYSINIT() from a loadable module would be > similar. I don't think this is the same thing, really. Consider that in order to use a dynamically linked shared library, the symbol list must be imported into the executable that is bound to the binary. You can't do this for a module which is dynamically loaded; there is no symbol set within the kernel with knowledge of the modules constructor symbol names, as there is when the symbols are linked into the CTOR/DTOR list with a C++ shared library. Shared libs LKM's has knowledge of symbols has knowledge of one offset has static data loads static data, which must be relocated has multiple entry points has one entry point because of vtable ld.so mapped into process paging (and therefore mapping) not supported > > > Device instances (struct isa_device) will refer to their driver by > > > name rather than by pointer. The name to driver mapping is > > > performed and the device is probed and attached as normal. > > > > I'm not clear on why this abstraction is necessary or useful??? > > By keeping a separation between device instances (probed or otherwise) and > device drivers, the driver does not need to be recompiled when the device > configuration (irq or whatever) is changed. The driver should not depend > on the individual resource requirements of a particular machine. Ah, I understand. It's to allow external manipulation of device data. Say I have an interface named "ed0" and I need variable numbers of parameters to make it work? For instance PCMCIA vs. non-PCMCIA vs. PnP ISA vs. real PnP PCI. The idea is sound, but perhaps it needs to be nearly as parametric as PnP itself? > > > Statically configured devices are placed in a table by config(8) > > > and modules containing their drivers are added to the kernel > > > Makefile. > > > > I would prefer that modules be build as seperate single object > > files (potentially agregating multiple object files into one using > > "ld -r"). > > > > A configuration is then simply a list of modules. > > > > I'm not sure if I like the idea of keeping a "config" around as > > anything other than a set of linker directives (in the a,out case), > > or as a vastly preferrable alternative, as input to an ELF section > > librarian for an agregate kernel image. > > There has to be a clear distinction between device instances (isa_device > in the current code) and device drivers (isa_driver). There can be many > device instances using the same driver, each with its own private > configuration data. The driver module itself must not embed any > specific device configuration. This should be supplied to it, either by a > user supplied configuration for legacy ISA devices or by a list generated > at boot time by PnP, PCI, EISA etc. But shouldn't device instantiation within a driver be handled by the probe code coming true? Is this just for static configuration of devices without invoking a probe? > The configuration of a kernel is a list of modules plus a list of ISA > device instances (assuming that ISA is the only bus which does not provide > a complete list of attached devices). This list of device instances would > be carefully ordered (exactly as it is today) to resulve probe > difficulties. OK. But I think we can do this anyway. For instance, a LANCE-based ethernet is probed by kicking it and seeing if it yells (INTs). But you *can* also detect the thing by its ROM. > > The object module per LKM is still a valid approach (ld -r). Perhaps > > you are considering a module that is set up as two distinct (and > > reusable) components? If so, I would argue that allowing dependencies > > and breaking it into two modules accomplishes much the same thing. > > The boot kernel is an example of a single kernel object which contains > many modules. The act of aggregating (with ld -r) several objects into > one also generates a single object containing many modules. OK, then I remove my question... it's a semantic issue, not a technical one. > My problem is that I want to be able to either load the modules > individually or aggregate them into larger sets (or statically in the boot > kernel). A single object file can only have a single entry point but can > contain many SYSINITs. It seems that a linker set of SYSINIT()'s would meet this need, as long as you had a "generic" _entry mechanism capable of multiplexing not only load/unload/stat but also which of the elements you are applying the operation to. This is reasonable if you are willing to continue linking a seperate entry stub for each "module group", OR if you are willing to double the interior symbol space (to distinguish between internal entry points used by the driver and those exported by the driver for use by other modules). I think something like this is necessary to reduce the amount of kernel symbol namespace pollution that results from loading a bazillion modules, anyway... in other words, it has benefit above and beyond that of formallizing the module interfaces. > I want a function call based mechanism for initialisation to avoid > embedding knowledge in the kernel linker of the many different linker sets > in current use in the kernel. Yes, this is an obvious requirement which I totally agree with. I'm just not sure you can cleanly implement a CTOR/DTOR calling method to be able to support it... at least not without going away from a.out, perhaps sooner than you want to (bigger delta's == bigger risks). Regards, Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703311732.KAA09669>