Chinaunix首页 | 论坛 | 博客
  • 博客访问: 807220
  • 博文数量: 247
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 501
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-12 21:53
个人简介

系统未建立

文章分类

全部博文(247)

文章存档

2021年(1)

2020年(3)

2019年(5)

2018年(3)

2017年(44)

2016年(75)

2015年(52)

2014年(63)

2013年(1)

我的朋友

分类: Android平台

2017-03-17 13:59:53

原文地址:关于__init与__exit 作者:apt_get

今天在编译linux-2.6.17的内核源码是出现如下的错误提示:
  LD      .tmp_vmlinux1
`gs_unbind' referenced in section `.init.text' of drivers/built-in.o: defined in discarded section `.exit.text' of drivers/built-in.o
`gs_unbind' referenced in section `.init.text' of drivers/built-in.o: defined in discarded section `.exit.text' of drivers/built-in.o
make: *** [.tmp_vmlinux1] 错误 1
    由上面的错误提示,先找到出错的地方,执行指令:grep -r -n ‘gs_unbind’ ./*
得到的结果为:
二进制文件 ./drivers/built-in.o 匹配
二进制文件 ./drivers/usb/gadget/built-in.o 匹配
二进制文件 ./drivers/usb/gadget/g_serial.o 匹配
二进制文件 ./drivers/usb/gadget/serial.o 匹配
./drivers/usb/gadget/serial.c:288:static void gs_unbind(struct usb_gadget *gadget);
./drivers/usb/gadget/serial.c:372:    .unbind =        __exit_p(gs_unbind),
./drivers/usb/gadget/serial.c:1510:        gs_unbind(gadget);
./drivers/usb/gadget/serial.c:1518:        gs_unbind(gadget);
./drivers/usb/gadget/serial.c:1536: * gs_unbind
./drivers/usb/gadget/serial.c:1541:static void __exit gs_unbind(struct usb_gadget *gadget)
./drivers/usb/gadget/serial.c:1558:    printk(KERN_INFO "gs_unbind: %s %s unbound\n", GS_LONG_NAME,
    打开文件serial.c,定位到gs_unbind()定义处,把函数定义片的__exit去掉,编译正常通过。那这里为什么会出错呢?我们还是先来看一下内核中有关__init与__exit的定义与说明。
    这两个宏均位于文件include/linux/init.h中,关于__init有如下的一段说明:
/* These macros are used to mark some functions or
* initialized data (doesn't apply to uninitialized data)
* as `initialization' functions. The kernel can take this
* as hint that the function is used only during the initialization
* phase and free up used memory resources after
*
* Usage:
* For functions:
*
* You should add __init immediately before the function name, like:
*
* static void __init initme(int x, int y)
* {
*    extern int z; z = x * y;
* }
*
* If the function has a prototype somewhere, you can also add
* __init between closing brace of the prototype and semicolon:
*
* extern int initialize_foobar_device(int, int, int) __init;
*
* For initialized data:
* You should insert __initdata between the variable name and equal
* sign followed by value, e.g.:
*
* static int init_variable __initdata = 0;
* static char linux_logo[] __initdata = { 0x32, 0x36, ... };
*
* Don't forget to initialize data not at file scope, i.e. within a function,
* as gcc otherwise puts the data into the bss section and not into the init
* section.
*
* Also note, that this data cannot be "const".
*/
/* These are for everybody (although not all archs will actually
   discard it in modules) */
#define __init        __section(.init.text) __cold
#define __initdata    __section(.init.data)
#define __initconst    __section(.init.rodata)
#define __exitdata    __section(.exit.data)
#define __exit_call    __used __section(.exitcall.exit)
#ifdef MODULE
#define __exitused
#else
#define __exitused  __used
#endif
#define __exit          __section(.exit.text) __exitused __cold
   至此,应该明白为什么会出错了吧。函数定义的时候加上__exit就说明这个函数特定用于模块退出的时候这样在其它地方就不能使用了,所以在连接的时候就会报错。
   init.h中还有许多内核中要用到的宏,有兴趣的话,可以再进行研究。
阅读(1032) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~