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
struct module:
























































struct module_symbol:
保存目標(biāo)代碼中的內(nèi)核符號,讀取文件裝入模塊時通過這個數(shù)據(jù)結(jié)構(gòu)將里面包含的符號信息讀入。





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






struct kernel_sym:
在sys_get_kernel_syms()中用到的結(jié)構(gòu),該函數(shù)將內(nèi)核符號拷貝到用戶空間的kernel_sym{}中,從而可以在用戶態(tài)存放模塊信息。





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