'module'에 해당되는 글 3건

  1. 2012.01.09 [Kernel] How to know KBUILD_MODNAME of each files.
  2. 2011.06.08 [Kernel] module & parameter initialization.
  3. 2011.05.17 [C/C++] Tips for OOP - module initialization.

[Kernel] How to know KBUILD_MODNAME of each files.

Domain/Kernel 2012.01.09 11:42

Kernel build system defines KBUILD_MODNAME automatically from each Makefile.
You can easily find below string from build command of each files of modules.

-D"KBUILD_MODNAME=KBUILD_STR(xxxxx)"
('xxxxx' is given module name)

This name xxxxx comes from Makefile.
Below is simple example.

[ in Makefile ]
xxxxx-y := a.o b.o c.o d.o

In above case, KBUILD_MODNAME of a.cb.cc.c and d.c becomes xxxxx.
This can be easily confirmed by checking command line of each objects - a.ob.oc.o and d.o.

신고
tags : module
Trackback 0 : Comment 0

[Kernel] module & parameter initialization.

Domain/Kernel 2011.06.08 11:20

Linux kernel uses lot's of sections to modularize it's code structure easily.
In case of kernel module and parameter, following section is used.

[ Module ]
macro   : module_init()
section : device_initcall (section name : .initcall6.init) <see init.h>
[ Parameter ]
macro   : module_param_named(), module_param(), core_param() etc.
section : __param <see moduleparam.h>

core_param() macro works like other module parameter. But this is NOT for module BUT for kernel booting parameter.
Kernel parameter doesn't have any prefix unlike other modules.
Module parameter's name has <module name> as it's prefix.
For example, parameter <param> of module <module> has name <module>.<param>
See source code for details.

KBUILD_MODNAME is preprocessor value for module name.
This is defined through complex script processing. See Makefile.libMakefile.mod* in scripts/.
But in most case, you can know it by intuition. That is,  name that seems like module name, is set as KBUILD_MODNAME.
(ex. <mod name>-y<mod-name>-m in Makefile)
So, usually, deep analysis about above scripts are not required.

Note:
It's possible that one object gets potentially linked into more than one module.
In that case KBUILD_MODNAME will be set to  foo_bar, where foo and bar are the name of the modules.

Module and parameter initialization.

[ Built-in module ]
module initialization : do_initcalls() <see 'main.c'> => initcall section is used
parameter sysfs node  : param_sysfs_init() -> param_sysfs_builtin() => __param section is used
[ Dynamic module ]
module & parameter initialization is done at system call
SYSCALL_DEFINE3(init_module, ...) => load_module()

Each parameter has permission mask. So, parameter value can be read or written at runtime through sysfs node.

/sys/module/<module name>/parameter/<parameter name>

But module parameter whose  permission is 0, is ignored at sysfs (Not shown at sysfs).
( See module_param_sysfs_setup(...) function. )

신고
tags : module, parameter
Trackback 0 : Comment 0

[C/C++] Tips for OOP - module initialization.

Language/C&C++ 2011.05.17 17:00

OOP SW design is usually compose of one main control routine (henceforth MCR) and lots of sub modules.
But, MCR don't need to (must not need to) know inside implementation of every sub modules.
Sometimes, MCR don't need to know even existence of some sub modules.
The problem is, most sub modules require initialization.
How can sub modules whose existence is now known, be initialized.
Due to this issue, principle of information hiding is sometimes broken.
Let's see below example.

FILE : main.c
-------------
int main(int argc, char* argv[]) {
        ...

}

FILE : moduleA.c
----------------
...

FILE : moduleB.c
----------------
...

Assume that, each module requires initialization and main.c don't need to know existence of each module.
How can we resolve this issue?
Easiest way is calling initialization function of each module with damaging principle of information hiding little bit, like mentioned above.

FILE : main.c
-------------
extern void moduleA_init();
extern void moduleB_init();

int main(int argc, char* argv[]) {
        ...
        moduleA_init();
        moduleB_init();
        ...
}

FILE : moduleA.c
----------------
...
void moduleA_init() { ... }

FILE : moduleB.c
----------------
...
void moduleB_init() { ... }

At above code, main.c becomes to know existence of moduleA and moduleB.
That is, in terms of modules, principle of information hiding is damaged although it's very little.
Additionally, global symbol space is dirtier.
Regarding maintenance, whenever new module is added, modifying main.c is unavoidable.
But, main.c doesn't have any dependency on newly added module.
With this and that, this way is uncomfortable.
How can we clean up these?
Using constructor leads us to better way.

Functions in constructor are executed before main function.
So, it is very useful for this case.
Easiest way is setting every initialization function as constructor.
But, in this case, we cannot control the moment when module is initialized at.
Therefore, it is better that each module's initialization function is registered to MCR, and MCR calls these registered function at right moment.
Following pseudo code is simple implementation of this concept.

FILE : main.c
-------------
void register_initfn(void (*fn)()) {
        list_add(initfn_list, fn);
}

int main(int argc, char* argv[]) {
        ...
        /* initialize modules */
        foreach(initfn_list, fn)
                (*fn)();
        ...
}

FILE : module.h
---------------
extern void register_initfn(void (*fn)());
#define MODULE_INITFN(fn)                               \
        static void __##fn##__() __attribute__ ((constructor)); \
        static void __##fn##__() { register_initfn(&fn); }

FILE : moduleA.c
----------------
...
#include "module.h"
...
static void _myinit() { ... }
MODULE_INITFN(_myinit)

FILE : moduleB.c
----------------
...
#include "module.h"
...
static void _myinit() { ... }
MODULE_INITFN(_myinit)

Now, MCR don't need to know existence of each modules.
And, MCR can also control the moment of each module's initialization.
In addition, adding new module doesn't require any modification of MCR side.
It is closer to OOP's concept, isn't it?

We can improve this concept by customizing memory section.
Here is rough description of this.

* Declare special memory section for initializer function.
    - In gcc, ld script should be modified.

* Put initializer function into this section.
    - __attribute__ ((__section__("xxxx"))) can be used.

* MCR can read this section and call these functions at appropriate moment.

Actually, this way is better than using constructor in terms of SW design.
Linux kernel uses this concept in it's driver model.
(For deeper analysis, kernel source code can be good reference.)
But, in many cases, using this concept may lead to over-engineering.
So, if there isn't any other concern, using constructor is enough.

신고
Trackback 0 : Comment 0

티스토리 툴바