详细 驱动加载过程可以参考《深入理解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(){
处理过程中会将d