/*NOTE: * Earlier I planned to do the inter-module stuff first ... but rth's comments are * a little discouraging. So I think I'll leave that stuff for later. * * And consider this as just the DRAFT ... tell me what changes are necessary :-) */ #define MOD_CAN_QUERY(mod) \ (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED)) /* * A module can be queried iff it has been entered in the 'module_list'. After entering * the module_list a module is in the state 'MOD_INITIALIZING' as 'sys_init_module()' is * called after 'sys_create_module()'. A module is inserted into the 'module_list' after * the successful execution of 'sys_create_module()'. * * Thus a module can be queried if either it is MOD_INITIALIZING or MOD_RUNNING, but not * MOD_DELETED. * */ #define mod_member_present(mod,member) \ ((unsigned long)(&((struct module *)0L)->member + 1) <= (mod)->size_of_struct) /* * This macro is used to find out wether member is included in the module or not. * * (struct module *)0L : cast 0L to struct module pointer i.e. _assume_ the virtual * address 0L to point to a module. * * ((struct module *)0L)->member + 1 : Dereference member from structure pointer at 0L * * &((struct module *)0L)->member + 1 : Get the address of member i.e. simply compute * the offset of member within the structure. This _compute_ gives the offset of the * member because the structure is at 0L. The other possible way could have been ... * (unsigned long)(&(mod->member)+1)-(unsigned long)(&mod) * * The remaining steps simply find out wether the offset of member is <= the size_of_struct. * If so then member is included in the structure, else there is _something_ wrong going on. * */ #define mod_bound(p,n,m) \ ((unsigned long)(p) >= ((unsigned long)(m) + (m)->size_of_struct)) && \ (unsigned long)((p) + (n)) <= (unsigned long)(m) + (m)->size /* * Check if an address p contains n entries within the body of module m. * * +----------------------+ * | struct module | * +----------------------+ * | some pointer P | * + + * | | * + + * | | * +----------------------+ size_of_struct == sizeof(struct module) * +----------------------+ * | module body | * + + * | | * + + * | | * +----------------------+ * | P points here | * +----------------------+ * | | * + + * | | * +----------------------+ size == sizeof(this module) * * The statement before && checks wether an address p is within the module body or not, * also, it should not be a part of the module structure itself. * The statement after && checks wether the n entries after address p are bounded by the * module body or not. * */ #define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount)) /* --*-- */ #define __MOD_IN_USE(mod) \ (mod_member_present((mod),can_unload) && \ (mod)->can_unload ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount)) /* * This macro is used to determine wether a module 'mod' is in use or not. * This macro will _always_ evaluate to false if the member 'can_unload' is not present. * * If 'can_unload' is present, then if 'can_unload' is a non-NULL pointer i.e. can_unload * function has been 'defined' by the programmer then, it _must_ return a positive value. * * And if 'can_unload' is a NULL pointer then, 'uc.usecount' should be greater than 0. * (Obviously a module cannot/should not be unloaded if 'uc.usecount' > 0) * * As an aside, this function has been used in the entire sources only in the * 'zftape-compress.c','zftape-init.c' and 'af_inet6.c' files. */ /* ---- HAVE SKIPPED MODULE DOCUMENTATION MACROS ---- */ #define MODULE_PARM(var,type) \ const char __module_parm_##var[] \ __attribute__((section(".modinfo"))) = \ "parm_" __MODULE_STRING(var) "=" type /* * This macro defines the load-time module parameters. * * To understand this, one has to be familiar with assembly language programming. * And in our case, also the features native to the GNU "as" assembler. Just read on * if you don't know AT&T syntax and GNU "as", I'll try to get the idea across. * * Suppose we have the following listing ... * * +-----------------------------------------------------------------------------+ * const char FOO[] __attribute__((section(".MY_OWN_SECTION"))) = "VALUE OF FOO"; * * main(){} * * +-----------------------------------------------------------------------------+ * * For the above listing, we run ... * $gcc -S my_listing.c * * We get my_listing.s, which looks like ... * +-----------------------------------------------------------------------------+ * * .file "test.c" * .version "01.01" * gcc2_compiled.: * .globl FOO * .section .MY_OWN_SECTION,"a",@progbits * .type FOO,@object * .size FOO,13 * FOO: * .string "VALUE OF FOO" * .text * .align 4 * .globl main * .type main,@function * main: * pushl %ebp * movl %esp, %ebp * popl %ebp * ret * .Lfe1: * .size main,.Lfe1-main * .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)" * * +----------------------------------------------------------------------------+ * * Note the '.section .MY_OWN_SECTION' etc line and also '.globl FOO' and 'FOO:'. * Assembly language programming involves dividing the program into sections. The * most important one being the '.text' section which is the executable code of the * program. The other being '.data' being the _initialised_ data, and sometimes '.bss' * section containing the uninitialised (but zeroed) data. There could be other such * sections too. * * More so we can have our own sections, besides the usual ones. Why is this needed ? * (Note that .MY_OWN_SECTION is a _section_, and FOO is a _symbol_ in .MY_OWN_SECTION) * Well first do the following to my_listing.c ... * $gcc -c my_listing.c * * We get my_listing.o _object file, and for this file run the following command ... * $objdump --section-headers my_listing.o * * We get the following screen dump ... * * test.o: file format elf32-i386 * Sections: * Idx Name Size VMA LMA File off Algn * 0 .text 00000008 00000000 00000000 00000034 2**2 * CONTENTS, ALLOC, LOAD, READONLY, CODE * * 1 .data 00000000 00000000 00000000 0000003c 2**2 * CONTENTS, ALLOC, LOAD, DATA * * 2 .bss 00000000 00000000 00000000 0000003c 2**2 * ALLOC * * 3 .note 00000014 00000000 00000000 0000003c 2**0 * CONTENTS, READONLY * * 4 .MY_OWN_SECTION 0000001b 00000000 00000000 00000050 2**0 * CONTENTS, ALLOC, LOAD, READONLY, DATA * * 5 .comment 00000036 00000000 00000000 0000006b 2**0 * CONTENTS, READONLY * * And finally run the following command also ... * $objdump --syms my_listing.o * * We get the following screen dump ... * test.o: file format elf32-i386 * SYMBOL TABLE: * 00000000 l df *ABS* 00000000 test.c * 00000000 l d .text 00000000 * 00000000 l d .data 00000000 * 00000000 l d .bss 00000000 * 00000000 l .text 00000000 gcc2_compiled. * 00000000 l d .MY_OWN_SECTION 00000000 * 00000000 l d .note 00000000 * 00000000 l d .comment 00000000 * * -----------NOTE THE NEXT LINE-------------------- * 00000000 g O .MY_OWN_SECTION 0000001b FOO * ^^^^^^^^^^^^^^ ^^^ * ------------------------------------------------- * 00000000 g F .text 00000005 main * * * Now remember that modules are compiled as elf32 objects, the insmod utility _links_ * it into the kernel. * * The whole idea behind this rather 'uglyfied' description is that, there has to be * a way for insmod to find out what params,symbols, documentations are embedded into * the module so that it can successfully link the module into the kernel. This is * achieved using the __attribute__((.section(".modinfo"))) = blah directive. * * And as you can see from the above dumps, that what we define through __attribute__ * gets into the assembly output and from there it gets embedded into the object code * also. The insmod extracts the information about the module from a _known_ location, * and that is '.section .modinfo' and does the linking. And these _insertions_ are * taken care of (for the programmers' ease) in this beautiful module.h header file. * * Now, just take a look at the macro that before the above discussion, it can now be * explained on the basis of above discussion ... consider the following module listing * * +--------------------------------------------------------------------------------+ * #define __KERNEL__ * #define MODULE * * #include * #include * * static int MY_MOD_PARM; * MODULE_PARM(MY_MOD_PARM,"i"); * * int init_module(void){return 0;} * * void cleanup_module(void){} * +--------------------------------------------------------------------------------+ * * Now compile this module using the 'gcc -c -Wall' command to get our_module.o and do * $objdump --syms our_module.o * * We get the following screen dump ... * * mod.o: file format elf32-i386 * SYMBOL TABLE: * 00000000 l df *ABS* 00000000 mod.c * 00000000 l d .text 00000000 * 00000000 l d .data 00000000 * 00000000 l d .bss 00000000 * 00000000 l .text 00000000 gcc2_compiled. * 00000000 l d .modinfo 00000000 * 00000000 l O .modinfo 00000018 __module_kernel_version * 00000000 l O .bss 00000004 MY_MOD_PARM * ^^^^ ^^^^^^^^^^^ * 00000000 l d .note 00000000 * 00000000 l d .comment 00000000 * 00000018 g O .modinfo 00000013 __module_parm_MY_MOD_PARM * ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ * 00000000 g F .text 0000000a init_module * 0000000c g F .text 00000005 cleanup_module * * This leaves just one thing to be explained although some experience in assembly programming * should've explained that thing on it's own ... but I'll write it in anyway. * * The section .modinfo contains the symbol __module_parm_MY_MOD_PARM, but note that the * .bss section has the symbol MY_MOD_PARM ... and that is simply because we _had_ declared * a global variable by that name (see the listing for the module file). * * Now we move on to the next macro, that should be simple enough if I have successfully * explained this one. * */ #define MODULE_PARM_DESC(var,desc) \ const char __module_parm_##var[] \ __attribute__ ((section(".modinfo"))) = \ "parm_desc_" __MODULE_STRING(var) "=" desc /* * This module creates an embeddable string constant which can be used to give a small * description of the parameter declared as loadable by the previous macro. * */ #define MODULE_GENERIC_TABLE(gtype,name) \ static const unsigned long __module_##gtype##_size \ __attribute__ ((unused)) = sizeof(struct gtype##_id); \ __attribute__ ((unused)) = name #define MODULE_DEVICE_TABLE(type,name) \ MODULE_GENERIC_TABLE(type##_device,name) /* * This macro exports information about devices supported by this module. * * The __attribute__ ((unused)) makes the symbols go to the section .rodata in the module. * This macro should be used while writing modules for pci,isapnp and usb devices. * * Another macro is available which writes information in the .modinfo section is * MODULE_SUPPORTED_DEVICE. * * Honestly speaking, I need to go a little deeper before I can correctly interpret the * meaning of this macro. * */ extern struct module __this_module; /* The module variable. */ #define THIS_MODULE (&__this_module) #define MOD_INC_USE_COUNT __MOD_INC_USE_COUNT(THIS_MODULE) #define MOD_DEC_USE_COUNT __MOD_DEC_USE_COUNT(THIS_MODULE) #define MOD_IN_USE __MOD_IN_USE(THIS_MODULE) /* * The use of these macros is quite obvious. * * __MOD_INC_USE_COUNT(THIS_MODULE) does an 'atomic_inc' on THIS_MODULE->uc.usecount and sets * the MOD_VISITED and MOD_USED_ONCE flags for THIS_MODULE. * * __MOD_DEC_USE_COUNT(THIS_MODULE) does an 'atomic_dec' on THIS_MODULE->uc.usecount and sets * the MOD_VISITED flag. * * (in the kernel sources the '__'ed version of INC and DEC macros are declared near the * __MOD_IN_USE macro) * */ #include static const char __module_kernel_version[] __attribute__ ((section(".modinfo"))) = "kernel_version=" UTS_RELEASE; /* * Simply define a string symbol __module_kernel_version in the .modinfo section whose * value is "kernel_version=" UTS_RELEASE. * * The macro UTS_RELEASE is declared in [~/linux/version.h]. * */ #ifdef MODVERSIONS static const char __module_using_checksums[] __attribute__((section(".modinfo"))) = "using checksums=1"; #endif /* * If module is kernel version dependent ( which it should, be by all means! ) then a string * symbol __module_using_checksums with value "using checksums=1" should appear in the * .modinfo section. * */ #define __EXPORT_SYMBOL(sym,str) \ const char __kstrtab_##sym[] \ __attribute__ ((section(".kstrtab"))) = str; \ const struct module_symbol __ksymtab_##sym \ __attribute__ ((section("__ksymtab"))) = \ { (unsigned long)&sym, __kstrtab_##sym } /* * Export a symbol to make it visible to the kernel, and in effect other modules too. * * Now this should be easy to interpret in one go ... i.e. * Declare a string symbol __kstrtab_##sym[] in a section .kstrtab whose value is 'str'. * And then, declare a 'struct module' type symbol in a section __ksymtab whose value is * '{&sym,__kstrtab_##sym[]}' * * Where struct module_symbol is defined as ... * struct module_symbol * { * unsigned long value, * const char *name * }; * */ #define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var,__MODULE_STRING(var)) /* * This macro is used to export a symbol without versioning info. * (Going by what I've learned ... DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE UP TO!) * */