Data structures related to “kernel modules” in Linux

[Abstract] This article explains in detail the kernel data structure related to modules in Linux, so that everyone can understand the corresponding code and ideas in learning and understanding kernel source code or driver programming.

3. Data structures related to kernel modules

Table of Contents

  • THIS_MODULE macro
  • module structure
  • module_use

3.1 THIS_MODULE macro

  • Similar to the CURRENT macro, the struct module structure pointer of the module can be referenced through the THIS_MODULE macro.

  • Located at \linux-2.6.32.63\include\linux\module.h

    #ifdef MODULE
        #define MODULE_GENERIC_TABLE(gtype,name) \
        extern const struct gtype##_id __mod_##gtype##_table \
          __attribute__ ((unused, alias(__stringify(name))))
        
        extern struct module __this_module;
        #define THIS_MODULE ( &__this_module)
    #else /* !MODULE */
        #define MODULE_GENERIC_TABLE(gtype,name)
        #define THIS_MODULE ((struct module *)0)
    #endif
    
  • The symbol __this_module is generated after loading into the kernel. After the insmod command is executed, it will call a system call sys_init_module in kernel/module.c, which will call the load_module function to create a kernel module from the entire kernel module file passed in by the user space, and return a struct module structure. , the kernel module is represented by this structure in the kernel. THIS_MODULE is similar to CURRENT of the process.

  • For the analysis of the system call kernel code principle of sys_init_module and load_module, please refer to http://www.cnblogs.com/LittleHann/p/3920387.html

3.2 module structure

  • The struct module represents a kernel module in the kernel. When you insert your own kernel module into the kernel through insmod (actually execute the sys_init_module system call), the module is associated with a struct module structure and becomes a part of the kernel, that is to say, in In the kernel, the module structure represents a kernel module (similar to the concepts of kprocess and kthread under windows).

    struct module
    {<!-- -->
        /*
        1. enum module_state state
        enum module_state
        {
            MODULE_STATE_LIVE, //The module is currently in normal use (survival state)
            MODULE_STATE_COMING, //The module is currently being loaded
            MODULE_STATE_GOING, //The module is currently being unloaded
        };
        load_module function: After completing part of the creation of the module, set the state to MODULE_STATE_COMING
        sys_init_module function: After completing all the initialization work of the module, add the module to the global module list,
        Call the initialization function of the module itself), set the module state to MODULE_STATE_LIVE
        When using the rmmod tool to uninstall a module, the system call delete_module will be called, and the state of the module will be set to MODULE_STATE_GOING
        */
        enum module_state state;
    
        /*
        2. struct list_head list
        list is a member of a list, all kernel modules are maintained in a global linked list,
        The head of the linked list is a global variable struct module *modules. Any newly created module will be added to the head of this linked list
        */
        struct list_head list;
        
        /*
        3. char name[MODULE_NAME_LEN]
        name is the name of the module. Generally, the file name of the module file is used as the module name. It is an identifier for this module
        */
        char name[MODULE_NAME_LEN];
    
        struct module_kobject mkobj; //see note below
     
        struct module_param_attrs *param_attrs;
        const char *version;
        const char *srcversion;
        
        /* Exported symbols */
        const struct kernel_symbol *syms;
        unsigned int num_syms;
        const unsigned long *crcs;
    
        /* GPL-only exported symbols. */
        const struct kernel_symbol *gpl_syms;
        unsigned int num_gpl_syms;
        const unsigned long *gpl_crcs;
    
        unsigned int num_exentries;
        const struct exception_table_entry *extable;
    
        int (*init)(void);
        /*
        Initialization related
        */
        void *module_init;
        void *module_core;
        unsigned long init_size, core_size;
        unsigned long init_text_size, core_text_size;
        struct mod_arch_specific arch;
        int unsafe;
        int license_gplok;
    
    #ifdef CONFIG_MODULE_UNLOAD
        struct module_ref ref[NR_CPUS];
        struct list_head modules_which_use_me;
        struct task_struct *waiter;
        void (*exit)(void);
    #endif
    
    #ifdef CONFIG_KALLSYMS
        Elf_Sym *symtab;
        unsigned long num_symtab;
        char *strtab;
        struct module_sect_attrs *sect_attrs;
    #endif
        void *percpu;
        char *args;
    };
    
  • About struct module_kobject mkobj

    • This member is a structure type, and the definition of the structure is as follows:

      struct module_kobject
      {<!-- -->
          struct kobject kobj;
          struct module *mod; //point to the struct module member containing it
      };
      
    • The kobject in the module_kobject structure is the basic structure that makes up the device model. The device model is a new concept that appeared in the 2.6 kernel, which realizes the general abstract description of the system. It was originally understood as a simple reference count, but now there are many members,
      The tasks it can handle and the code it supports include: object reference counting; sysfs representation; structure association; hot-plug event processing. The following is the definition of the kobject structure:

      struct kobject
      {<!-- -->
            //k_name and name are the name of the kernel object, in the embedded kobject of the kernel module, the name is the name of the kernel module
            const char *k_name;
            char name[KOBJ_NAME_LEN];
          
            /*
             *kref is the reference count of the kobject, when the newly created kobject is added to kset (calling kobject_init),
             *The reference count is increased by 1, and then when the kobject is associated with its parent, the reference count is increased by 1, so a newly created
             *kobject whose reference count is always 2
             */
            struct kref kref;
      
            //entry is a node as a linked list, all kobjects of the same type under the same subsystem are linked into a linked list
            struct list_head entry;
      
            //parent points to the upper node in the hierarchical structure to which the kobject belongs, and the parent of all kernel modules is module
            struct kobject *parent;
      
           /*
            * Member kset is a collection of kobjects embedded in the same type of structure. The following is the definition of the struct kset structure:
                struct kset
                {
                    struct subsystem *subsys;
                    struct kobj_type *ktype;
                    struct list_head list;
                    spinlock_t list_lock;
                    struct kobject kobj;
                    struct kset_uevent_ops * uevent_ops;
                };
            */
            struct kset *kset;
      
            //ktype is the attribute of the module, these attributes will be displayed in the sysfs directory of kobject
            struct kobj_type *ktype;
      
            //dentry is a node related to the file system
            struct dentry *dentry;
      };
      
  • As can be seen from the struct module structure, in the kernel state, if we want to refer to the linked list of the current kernel module, we can use any of the following three:

    • struct module->list
    • struct module->mkobj->kobj->entry
    • struct module->mkobj->kobj->kset
  • expand link

    • http://lxr.free-electrons.com/source/include/linux/module.h
    • http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/module.h
    • http://blog.chinaunix.net/uid-9525959-id-2001630.html
    • http://blog.csdn.net/linweig/article/details/5044722

3.3 module_use

/*
 *source/include/linux/module.h
 */

/* modules using other modules: kdb wants to see this. */
struct module_use
{<!-- -->
    struct list_head source_list;
    struct list_head target_list;
    struct module *source, *target;
};
  • The two results “struct module_use” and “struct module->module_which_use_me” together combine and guarantee dependencies in kernel modules.
  • If module B uses the functions provided by module A, then there is a relationship between module A and module B, which can be viewed from two aspects:
    1. Module B depends on module A – unless module A is already resident in kernel memory, module B cannot be loaded.
    2. Module B references module A – module A cannot be removed from the kernel unless module B has been removed. In the kernel, this relationship is called “module B uses module A”.
  • For each module B that uses the functions in module A, a module_use structure instance will be created, which will be added to the modules_which_use_me linked list in the module instance of module A (the dependent module), and modules_which_use_me points to the module of module B instance. After understanding the performance of the dependencies between modules in the data structure, it is easy to enumerate the dependencies of all modules.