linux内核两个模块编译,linux内核模块编译链接与加载剖析二

模块加载

当我们执行insmod的时候发生了什么?我们查看一下linux3.6代码在加载内核模块的时候做了什么

内核中处理模块的调用关系

include/linux/syscalls.h

#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)

#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)

#ifdef CONFIG_FTRACE_SYSCALLS

#define SYSCALL_DEFINEx(x, sname, ...)\

static const char *types_##sname[] = {\

__SC_STR_TDECL##x(__VA_ARGS__)\

};\

static const char *args_##sname[] = {\

__SC_STR_ADECL##x(__VA_ARGS__)\

};\

SYSCALL_METADATA(sname, x);\

__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

#else

#define SYSCALL_DEFINEx(x, sname, ...)\

__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)

#endif

#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS

#define SYSCALL_DEFINE(name) static inline long SYSC_##name

#define __SYSCALL_DEFINEx(x, name, ...)\

asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__));\

static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__));\

asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__))\

{\

__SC_TEST##x(__VA_ARGS__);\

return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__));\

}\

SYSCALL_ALIAS(sys##name, SyS##name);\

static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))

#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */

#define SYSCALL_DEFINE(name) asmlinkage long sys_##name

#define __SYSCALL_DEFINEx(x, name, ...)\

asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))

#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */

asmlinkage long sys_init_module(void __user *umod, unsigned long len,

const char __user *uargs);

asmlinkage long sys_delete_module(const char __user *name_user,

unsigned int flags);

调用关系

sys_init_module

|----->load_module

|           |----->layout_and_allocate

|           |              |----->setup_load_info

|           |              |----->check_modinfo

|           |----->find_module_sections

|           |----->setup_modinfo

|           |----->simplify_symbols

|           ...

|----->do_one_initcall

...

setup_load_info

setup_load_info有一段代码,会查找".gnu.linkonce.this_module"这个段,如果找到后会把该段的虚拟地址给mod变量,在编译连接过程中我已知道该段存放了什么内容,主要是init和cleanup函数

info->index.mod = find_sec(info, ".gnu.linkonce.this_module");

if (!info->index.mod) {

printk(KERN_WARNING "No module found in object\n");

return ERR_PTR(-ENOEXEC);

}

/* This is temporary: point mod into copy of data. */

mod = (void *)info->sechdrs[info->index.mod].sh_addr;

check_modinfo->set_license->add_taint_module->add_taint

这是一个对module进行license检查的过程,如果模块内没有使用license则会打印一下内核受到污染的信息

static void set_license(struct module *mod, const char *license)

{

if (!license)

license = "unspecified";

if (!license_is_gpl_compatible(license)) {

if (!test_taint(TAINT_PROPRIETARY_MODULE))

printk(KERN_WARNING "%s: module license '%s' taints "

"kernel.\n", mod->name, license);

add_taint_module(mod, TAINT_PROPRIETARY_MODULE);

}

}

void add_taint(unsigned flag)

{

/*

* Can't trust the integrity of the kernel anymore.

* We don't call directly debug_locks_off() because the issue

* is not necessarily serious enough to set oops_in_progress to 1

* Also we want to keep up lockdep for staging/out-of-tree

* development and post-warning case.

*/

switch (flag) {

case TAINT_CRAP:

case TAINT_OOT_MODULE:

case TAINT_WARN:

case TAINT_FIRMWARE_WORKAROUND:

break;

default:

if (__debug_locks_off())

printk(KERN_WARNING "Disabling lock debugging due to kernel taint\n");

}

set_bit(flag, &tainted_mask);

}

do_one_initcall

执行传入的函数指针mod->init也就是我们注册的初始化函数

模块卸载

sys_delete_module

|----->capable

|

|----->free_module

...

sys_delete_module

/* Final destruction now no one is using it. */

if (mod->exit != NULL)

mod->exit();

blocking_notifier_call_chain(&module_notify_list,

MODULE_STATE_GOING, mod);

async_synchronize_full();

模块卸载相对比较简单,调用退出函数,处理一下模块未处理的任务,进行数据同步然后释放内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值