I have a kernel module modA.ko that depends upon exported symbols.
exported_func1(void)
exported_func2(void)
And I have two other modules modB.ko and modC.ko that has the definitions for exported functions separately. Function signature is the same but functionality is different. Only one of the modB.ko or modC.ko is supposed to be loaded at the same time. Every time the kbuild determines that modA.ko is dependent on modB.ko. I don't want that. I want to dynamically load the appropriate modules before using modA.ko according to the need.
Is there a way to force the kernel build system to not add dependencies just for this particular module.
I am using Buildroot to build the Linux image but no dependencies are defined in buildroot-config for these modules. In the Buildroot output/, both modB.ko and modC.ko have exported functions listed in the .symvers files.
Related
I have two plugins pluginA.plugin and pluginB.plugin which are both depend on same library libC.dylib. When plugins are built, I recursively go over dynamic dependencies (use otool -L), copy all dependencies inside each plugin's libs folder and adjust dependencies paths using install_name_tool, i.e. "carrying all all my stuff with me" approach.
I'm trying to understand what is happening when those two plugins will be loaded by some program? Will libC.dylib be loaded twice and this will cause runtime crash? Or will runtime realize that there are two copies of the same dylib (based on versions?) and use just one?
The order of dynamic library search and load is described in Apple's Dynamic Library Usage Guidelines
In short, if paths to depended library in your plugins matches than this library will be loaded only once. On every next load only internal counter will be increased:
The dlopen function returns the same library handle it returned in the
first call, but it also increments the reference count associated with
the handle
If paths to library is different than different copies of library will be loaded.
Note: While checking whether the library is already loaded, the absolute path to it is used. It may be directly set in dependency, discovered during search in global directories or resolved from #rpath.
And about potential confilcts during symbol resolving:
Name conflicts between dynamic shared libraries are not discovered at
compile time, link time, or runtime. The dlsym function uses string
matching to find symbols. If two libraries use the same name for a
function, the dynamic loader returns the first one that matches the
symbol name given to dlsym.
So several copies will not crash program if both plugins uses the same library. If they expect different libraries under the same name than it's a big problem and you should use version compatibility mechanism - see Dynamic Library Design Guidelines
In order to achieve better encapsulation and modularity I've decided to split my kernel driver into 2 (can be more) modules where each is responsible for different functionality.
However, there are still some data+logic which I'd like to share between those modules (i.e. one module can manage the communication with user-space, while the other uses it as mediator) and I wonder if there's any easy way to do so.
For example, I'd like to publish some API from one module to another, which is absolutely doable since both modules are running under kernel process and are mapped in separated ranges in the same address space.
The catch is that each kernel module has symbol table of its own, and in order to publish the API, some sort of loader is needed to fix the addressing/pointers/etc.. It's like calling dlopen and dlsym from user-space when dynamically linking with library, but in kernel space and where each library also possess state (the state defined by the current snapshot of all its inner heap/global parameters).
My question is whether this approach is valid and accpeted in the realms of macOS?
EDIT, in the following question, it's explained the linux way of achieving my goal, Perhaps do you know what's the equivalent in macOS/XNU to symbol_get and symbol_put ?
It looks like the Linux side has already been answered in comments.
For macOS kexts, the mechanism to use are the OSBundleLibraries and OSBundleCompatibleVersion Info.plist properties. The kext exporting symbols must have the OSBundleCompatibleVersion property set. This must be less than or equal to its CFBundleVersion and allows you to version your API.
The kext which wishes to import the other kext's symbols must list the exporting kext's bundle identifier in the OSBundleLibraries dictionary, with the appropriate version number.
Note that linking against another kext will import all of its public symbols, so I strongly recommend making all symbols default-hidden and providing an explicit exports file. To do this, enable "Symbols hidden by default" in the Xcode target settings, create a new .exp (or .exports) file, and declare it in the "Exported Symbols File" setting. At a minimum, you will need to add _kmod_info to this file. Then add all the symbols you wish to export, one on each line.
C functions and global variables will need to be prefixed with an underscore, C++ functions and static class member variables will need to be mangled in the usual way. You can use * as a (partial) wildcard, which is sometimes handy for C++ classes with a lot of member functions, for example. The xnu source distribution contains plenty of examples of exports files if you need a reference. You can use the nm tool to generate a list of all the symbols in your kext, from which you can then pick & choose; this saves you from manually mangling names.
Kexts can't circularly depend on one another. One will need to be the "library," the other the "user" of that library. If they need to interact, you will need to use callbacks, virtual functions, etc.
The "library" kext must be installed in /Library/Extensions (/System/Library/Extensions on OS X 10.8 or earlier) or the user of the library will not find it, potentially even if the library kext is already loaded. If your "user" kext specifies in its OSBundleRequired property that it may be needed for local or network booting, the libraries it depends on should declare the same or a superset of those conditions, or they may not be appropriately prelinked/kextcached.
Apple does have a small amount of documentation on designing kext libraries too.
I need to build mmc_block.ko but with MMC_BLOCK_MINORS=16. I do not wish to build the entire kernel. I am using Ubuntu 15.10. How do I do this?
Dpending on how the Makefile has been written, a module can be compiled out of the kernel tree or in the kernel tree.
Concerning your specific example, I assume the module is the one shipped with the kernel and therefore the Makefile has been written for in-tree compilation. In this case, you can just type make modules to rebuild the module, provided that the kernel has been already compiled (which is a mandatory condition also for out-of-the-tree compilation).
I have create a new Kernel Module following The Linux Kernel Module Programming Guide.I want to add my module to the [config -> Package selection -> package List]
and distribute my module with target image
â–ºDevelopment Environment
boundary device sabrelite board
LTIB (i.MX6 kernel 4.1.0)
I put my kernel module's source on [/home/USER/ltib/rpm/BUILD/myModule] path. (just like hello_mod example module which explained in "The Linux Kernel Module Programming Guide")
but when i build target image it does not compile.
hello_mod example module can be selected in configuration mode(./ltib -m config).
How can I add my module to this config -> Package selection -> package List
If you want to build from make menuconfig, that you probably should change the makefiles.
Check this documentation from the linux kernel. Taken from it:
Normal developers are people who work on features such as device drivers, file systems, and network protocols. These people need to
maintain the kbuild Makefiles for the subsystem they are working on.
In order to do this effectively, they need some overall knowledge
about the kernel Makefiles, plus detailed knowledge about the public
interface for kbuild.
I am working on a project which consists of multiple kernel modules. There is some shared functionality between the different modules, but I don't want to include the same code in each module. Does the Linux kernel have a "shared object library" or does the common code go into a separate module?
Typically, you would put the functionality common to the modules in a separate module itself. A good example of this is the drivers/scsi/libsas module used by other SAS (Serial Attached SCSI) device drivers. If you go this route, see the kernel documentation in section 6.3 of Documentation/kbuild/modules.txt for suggestions on referencing symbols from other external modules.
If you're looking for a way to share functions between modules you should take a look at EXPORT_SYMBOL macro. A simple example:
file super.c
void call_me(){
printk("Hello from super.\n");
}
EXPORT_SYMBOL(call_me);
file super.h
extern void call_me();
file base.c
#include "super.h"
void call_super(){
call_me();
}
Here super.c and base.c are different modules.
If this is what you're looking for let me know. I can send you a more complex example with makefiles and stuff. Hope it helps.
Note: I've used this in many distros... however each time I did it I needed to copy the file Modules.symvers to each other module directory.
Supose you have a module A and a module B, which uses functions from A. Upon compiling A, a file named Modules.symvers is created. I've needed to copy that file to B's folder before compiling it. Just don't issue make clean in B's folder after copying Modules.symvers, or it will get deleted.