struct module構造体とTHIS_MODULE詳細

5276 ワード

構造体struct module
構造体struct moduleは、カーネルにカーネルモジュールを表し、insmod(実際にinit_moduleシステム呼び出しを実行)によって自分で作成したカーネルモジュールをカーネルに挿入すると、モジュールはstruct module構造体に関連付けられ、カーネルの一部となる.次に、構造体struct moduleの完全な定義を説明します.
   
 struct module
    {
        enum module_state state;
        struct list_head list;
        char name[MODULE_NAME_LEN];
 
        struct module_kobject mkobj;
        struct module_param_attrs *param_attrs;
        const char *version;
        const char *srcversion;
 
        const struct kernel_symbol *syms;
        unsigned int num_syms;
        const unsigned long *crcs;
 
        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);
        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;
    };

カーネルモジュールを挿入します.一般的には、システム呼び出しinit_を実際に呼び出すツールinsmodを使用します.module、このシステム呼び出し関数では、まずload_を呼び出します.moduleは、ユーザー空間から転送されたカーネルモジュールファイル全体をカーネルモジュールに作成し、struct module構造体を返します.カーネルでは、このカーネルモジュールをこの構造体で表します.
stateはモジュールの現在の状態です.これは列挙型変数であり、以下の値をとることができる:MODULE_STATE_LIVE,MODULE_STATE_COMING,MODULE_STATE_GOING.
enum module_state
{
    MODULE_STATE_LIVE,  //         (    ) 0
    MODULE_STATE_COMING, //           1 
    MODULE_STATE_GOING,  //           2
};

load_Module関数でモジュールの作成が完了したら、状態をMODULE_にします.STATE_COMING,sys_init_module関数でモジュールのすべての初期化作業が完了した後(モジュールをグローバルなモジュールリストに追加し、モジュール自体の初期化関数を呼び出すことを含む)、モジュール状態をMODULE_STATE_ライブ、最後にrmmodツールを使用してモジュールをアンインストールすると、システム呼び出しdelete_が呼び出されます.module、モジュールの状態をMODULE_にしますSTATE_GOING.これはモジュール内部のメンテナンスのステータスです.
    
listはリストのメンバーとして、すべてのカーネルモジュールがグローバルチェーンテーブルに維持され、チェーンテーブルヘッダはグローバル変数struct module*modulesです.新しく作成されたモジュールは、modules->nextで参照できるチェーンテーブルのヘッダに追加されます.
nameはモジュールの名前で、モジュールファイルのファイル名をモジュール名とするのが一般的です.このモジュールの識別子です.
また、マクロTHIS_についてもご紹介しますMODULE、その定義は以下のとおりです#define THIS_MODULE (&__this_module),__this_moduleはstruct module変数であり、現在のモジュールを表し、currentといくつか似ています.THIS_を通過できるMODULEマクロはモジュールのstruct module構造を参照し、次のモジュールを試してみます.
#include 
    MODULE_LICENSE("GPL"); 
    MODULE_AUTHOR("Jack Chen");/*  */
    MODULE_DESCRIPTION("HELLO");
    MODULE_VERSION("1.0");//   
    static int hello_init(void)
    {
        unsigned int cpu = get_cpu();
        struct module *mod;
        printk(KERN_ALERT "this module: %p==%p/n", &__this_module, THIS_MODULE );
        printk(KERN_ALERT "module state: %d/n", THIS_MODULE->state );
        printk(KERN_ALERT "module name: %s/n", THIS_MODULE->name );
              printk(KERN_ALERT"module version:%s
",THIS_MODULE->version); list_for_each_entry(mod, *(&THIS_MODULE->list.prev), list ) printk(KERN_ALERT "module name: %s/n", mod->name ); return 0; } static void hello_exit(void) { printk(KERN_ALERT "module state: %d/n", THIS_MODULE->state ); printk("find_module bye...
"); } module_init(hello_init); module_exit(hello_exit);

ownerはstruct module*タイプの構造体ポインタで、今あなたに教えているのはstruct module構造体がカーネルの中でカーネルモジュールを代表していることです.十七里のすべての代表が多くの人を代表しているように、誰を代表しているのか、彼らを選んだ人は知っています.同じように、struct module構造体ごとにどんなモジュールを代表しているのか、初期化されたモジュールがわかります.もちろん、この構造を初期化するのは駆動を書く人がすべきことではありません.さっき省略したinsmodやmodprobeからあなたが駆動するxxxまでです.Init関数の曲がりくねった過程でやったこと.insmodコマンドが実行されるとkernel/moduleが呼び出されます.cのシステム呼び出しinit_module、load_を呼び出すmodule関数は、ユーザ空間から入力されたカーネルモジュールファイル全体をカーネルモジュールに作成し、struct module構造体を返します.これにより、カーネルではこのカーネルモジュールを表す構造体になります.
THISを見てみましょうMODULE宏是什么意思
include/linux/module.hの定義は
85 #define THIS_MODULE (&__this_module)
現在のモジュールを表すstruct module変数で、その有名なcurrentといくつか似ていて、THIS_を通過することができます.MODULEマクロは、THIS_を使用するなど、モジュールのstruct module構造を参照する.MODULE->stateは、現在のモジュールの状態を取得します.なぜあの歳月の中で、ためらうことなくstruct usbをdriver構造のownerをTHIS_に設定MODULEですね.このownerポインタはあなたのモジュール自身を指しています.じゃあ今ownerはどうしてないと言ったの?これを言うと話が長くなるから,長々と話しましょう.その时、あなたはownerを初期化することを忘れたことがあるかどうか分かりませんが、どうせ多くの人が忘れてしまいます.みんなprobe、disconnectなど頭を働かす必要がある役に集中しています.これは頭を働かす必要はありません.数秒で指定するownerはかえって無視されがちです.容易に得られないものは往々にして日々考えて勝ち取る.そこで2006年の春節を前に、私たちが仕事をする気がなく、勉強する気がなく、春節を待っていたとき、Gregは一線を守り、ownerを取り除いた.そこで、何千万人ものusb駆動を書いた人は、いつもownerを初期化する必要はない.ownerを設定する必要はありませんが、coreには設定しないわけにはいきません.struct usb_driver構造にはownerはいないのではないでしょうか.しかし、その中に埋め込まれているstruct device_driver構造にはまだありますね.設定すればいいです.Gregは同時にusb_を追加しましたregister_driver()という層、usb_register()は、パラメータをTHIS_として指定することによりMODULEはそれを呼び出して、すべてのことをその中に移します.どうせusb_register()もインラインであり、呼び出しのオーバーヘッドは増加しません.