• linux 模块结构


    struct module
    {
    unsigned long size_of_struct;
    struct module *next;
    const char *name;
    unsigned long size;

    union
    {
    atomic_t usecount;
    long pad;
    }uc;
    unsigned long flags;

    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
    const struct module_persist *persist_start;
    const struct module-persist *persist_end;
    int (*can_unload)(void);
    int runsize;
    const char *kallsyms_start;
    const char *kallsyms_end;
    const char *archdata_start;
    const char *archdata_end;
    const char *kernel_data;
    };

    struct module_symbol
    {
    unsigned long value;
    const char *name;
    }

    struct module_ref
    {
    struct module *dep; /*"parent"pointer*/
    struct module *ref; /*"child"pointer*/
    struct module_ref *next_ref;
    }

    struct kernel_sym
    {
    unsigned long value;
    char name[60];
    };

    //启动内核模块的初始化
    void __init int_modules(void)
    {
    kernel_module.nsyms=__stop___ksymtab-__start___ksymtab;

    arch_init_modules(&kernel_module);
    }


    //创建一个新模块
    asmlinkage unsigned long sys_create_modules(const char *name_user,size_t size)
    {
    char *name;
    long namelen,error;
    struct module *mod;
    unsigned long flags;

    if(!capable(CAP_SYS_MODULE)) //验证是否由权限执行
    {
    return -EPERM;
    }
    lock_kernel();
    if((namelen=get_mod_name(name_user,&name))<0) //从内核空间中申请一个页面,将用户空间的名称拷贝到内核空间
    {
    error=namelen;
    goto err0;
    }
    if(size<sizeof(struct module)+namelen) //检查入口参数size的长度,这个长度不能小于module{}结构的长度和模块的名称字符串的长度的和
    {
    error=-EINVAL;
    goto err1;
    }
    if(find_module(name)!=NULL) //在模块联表中查找是否已经有名为name的模块
    {
    error=-EEXIST;
    goto err1;
    }
    if((mod=(struct module*)module_map(size))==NULL) //module_map()宏取得内核空间用来存放模块数据的内存
    {
    error=-ENOMEM;
    goto err1;
    }

    memset(mod,0,sizeof(*mod));
    mod->size_of_struct=sizeof(*mod);
    mod->name=(char*)(mod+1);
    mod->size=size;
    memcpy((char*)(mod+1),name,namelen+1);

    put_mod_name(name); //释放name所占用的空间

    spin_lock_irqsave(&modlist_lock,flags); //把该module结构加到原来模块联表的头上
    mod->next=module_list;
    module_list=mod;
    spin_unlock_irqrestore(&modlist_lock,flags);

    error=(long)mod; //获得创建模块的地址
    goto err0;
    err1:
    put_mod_name(name);
    err0:
    unlock_kernel();
    return error; //返回模块的地址
    }
    Live together,or Die alone!
  • 相关阅读:
    配置文件和脚本文件区别
    .sh
    瘋耔思维空间
    vi编辑器的三种模式
    在ubuntu系统荣品开发配套JDK安装
    如何查看自己运行ubuntu是32位还是64位
    志气
    高仿微信朋友圈
    Java OCR tesseract 图像智能字符识别技术 Java代码实现
    构建基于Javascript的移动CMS——加入滑动
  • 原文地址:https://www.cnblogs.com/hzhida/p/2395653.html
Copyright © 2020-2023  润新知