/*NOTE: * Some FLAGS values haven't been described as yet ... will be done during the read up of * modutils ... kindly bear with this unpleasent delay :( . */ struct module { /* 1 */ unsigned long size_of_struct; /* * 1.1 * The module structure consists of some members which have to be present * while others are optional. * * 1.2 * It is also possible that new members other than the compulsory ones are * _added_ to the structure. * * Thus in the view of above, a macro called ,mod_member_present has been * declared in [module.h] which verifys wether a member is a constituent of * the module structure or not. * * 'size_of_struct' is used by mod_member_present to accomplish the same. * * mod_member_present finds out wether the _offset_ of the member in the * structure is less than or equal to 'size_of_struct', if so then the member * is a part of the structure, otherwise there _must_ be something wrong going * on. * */ /* 2 */ struct module *next; /* * 'struct module' is self refferential and the kernel maintains a _list_ * of all the loaded modules using this '*next' member. * */ /* 3 */ const char *name; /* 4 */ unsigned long size; /* * 4.1 * This could be _slightly_ confusing, but this member is used to save the * size of the _initialized_ module header. * * Why is it needed ? Well 'size_of_struct' simply saves the size the of the * module structure itself i.e. '*name' will contribute 4 bytes to 'size_of_struct' * whereas after initialization (the module is assigned a name after initialization) * '*name' will point a string of characters of some finite length which will * contribute to the 'size' member. * * Simply consider this compound statement ... * { * struct module foo; * foo.size_of_struct = sizeof(struct module); * . * . * foo.size = sizeof(foo); * . * . * } * */ /* 5 */ union { atomic_t usecount; unsigned long pad; }uc; /* * 5.1 * This member _remembers_ the usage count of this module i.e. the number of processes * requesting services from this module. A module cannot be unloaded unless the * value of usecount becomes 0. * * As with the other data structures in the kernel, the kernel _expects_ to find * module structure members at _known_ locations. In [atomic.h], atomic_t is defined * to be a single-membered structure i.e. the only member in 'atomic_t' is 'volatile * int counter'. It is declared as volatile so that "gcc doesn't try to be clever". * This _cleverness_ is a characteristic of "optimizing compilers" like gcc which * make rearrangements in the structure to get the best performance. However this * rearrangement needs to be prevented sometimes, and this is done by declaring the * required member as 'volatile'. * * 5.2 * Here, the kernel expects to the find the next member 'flags' at exactly 4 bytes from * 'uc', thats why it has been unioned with an 'unsigned long'. This is because there * seems to be a discrepancy as the "guaranteed usefull range of atomic_t is only * 24 bits" ( [~/include/asm-i386/atomic.h] ) * */ /* 6 */ unsigned long flags; /* * Consider this as a "status double word" for a module. The various flag bits are * * 6.1 * #define MOD_UNINITIALIZED 0 * Implies that a module entry has been added to the 'module_list' by * 'sys_create_module' but 'sys_init_module' hasn't yet been called. * * 6.2 * #define MOD_RUNNING 1 * Implies that 'sys_init_module' has been called and module is now running. * * 6.3 * #define MOD_DELETED 2 * Set this flag to prevent accidental dirty reads for this module. * * 6.4 * #define MOD_AUTOCLEAN 4 * * 6.5 * #define MOD_VISITED 8 * The module structure has been _poked_, as in usage count. * * 6.6 * #define MOD_USED_ONCE 16 * The module has been refferenced by a user process. * * 6.7 * #define MOD_JUST_FREED 32 * * 6.8 * #define MOD_INITIALIZING 64 * Implies that 'sys_init_module' is still executing and the module is not running. * */ /* 7 */ unsigned nsyms; /* * Number of symbols exported by the module. * */ /* 8 */ unsigned ndeps; /* * Number of modules on which this module depends. * */ /* 9 */ struct module_symbol *syms; /* * A linked list of exported module symbols. * * struct module_symbol * { * unsigned long value; * const char *name; * } * */ /* 10 */ struct module_ref *deps; /* * struct module_ref * { * struct module *dep; * struct module *ref; * struct module_ref *next; * } * * A list of all the modules on which this module depends. * */ /* 11 */ struct module_ref *refs; /* * A list of all the modules which depend on this module. * */ /* 12 */ int (*init)(void); /* * Pointer to the 'init' function of the module; * */ /* 13 */ void (*cleanup)(void); /* * Pointer to the 'cleanup' function of the module; * */ /* 14 */ const struct exception_table_entry *ex_table_start; const struct exception_table_entry *ex_table_end; /* * TODO:Dunno about this at all * */ /* 15 */ #ifdef __alpha__ unsigned long gp; #endif /* * TODO: Dunno about this too, at all! * */ /* THE FOLLOWING MEMBERS ARE THE OPTIONAL MEMBERS */ /* THESE MEMBERS STILL NEED TO BE DESCRIBED * Will do this during the read-up of modutils, that * seems to be the place which will answer a lot of * questions. */ const struct module_presist *persist_start; const struct module_presist *persist_end; int (*can_unload)(void); int runsize; const char *kallsyms_start; const char *kallsyms_end; const char *archdata_start; const char *archdata_end; const char *kernel_data; };