模块加载过程分析:INSMODDEMODEV.KO
模块加载过程分析:INSMODDEMODEV.KO
详细 驱动加载过程可以参考《深⼊理解Linux内核驱动》陈学松 著
insmod利⽤⽂件系统接⼝将数据读取到⽤户空间的⼀段内存中,然后通过系统调⽤sys_init_module让内核去处理模块加载的整个过程。
sys_init_module()执⾏过程可以分为两个部分。第⼀部分:调⽤load_module(),完成模块加载的核⼼任务;第⼆部分是在模块加载成功后
的后续⼯作。
long sys_init_module(void __user * umod, unsigned long len, const char __user* uargs);
—umod是指向⽤户空间demodev.ko⽂件映像的内存地址
—len是该⽂件的⼤⼩
—uargs是传递给模块的参数
static struct module *load_module(void __user * umod, unsigned long len, const char __user* uargs);
关于struct module结构体。内核⽤该结构体来表⽰加载到内核的模块(即模块在linux系统中的抽象),全局变量 modules为所有模块的
的标头。
struct module{
/*主要数据类型*/
enum module_state state; //记录模块状态
enum module_state
{
模块成功加载后的状态
MODULE_STATE_LIVE,
模块正在加载中
MODULE_STATE_COMING,
模块正在卸载中
MODULE_STATE_GOING,
};
struct list_head  list;  //内核⽤⼀个链表管理所有被成功加载的模块
char name[MODULE_NAME_LEN]; //记录模块名
/* Exported symbols */
const struct kernel_symbol *syms;  //导出符号表起始地址
const unsigned long *crcs;
unsigned int num_syms;  //导出符号校验码所在起始地址
/* Kernel parameters. */
struct kernel_param *kp;  //内核模块参数所在地址
/
* Startup function. */
int (*init)(void);  //指向模块初始化函数的指针,由module_init 宏指定的函数
}座便器漏水
sys_init_module(){
load_module(){
处理过程中会将demodev.ko的程序段分成 CORE section和INIT section两种类型,成为HDR视图(之所以这个分,是因为在模块加载过程结束时,系统会释关于导出符号: demodev.ko 可以使⽤内核导出的符号或者其他模块导出的符号,⾃⼰也可以向外部导出符号。使⽤宏EXPORT_SYMBOL、EXPORT_SYMBO
}
调⽤模块的初始化函数(模块可以不定义初始化函数);mod->init()
释放INIT section所占⽤的空间;
呼叫模块通知链;通过通知链,模块或者其他内核组件可以对其感兴趣的⼀些内核事件进⾏注册,当该事件发⽣时,这些模块或者组件当初注册的回调函数将}女士棉服
模块的版本控制:
你和必须⾸先启⽤ CONFIG_MODVERSIONS这个宏,在此基础上内核模块在编译时也必须启⽤CONFIG_MODVERSIONS,因此需要内核和模块双⽅协作才能实现版本控制。
模块编译是版本控制相关的⽂件有:
1、 内核源码⽬录下的 Module.symvers⽂件
2、 模块⽬录下的Module.symvers⽂件
3、 A模块和B模块间的依赖关系,需要在内核Module.symvers添加相应的依赖⽂件,否则即使编译能通过,加载⼀般会失败。
struct module  结构
{
enum module_state state;
/* Member of list of modules */
struct list_head list;
/* Unique handle for this module */
char name[MODULE_NAME_LEN];
/* Sysfs stuff. */
struct module_kobject mkobj;
struct module_attribute *modinfo_attrs;
const char *version;
const char *srcversion;
struct kobject *holders_dir;
/
* Exported symbols */
const struct kernel_symbol *syms;
const unsigned long *crcs;
unsigned int num_syms;
/* Kernel parameters. */
struct kernel_param *kp;
unsigned int num_kp;
/* GPL-only exported symbols. */
unsigned int num_gpl_syms;
const struct kernel_symbol *gpl_syms;
const unsigned long *gpl_crcs;
#ifdef CONFIG_UNUSED_SYMBOLS
/* unused exported symbols. */
const struct kernel_symbol *unused_syms;
const unsigned long *unused_crcs;
unsigned int num_unused_syms;
/* GPL-only, unused exported symbols. */
unsigned int num_unused_gpl_syms;
全国猪肉价格连降10周const struct kernel_symbol *unused_gpl_syms;
const unsigned long *unused_gpl_crcs;
#endif
/* symbols that will be GPL-only in the near future. */
const struct kernel_symbol *gpl_future_syms;
const unsigned long *gpl_future_crcs;
unsigned int num_gpl_future_syms;
/* Exception table */
unsigned int num_exentries;
struct exception_table_entry *extable;
/* Startup function. */
int (*init)(void);
/* If this is non-NULL, vfree after init() returns */
/* If this is non-NULL, vfree after init() returns */
void *module_init;
/
* Here is the actual code + data, vfree'd on unload. */
void *module_core;
/* Here are the sizes of the init and core sections */
unsigned int init_size, core_size;
/* The size of the executable code in each section.  */ unsigned int init_text_size, core_text_size;
/* Arch-specific module values */
struct mod_arch_specific arch;
unsigned int taints;    /* same bits as kernel:tainted */
#ifdef CONFIG_GENERIC_BUG
/* Support for BUG */
unsigned num_bugs;
十大灯饰品牌排行榜>穿衣镜的摆放
struct list_head bug_list;
struct bug_entry *bug_table;
#endif
#ifdef CONFIG_KALLSYMS
/*
* We keep the symbol and string tables for kallsyms.
* The core_* fields below are temporary, loader-only (they
* could really be discarded after module init).
*/
Elf_Sym *symtab, *core_symtab;
unsigned int num_symtab, core_num_syms;
char *strtab, *core_strtab;
/* Section attributes */
struct module_sect_attrs *sect_attrs;
/* Notes attributes */
struct module_notes_attrs *notes_attrs;
#endif
/* Per-cpu data. */
void *percpu;
/* The command line arguments (may be mangled).  People like        keeping pointers to this stuff */
char *args;
#ifdef CONFIG_TRACEPOINTS
struct tracepoint *tracepoints;
unsigned int num_tracepoints;
#endif
#ifdef CONFIG_TRACING
const char **trace_bprintk_fmt_start;
unsigned int num_trace_bprintk_fmt;
#endif
#ifdef CONFIG_EVENT_TRACING
struct ftrace_event_call *trace_events;
unsigned int num_trace_events;
#endif
感恩节祝福语 老师
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
unsigned long *ftrace_callsites;
unsigned int num_ftrace_callsites;
#endif
#ifdef CONFIG_MODULE_UNLOAD
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */ struct list_head modules_which_use_me;
/* Who is waiting for us to be unloaded */ struct task_struct *waiter;
/* Destruction function. */
void (*exit)(void);
#ifdef CONFIG_SMP
char *refptr;
#else
local_t ref;
#endif
#endif
#ifdef CONFIG_CONSTRUCTORS
/* Constructor functions. */
ctor_fn_t *ctors;
unsigned int num_ctors;
#endif
};

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。