报错误in expansion of macro 'module_init'之分析

卫深
2023-12-01

 Warning (unit_address_vs_reg): Node /memory has a reg or ranges property, but no unit name
Warning (unit_address_vs_reg): Node /reserved-memory/ramoops has a reg or ranges property, but no unit name
  GZIP    kernel/config_data.gz
  CHK     kernel/config_data.h
  CC [M]  drivers/usb/gadget/function/f_fs.o
In file included from /home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:25:0:
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:128:42: error: redefinition of '__inittest'
  static inline initcall_t __maybe_unused __inittest(void)  \
                                          ^                                                                     #define module_init(initfn)                    \
                                                                                                                static inline initcall_t __maybe_unused __inittest(void)        \
                                                                                                                { return initfn; }                    \
                                                                                                                int init_module(void) __attribute__((alias(#initfn)));
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4211:1: note: in expansion of macro 'module_init'
 module_init(ffs_init);                                                                                        module_init(ffs_init);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:128:42: note: previous definition of '__inittest' was here
  static inline initcall_t __maybe_unused __inittest(void)  \                                                     #define module_init(initfn)                    \
                                                                                                                    static inline initcall_t __maybe_unused __inittest(void)        \
                                                                                                                    { return initfn; }                    \
                                                                                                                    int init_module(void) __attribute__((alias(#initfn)));
                                          ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/usb/composite.h:637:2: note: in expansion of macro 'module_init'
  module_init(_name ## mod_init);     \                                                                                #define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc)    \
                                                                                                                DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc)        \
                                                                                                                static int __init _name ## mod_init(void)            \
                                                                                                                {                                \
                                                                                                                    return usb_function_register(&_name ## usb_func);    \
                                                                                                                }                                \
                                                                                                                static void __exit _name ## mod_exit(void)            \
                                                                                                                {                                \
                                                                                                                    usb_function_unregister(&_name ## usb_func);        \
                                                                                                                }                                \
                                                                                                                module_init(_name ## mod_init);                    \
                                                                                                                module_exit(_name ## mod_exit)
  ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4198:1: note: in expansion of macro 'DECLARE_USB_FUNCTION_INIT'
 DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);                                                        DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:130:6: error: redefinition of 'init_module'
  int init_module(void) __attribute__((alias(#initfn)));                                                    #define module_init(initfn)                    \
                                                                                                            static inline initcall_t __maybe_unused __inittest(void)        \
                                                                                                            { return initfn; }                    \
                                                                                                            int init_module(void) __attribute__((alias(#initfn)));
      ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4211:1: note: in expansion of macro 'module_init'
 module_init(ffs_init);                                                                                        module_init(ffs_init);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:130:6: note: previous definition of 'init_module' was here
  int init_module(void) __attribute__((alias(#initfn)));
      ^                                                                                                        #define module_init(initfn)                    \
                                                                                                            static inline initcall_t __maybe_unused __inittest(void)        \
                                                                                                            { return initfn; }                    \
                                                                                                            int init_module(void) __attribute__((alias(#initfn)));
                                                                                                        /home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/usb/composite.h:637:2: note: in expansion of macro 'module_init'
                                                                                                          module_init(_name ## mod_init);     \
                                                                                                          ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4198:1: note: in expansion of macro 'DECLARE_USB_FUNCTION_INIT'
 DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
 ^                                                                                                            DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:134:42: error: redefinition of '__exittest'
  static inline exitcall_t __maybe_unused __exittest(void)  \
                                          ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4220:1: note: in expansion of macro 'module_exit'
 module_exit(ffs_exit);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:134:42: note: previous definition of '__exittest' was here
  static inline exitcall_t __maybe_unused __exittest(void)  \
                                          ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/usb/composite.h:638:2: note: in expansion of macro 'module_exit'
  module_exit(_name ## mod_exit)
  ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4198:1: note: in expansion of macro 'DECLARE_USB_FUNCTION_INIT'
 DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:136:7: error: redefinition of 'cleanup_module'
  void cleanup_module(void) __attribute__((alias(#exitfn)));
       ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4220:1: note: in expansion of macro 'module_exit'
 module_exit(ffs_exit);
 ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/module.h:136:7: note: previous definition of 'cleanup_module' was here
  void cleanup_module(void) __attribute__((alias(#exitfn)));
       ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/include/linux/usb/composite.h:638:2: note: in expansion of macro 'module_exit'
  module_exit(_name ## mod_exit)
  ^
/home/user33/g6pla1/LINUX/android/kernel/msm-4.4/drivers/usb/gadget/function/f_fs.c:4198:1: note: in expansion of macro 'DECLARE_USB_FUNCTION_INIT'
 DECLARE_USB_FUNCTION_INIT(ffs, ffs_alloc_inst, ffs_alloc);    

 

在前面helloworld的编写里面,我们使用了两个宏分别是module_init和module_exit,这里分析下为什么使用这两个宏。

在写模块的时候有两个特殊的函数,分别是init_module和cleanup_module,这两个函数分别在insmod的时候和rmmod的时候调用,并且insmod和rmmod只识别这两个特殊的函数,可是我们前面的例子里面并没有这两个函数。怎么会这样呢,那就必须得说说module_init/module_exit了。

         一个驱动可以作为一个模块动态的加载到内核里,也可以作为内核的一部分静态的编译进内核,module_init/module_exit也就有了两个含义:

一、动态编译成模块

在内核里有如下定义:

         /*Each module must use one module_init(). */

#define module_init(initfn)                                            \

         staticinline initcall_t __inittest(void)               \

         {return initfn; }                                              \

         intinit_module(void) __attribute__((alias(#initfn)));

 

/* This is only required if youwant to be unloadable. */

#define module_exit(exitfn)                                          \

         staticinline exitcall_t __exittest(void)             \

         {return exitfn; }                                             \

         voidcleanup_module(void) __attribute__((alias(#exitfn)));

 

         首先我们可以发现发现module_init有两个含义:

         1、验证加载函数的格式

static inline initcall_t__inittest(void)               \

{ return initfn; }

这个函数的作用是验证我们穿过来的加载函数格式是否正确,linux内核规定加载函数的的原型是:

typedef int(*initcall_t)(void);

         所以我们写加载函数的时候必须是返回值为int参数为void的函数,这个在内核里要求比较严格,所以我们写加载函数的时候必须按照这个约定。

         2、定义别名

         intinit_module(void) __attribute__((alias(#initfn)));

         这段代码的作用是给我们的加载函数定义一个别名,别名就是我们前面提到的init_module,这样insmod就能够执行我们的加载函数了。

         module_exit的作用和module_init一样,同样也是验证函数格式和定义别名。

二、静态编译

在静态编译的时候module_init的定义如下:

#define module_init(x)     __initcall(x);

 

#define __initcall(fn)device_initcall(fn)

 

#definedevice_initcall(fn)                 __define_initcall("6",fn,6)

 

#define__define_initcall(level,fn,id) \

         static initcall_t __initcall_##fn##id __used \

         __attribute__((__section__(".initcall" level".init"))) = fn

         通过这些段代码,我们能够看出最终的结果是将我们的使用module_init修饰的函数指针链接到一个叫.initcall的段里,也就是说最终所以的使用module_init修饰的函数指针都被链接在这个段里,最终内核在启动的时候顺序调用所有链接在这个段里的函数,实现设备的初始化。

 

 类似资料: