linux中创建模块,调用do_fork,插入模块的时候,显示失败

mx_try 2018-06-12 04:19:54
代码如下:

#include <linux/init.h>
#include <linux/module.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <linux/thread_info.h>
#include <linux/slab.h>
#include <linux/sched.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sun");

static int __init myModule_init(void)
{

struct pt_regs *regs;

long id=do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, NULL, NULL);

printk(KERN_ALERT"myModule init----fork_id:%d.\r\n",id);

return 0;
}

static void __exit myModule_exit(void)
{
printk(KERN_ALERT"myModule exit.\r\n");
}

module_init(myModule_init);
module_exit(myModule_exit);
然后编译成功后,insmod page.ko,出现下面错误:

insmod: ERROR: could not insert module page.ko: Unknown symbol in module
查看 dmesg | tail :

[108843.437019] page: Unknown symbol do_fork (err 0)
查看依赖关系:

modinfo page.ko
filename: /home/sun/kernel_code/page.ko
author: colorfulshark@hotmail.com
license: GPL
rhelversion: 7.4
srcversion: 3913DBD14892947BDDCE568
depends:
vermagic: 3.10.0-693.el7.x86_64 SMP mod_unload modversions
看了相关资料,是不是要要在kernelfork.c修改,添加:

EXPORT_SYMOBL(do_fork)
然后重新编译linux内核,但是我的是x86平台,虚拟机重新编译运行比较慢,我就不知道linux内核代码是如何调用do_fork函数的?

#include <linux/sched.h>已经含有do_fork函数了,为什么不能调用?
...全文
1810 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
CHENG Jian 2018-09-07
从Linux内核的2.6某个版本开始,内核引入了导出符号的机制。 只有在内核中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL导出的符号才能在内核模块中直接使用。 然而,do_fork 这种危险的函数 内核是不会导出的。 可以参照 获取Linux内核未导出符号的几种方式
回复
john_liqinghan 2018-08-30
首先代码就有问题了。do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, NULL, NULL); regs本来就是空了,还能有sp成员?
回复
jklinux 2018-06-15
有可能是系统限制直接调用此函数吧
回复
mx_try 2018-06-14
引用 3 楼 jklinux 的回复:
你用的内核版本多少?linux-3.4版本里的do_fork参数不一样了:

1567 long do_fork(unsigned long clone_flags,
1568           unsigned long stack_start,
1569           struct pt_regs *regs,
1570           unsigned long stack_size,
1571           int __user *parent_tidptr,
1572           int __user *child_tidptr)

/////////////////////////////////////////////////////////////////////////
非得到这函数可以参考内核里应用代码,如我找到的:
[code=c]
609 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
610 {
611     struct pt_regs regs;
612 
613     memset(®s, 0, sizeof(regs));
614 
615     regs.ARM_r4 = (unsigned long)arg;
616     regs.ARM_r5 = (unsigned long)fn;
617     regs.ARM_r6 = (unsigned long)kernel_thread_exit;
618     regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
619     regs.ARM_pc = (unsigned long)kernel_thread_helper;
620     regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
621 
622     return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
623 }
624 EXPORT_SYMBOL(kernel_thread);
[/code]
我的内核版本是3.10.0-693.el7.x86_64 换到版本3.2.79,do_fork的参数就跟你的版本一致 然后我调用kernel_thread就不会报错了。谢谢 但是我还是有些不明白,为什么do_fork不能调用?cat /proc/kallsyms | grep do_fork 的结果显示也是包含do_fork的, 我后面自己修改内核代码,添加EXPORT_SYMBOL(do_fork),依旧一样的结果,不可以insmod,会报错
回复
jklinux 2018-06-14
你用的内核版本多少?linux-3.4版本里的do_fork参数不一样了:

1567 long do_fork(unsigned long clone_flags,
1568           unsigned long stack_start,
1569           struct pt_regs *regs,
1570           unsigned long stack_size,
1571           int __user *parent_tidptr,
1572           int __user *child_tidptr)

/////////////////////////////////////////////////////////////////////////
非得到这函数可以参考内核里应用代码,如我找到的:
[code=c]
609 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
610 {
611     struct pt_regs regs;
612 
613     memset(®s, 0, sizeof(regs));
614 
615     regs.ARM_r4 = (unsigned long)arg;
616     regs.ARM_r5 = (unsigned long)fn;
617     regs.ARM_r6 = (unsigned long)kernel_thread_exit;
618     regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
619     regs.ARM_pc = (unsigned long)kernel_thread_helper;
620     regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
621 
622     return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
623 }
624 EXPORT_SYMBOL(kernel_thread);
[/code]
回复
mx_try 2018-06-13
引用 1 楼 jklinux 的回复:
先通过"cat /proc/kallsyms | grep do_fork" 确认你的内核有没有导出此函数
这是我查询的结果: root@ubuntu:~# cat /proc/kallsyms | grep do_fork c1059820 T do_fork c158b40f t do_fork_idl 我上网搜索了相关知识,do_fork确实是有导出此函数,但是内核也没有export_symbol
回复
jklinux 2018-06-12
先通过"cat /proc/kallsyms | grep do_fork" 确认你的内核有没有导出此函数
回复
相关推荐
发帖
Linux_Kernel
创建于2007-08-27

4152

社区成员

Linux/Unix社区 内核源代码研究区
申请成为版主
帖子事件
创建了帖子
2018-06-12 04:19
社区公告
暂无公告