使用netlink实现用户态和内核态通信

dengjingen 2013-01-13 06:54:30
我在linux内核中创建netlink和用户态通信,创建函数为nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL, THIS_MODULE);但是我编译的时候错误如下:drivers/built-in.o: In function `gfar_nl_init':
(.text+0x375ce): undefined reference to `__this_module'
无论是我创建一个模块,或者是加到已有的模块里面初始化都是这个错误。麻烦大虾指点啊。。。
...全文
357 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dengjingen 2013-01-15
  • 打赏
  • 举报
回复
接10楼,打印的错误信息: Unable to handle kernel paging request for data at address 0x00000025 Faulting instruction address: 0xc0281398 Oops: Kernel access of bad area, sig: 11 [#1] MPC831x RDB Modules linked in: NIP: c0281398 LR: c01efc04 CTR: 00000000 REGS: cf339b80 TRAP: 0300 Not tainted (2.6.29.6) MSR: 00009032 <EE,ME,IR,DR> CR: 22000424 XER: 20000000 DAR: 00000025, DSISR: 20000000 TASK = cf025430[686] 'socktest' THREAD: cf338000 GPR00: 00000000 cf339c30 cf025430 00000000 cf270980 000002ae 00000040 00004000 GPR08: cf270a28 00000000 000000c8 cf27d420 22000422 10019378 0fffb000 00000000 GPR16: b1cdb17a 00000000 00000000 00000000 00000000 10103234 10103224 00000000 GPR24: c0470000 fffff000 00000000 c0470000 000002ae 00000008 cf270980 00000020 NIP [c0281398] netlink_unicast+0xcc/0x2ec LR [c01efc04] kernel_receive+0x1ac/0x1e0 Call Trace: [cf339c30] [c0035bd8] printk+0x50/0x60 (unreliable) [cf339c70] [c01efc04] kernel_receive+0x1ac/0x1e0 [cf339ca0] [c02815b0] netlink_unicast+0x2e4/0x2ec [cf339ce0] [c0281eac] netlink_sendmsg+0x1b4/0x27c [cf339d30] [c0260214] sock_sendmsg+0xac/0xf4 [cf339e20] [c02605a0] sys_sendto+0xb8/0x100 [cf339f00] [c02610bc] sys_socketcall+0x1f0/0x1f4 [cf339f40] [c001142c] ret_from_syscall+0x0/0x38 --- Exception: c01 at 0xff71d04 LR = 0x1000092c Instruction dump: 2f830000 409e0010 801e00a0 7c1d0050 901e00a0 2f990000 38000000 409e0008 801a00d0 90010008 3f60c047 3b20f000 <881a0025> 7f84e378 813bba9c 54033032 Kernel panic - not syncing: Fatal exception in interrupt 大牛再帮忙看下呗,又耗费一天啊
dengjingen 2013-01-14
  • 打赏
  • 举报
回复
我现在内核可以接收到用户态发送的消息了,但是回复消息的时候出现了指针错误,不知道和你说的crash问题是否相关?发送函数代码如下: static int send_to_user(struct packet_info *info) { printk("test:inside function() %s.\n", __func__); int ret; int size; unsigned char *old_tail; struct sk_buff *skb; struct nlmsghdr *nlh; struct packet_info *packet;//struct packet_info结构体包含int型的变量src和dest size = NLMSG_SPACE(sizeof(*info)); skb = alloc_skb(size, GFP_ATOMIC); old_tail = skb->tail; nlh = NLMSG_PUT(skb, 0, 0, IMP2_K_MSG, size-sizeof(*nlh)); packet = NLMSG_DATA(nlh); memset(packet, 0, sizeof(struct packet_info)); packet->src = info->src; packet->dest = info->dest; nlh->nlmsg_len = skb->tail - old_tail; NETLINK_CB(skb).dst_group = 0; read_lock_bh(&user_proc.lock); ret = netlink_unicast(nlfd, skb, user_proc.pid, MSG_DONTWAIT);//此处执行时出错 read_unlock_bh(&user_proc.lock); return ret; nlmsg_failure: if(skb) kfree_skb(skb); return -1; } 通过打印定位出netlink_unicast函数初出错(如上代码注释),错误提示为指针错误,bad area. 再次麻烦大虾了。。。 [quote=引用 3 楼 nevil 的回复:] 修改内核的话你可以试试nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL, 0);可能会crash
dengjingen 2013-01-14
  • 打赏
  • 举报
回复
楼上的测试结果为: 第一行打印为实际地址,第二行为1,也就是偏移量。不知对否?
swq1982 2013-01-14
  • 打赏
  • 举报
回复
#define THIS_MODULE ((struct module *)0)这里的0是很有艺术的,这里表达相对(struct module *)结构开始的0地址。你可以通过如下来测试: struct s { char x; char y; }; int main() { struct s test; printf ("&test.y=%p\n", &test.y); printf ("&((struct s *)0)->y=%d", int(&((struct s *)0)->y)); return 0; }
dengjingen 2013-01-14
  • 打赏
  • 举报
回复
谢谢啊!!编译通过了。可是我定义过MODULE啊,和下面的描述不符啊 #ifdef MODULE #define THIS_MODULE (&__this_module) #else /* !MODULE */ #define THIS_MODULE ((struct module *)0) #endif 还有就是内核里面不是很多模块么,0怎么识别出本模块啊?
nevil 2013-01-14
  • 打赏
  • 举报
回复
嗯,那传0就可以了,不用THIS_MODULE
引用 5 楼 dengjingen 的回复:
我使用的不是ko这种动态加载方式,是静态加载。我吧init和exit放在内核已有的某个网卡模块里面了,自己创建模块还没弄明白,初学,以前做应用层得。
dengjingen 2013-01-14
  • 打赏
  • 举报
回复
我使用的不是ko这种动态加载方式,是静态加载。我吧init和exit放在内核已有的某个网卡模块里面了,自己创建模块还没弄明白,初学,以前做应用层得。
nevil 2013-01-14
  • 打赏
  • 举报
回复
因为只有定义了宏MODULE才会用到THIS_MODULE,而这个宏是由modpost自动生成的 所以你编built-in的话,只要传0就可以了

#ifdef MODULE
#define THIS_MODULE (&__this_module)
#else  /* !MODULE */
#define THIS_MODULE ((struct module *)0)
#endif
引用 2 楼 dengjingen 的回复:
有包含的,在网上查找资料更像是编译和连接的问题啊
nevil 2013-01-14
  • 打赏
  • 举报
回复
你不是通过insmod加入自己的模块而是在修改源码? 那比较麻烦的,因为THIS_MODULE其实指向的是你通过insmod加入的.ko生成的一个struct module结构,这是在init_module()的load_module()实现的
/* This is where the real work happens */
SYSCALL_DEFINE3(init_module, void __user *, umod,
		unsigned long, len, const char __user *, uargs)
{
	struct module *mod;
	int ret = 0;

	/* Must have permission */
	if (!capable(CAP_SYS_MODULE) || modules_disabled)
		return -EPERM;

	/* Only one module load at a time, please */
	if (mutex_lock_interruptible(&module_mutex) != 0)
		return -EINTR;

	/* Do all the hard work */
	mod = load_module(umod, len, uargs);
修改内核的话你可以试试nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL, 0);可能会crash
引用 2 楼 dengjingen 的回复:
有包含的,在网上查找资料更像是编译和连接的问题啊
dengjingen 2013-01-14
  • 打赏
  • 举报
回复
有包含的,在网上查找资料更像是编译和连接的问题啊
nevil 2013-01-14
  • 打赏
  • 举报
回复
module.h包含了么?

4,441

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧