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

          讀核筆記(1) - 內核模塊

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

              
          // 模塊引用計數器,還沒搞清楚這里的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 */

              
          // 模塊當前狀態,已初始化/運行中/被移除/被訪問過等
              unsigned long flags;        /* AUTOCLEAN et al */

              
          // 定義的內核模塊符號數
              unsigned nsyms;
              
          // 引用的模塊鏈表節點數,遍歷模塊依賴性時使用
              unsigned ndeps;

              
          // 符號表
              struct module_symbol *syms;
              
          // 記錄依賴的其他模塊的數組
              struct module_ref *deps;
              
          // 記錄引用該模塊的其他模塊的數組
              struct module_ref *refs;
              
          // 初始化和刪除模塊時調用的函數指針
              int (*init)(void);
              
          void (*cleanup)(void);
              
          // 中斷向量表的入口和結束位置
              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.  
          */

              
          // 這兩個指針維持一些模塊相關信息,方便卸載后再次裝載模塊時的配置
              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:
          保存目標代碼中的內核符號,讀取文件裝入模塊時通過這個數據結構將里面包含的符號信息讀入。
          struct module_symbol
          {
              unsigned 
          long value; // 入口地址
               const char *name;    // 內核符號名稱
          }
          ;

          struct module_ref:
          注意這里dep和ref記錄的不對稱,應該可以看成是一個ref鏈表吧
          module{} 中的deps數組分別指向了各個依賴的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()中用到的結構,該函數將內核符號拷貝到用戶空間的kernel_sym{}中,從而可以在用戶態存放模塊信息。
          struct kernel_sym
          {
              unsigned 
          long value;    // 內核符號地址
              char name[60];        /* should have been 64-sizeof(long); oh well */
          }
          ;

          module.c中的一些函數先略去了,書上蠻詳細的

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

          rmmod的任務:
          用QM_MODULES和QM_REFS取得已經鏈接的模塊列表和依賴關系
          調用delete_module

          評論

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

          2008-02-07 14:27 by Lee.MaRS
          // 模塊引用計數器,還沒搞清楚這里的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) - 內核模塊  回復  更多評論   

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

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

          2008-02-08 22:55 by Lee.MaRS
          @ZelluX
          除了對齊我也想不出還有什么別的用了
          主站蜘蛛池模板: 全椒县| 临泉县| 阳泉市| 白玉县| 元谋县| 旬阳县| 阿图什市| 巫山县| 汉沽区| 巧家县| 和顺县| 镇江市| 颍上县| 仲巴县| 松潘县| 年辖:市辖区| 汉源县| 广河县| 华坪县| 翁源县| 绵竹市| 建阳市| 高台县| 陆丰市| 丹棱县| 正蓝旗| 嘉禾县| 琼中| 太仓市| 陇川县| 宁城县| 呈贡县| 大港区| 泰兴市| 龙海市| 项城市| 嵊泗县| 沭阳县| 余干县| 湘潭市| 平和县|