8

我一直在尝试移植几个Linux驱动程序,并意识到有内核版本2.4和2.6的Linux之间的实质性区别。Linux内核模块中module_init和init_module有什么区别?

在2.4版内核,模块编程为如下 -

#define MODULE 
#include <linux/module.h> 
#include <linux/kernel.h> 

int init_module(void)  
{ 
printk(KERN_INFO "Hi \n"); 
return 0; 
} 

void cleanup_module(void) 
{ 
printk(KERN_INFO "Bye \n"); 
} 

但是,随着2.6版本内核的,下面有模块做 -

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 

static int hi_init(void) 
{ 
    printk(KERN_ALERT "Hi \n"); 
    return 0; 
} 

static void hi_exit(void) 
{ 
    printk(KERN_ALERT "Bye \n"); 
} 

module_init(hi_init); 
module_exit(hi_exit); 

内核2.6中这种变化的优点是什么?为什么Linux内核2.6中需要这种变化?

+0

2.4声明意味着你永远无法将模块构建到系统中(因为声明不是静态的)。 – stsquad 2012-06-13 07:55:20

+1

下面是一个非常好的解释module_init: http://stackoverflow.com/questions/18605653/linux-module-init-vs-core-initcall-vs-early-initcall – user2311046 2014-01-06 14:45:26

回答

6

如果你看看新函数的定义:

/* Each module must use one module_init(). */ 
#define module_init(initfn)     \ 
static inline initcall_t __inittest(void)  \ 
{ return initfn; }     \ 
int init_module(void) __attribute__((alias(#initfn))); 

/* This is only required if you want to be unloadable. */ 
#define module_exit(exitfn)     \ 
static inline exitcall_t __exittest(void)  \ 
{ return exitfn; }     \ 
void cleanup_module(void) __attribute__((alias(#exitfn))); 

你会看到它确保正确的样板包括在内,以便这些特殊功能可以通过编译器正确对待。这就是Linux的内部API所做的事情,如果有更好的解决问题的方法,它就会发展。

+0

是的,但这是如何更好办法?指令只是为了使用户提供的函数名称作为init_module()函数的别名 – Chethan 2012-06-11 09:52:18

+0

API的可读性,一致性,强制约定。一般而言,您希望使API API一致性的锅炉板难以搞砸,并让开发人员专注于解决他们需要解决的实际问题。 – stsquad 2012-06-13 07:54:08

1

一个优点是可读性。 cdrom_init()立即告诉你它是cdrom驱动程序的init()调用。

5

什么是内核2.6

module_init的[宏module_init]优势也退出在2.4,你介意。

它增加了必要的样板来初始化模块并在模块文件被编译到内核而不是模块时运行入口函数。

相关问题