Linux内核源代码情景分析-insmod

    看本文前,先看着篇文章,Linux字符设备驱动

    insmod,大体上所做的事,有这么一些:

    1、打开待安装模块并将其读入到用户空间。所谓“模块”就是经过编译但未经连接的.o文件。

    2、模块中必定有一些在模块内部无法落实的符号(函数名或变量名),对这些符号的引用必须连接到内核中的相应符号。为此目的,需要通过系统调用query_module向内核询问这些符号在内核中的地址。如果内核允许"移出"这些符号的地址,就会返回有关的"符号表“。有些符号可能并不属于内核本身,而属于已经安装的其他模块。

    至此在用户空间中完成了单向连接的模块镜像。后面init_module中参数mod_user,前半部分是module结构(里面的指针指向了后半部分的数据),后半部分是name大小+模块镜像(里面包含init_module和cleanup_module)+其他参数(例如deps)的集合体

    3、然后,通过系统调用create_module在内核中创建一个module数据结构,并且"预订"所需的系统(内核)空间。

    4、最后,通过系统调用init_module,把用户空间中完成了单向连接的模块映像装入内核空间,再调用模块中一个名为init_module的函数(在Linux字符设备驱动一文中就是freg_init)。


    接下来,我们解释query_module,代码如下:

asmlinkage long
sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,//name_user为查询对象所在模块的模块名,查询的结果通过缓冲区buf返回
		 size_t *ret)
{
	struct module *mod;
	int err;

	lock_kernel();
	if (name_user == NULL)
		mod = &kernel_module;
	else {
		long namelen;
		char *name;

		if ((namelen = get_mod_name(name_user, &name)) < 0) {//把name从用户空间拷贝到系统空间
			err = namelen;
			goto out;
		}
		err = -ENOENT;
		if (namelen == 0)//如果为0,则指向内核本身
			mod = &kernel_module;
		else if ((mod = find_module(name)) == NULL) {//在module_list中寻找相应的module结构
			put_mod_name(name);
			goto out;
		}
		put_mod_name(name);
	}

	switch (which)
	{
	case 0:
		err = 0;
		break;
	case QM_MODULES:
		err = qm_modules(buf, bufsize, ret);
		break;
	case QM_DEPS:
		err = qm_deps(mod, buf, bufsize, ret);//所依赖模块的个数,buf为这些模块的模块名
		break;
	case QM_REFS:
		err = qm_refs(mod, buf, bufsize, ret);
		break;
	case QM_SYMBOLS:
		err = qm_symbols(mod, buf, bufsize, ret);
		break;
	case QM_INFO:
		err = qm_info(mod, buf, bufsize, ret);
		break;
	default:
		err = -EINVAL;
		break;
	}
out:
	unlock_kernel();
	return err;
}

struct module *
find_module(const char *name)
{
	struct module *mod;

	for (mod = module_list; mod ; mod = mod->next) {
		if (mod->flags & MOD_DELETED)
			continue;
		if (!strcmp(mod->name, name))
			break;
	}

	return mod;
}
static int
qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
{
	size_t i, space, l
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值