posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          讀核筆記(1) - 內(nèi)核模塊

          Posted on 2008-02-07 11:22 ZelluX 閱讀(572) 評論(3)  編輯  收藏 所屬分類: System
          include/linux/module.h
          struct module:
          struct module
          {
              
          // 用于在用戶空間傳入module對象時判斷傳入的結(jié)構(gòu)是否有效
              unsigned long size_of_struct;    /* == sizeof(module) */
              
          struct module *next;
              
          // 指向本module的名稱,通常內(nèi)核空間里申請的name內(nèi)存位置都是緊跟在module{}結(jié)構(gòu)后面的
              const char *name;
              
          // 本module{}結(jié)構(gòu)的空間 + 緊接著這段內(nèi)存申請的歸module{}結(jié)構(gòu)使用的一部分空間
              
          // size = sizeof(struct module) + sizeof(misc data)
              unsigned long size;

              
          // 模塊引用計(jì)數(shù)器,還沒搞清楚這里的pad是干什么用的
              
          // i386中atomic_t的定義: typedef struct { volatile int counter; } atomic_t;
              union
              
          {
                  atomic_t usecount;
                  
          long pad;
              }
           uc;                /* Needs to keep its size - so says rth */

              
          // 模塊當(dāng)前狀態(tài),已初始化/運(yùn)行中/被移除/被訪問過等
              unsigned long flags;        /* AUTOCLEAN et al */

              
          // 定義的內(nèi)核模塊符號數(shù)
              unsigned nsyms;
              
          // 引用的模塊鏈表節(jié)點(diǎn)數(shù),遍歷模塊依賴性時使用
              unsigned ndeps;

              
          // 符號表
              struct module_symbol *syms;
              
          // 記錄依賴的其他模塊的數(shù)組
              struct module_ref *deps;
              
          // 記錄引用該模塊的其他模塊的數(shù)組
              struct module_ref *refs;
              
          // 初始化和刪除模塊時調(diào)用的函數(shù)指針
              int (*init)(void);
              
          void (*cleanup)(void);
              
          // 中斷向量表的入口和結(jié)束位置
              const struct exception_table_entry *ex_table_start;
              
          const struct exception_table_entry *ex_table_end;
          #ifdef __alpha__
              unsigned 
          long gp;
          #endif
              
          /* Members past this point are extensions to the basic
                 module support and are optional.  Use mod_member_present()
                 to examine them.  
          */

              
          // 這兩個指針維持一些模塊相關(guān)信息,方便卸載后再次裝載模塊時的配置
              const struct module_persist *persist_start;
              
          const struct module_persist *persist_end;
              
          int (*can_unload)(void);
              
          int runsize;            /* In modutils, not currently used */
              
          const char *kallsyms_start;    /* All symbols for kernel debugging */
              
          const char *kallsyms_end;
              
          const char *archdata_start;    /* arch specific data for module */
              
          const char *archdata_end;
              
          const char *kernel_data;    /* Reserved for kernel internal use */
          }
          ;

          struct module_symbol:
          保存目標(biāo)代碼中的內(nèi)核符號,讀取文件裝入模塊時通過這個數(shù)據(jù)結(jié)構(gòu)將里面包含的符號信息讀入。
          struct module_symbol
          {
              unsigned 
          long value; // 入口地址
               const char *name;    // 內(nèi)核符號名稱
          }
          ;

          struct module_ref:
          注意這里dep和ref記錄的不對稱,應(yīng)該可以看成是一個ref鏈表吧
          module{} 中的deps數(shù)組分別指向了各個依賴的module_ref{}
          struct module_ref
          {
              
          struct module *dep;    /* "parent" pointer */
              
          struct module *ref;    /* "child" pointer */
              
          struct module_ref *next_ref;
          }
          ;

          struct kernel_sym:
          在sys_get_kernel_syms()中用到的結(jié)構(gòu),該函數(shù)將內(nèi)核符號拷貝到用戶空間的kernel_sym{}中,從而可以在用戶態(tài)存放模塊信息。
          struct kernel_sym
          {
              unsigned 
          long value;    // 內(nèi)核符號地址
              char name[60];        /* should have been 64-sizeof(long); oh well */
          }
          ;

          module.c中的一些函數(shù)先略去了,書上蠻詳細(xì)的

          模塊的加載和卸載
          insmod的任務(wù):
          從命令行中讀入模塊名,確定代碼所在文件的位置
          計(jì)算需要的內(nèi)存
          執(zhí)行系統(tǒng)調(diào)用create_module(),傳遞新模塊的名稱和大小
          用QM_MODULES獲得所有已經(jīng)鏈接模塊的模塊名
          用QM_SYMBOL獲得內(nèi)核符號表和已經(jīng)鏈接到內(nèi)核的模塊的符號表
          使用這些信息重新定位該模塊文件中的代碼
          在用戶空間分配內(nèi)存,拷貝相關(guān)信息
          調(diào)用sys_init_module(),傳遞上面創(chuàng)建的用戶態(tài)的內(nèi)存區(qū)地址
          釋放用戶態(tài)內(nèi)存,結(jié)束

          rmmod的任務(wù):
          用QM_MODULES和QM_REFS取得已經(jīng)鏈接的模塊列表和依賴關(guān)系
          調(diào)用delete_module

          評論

          # re: 讀核筆記(1) - 內(nèi)核模塊  回復(fù)  更多評論   

          2008-02-07 14:27 by Lee.MaRS
          // 模塊引用計(jì)數(shù)器,還沒搞清楚這里的pad是干什么用的
          // i386中atomic_t的定義: typedef struct { volatile int counter; } atomic_t;
          union
          {
          atomic_t usecount;
          long pad;
          } uc; /**//* Needs to keep its size - so says rth */

          看它這里的注釋,似乎是為了保證sizeof(uc)至少為sizeof(long)

          # re: 讀核筆記(1) - 內(nèi)核模塊  回復(fù)  更多評論   

          2008-02-07 14:33 by ZelluX
          @Lee.MaRS
          哦,保證這個有什么用呢?對齊時方便嗎?

          # re: 讀核筆記(1) - 內(nèi)核模塊  回復(fù)  更多評論   

          2008-02-08 22:55 by Lee.MaRS
          @ZelluX
          除了對齊我也想不出還有什么別的用了
          主站蜘蛛池模板: 独山县| 伊川县| 灵寿县| 合作市| 梁河县| 湘潭县| 锡林浩特市| 双城市| 桐梓县| 延边| 垦利县| 玉林市| 林芝县| 阿拉善左旗| 平舆县| 隆安县| 邛崃市| 玉溪市| 工布江达县| 南昌市| 长宁区| 柳林县| 井陉县| 曲麻莱县| 布拖县| 新化县| 泰州市| 三都| 玛多县| 沂南县| 安平县| 房产| 西充县| 秦皇岛市| 临沧市| 永春县| 四川省| 永寿县| 乌兰察布市| 桐梓县| 通海县|