LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1370|回复: 6

模块问题

[复制链接]
发表于 2003-5-30 10:07:39 | 显示全部楼层 |阅读模式
我抄写了一测试程序,以前好像还能成功,现在竟然不行了,谁帮我看看,这是哪里有问题,程序如下:
#include linux/kernel.h

#define __NO_VERSION__
#include linux/version.h
#include linux/module.h
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include linux/modversions.h
#endif

int init_module()
{
printk("Hello,world-this is the kernel speaking\n");
return 0;
}

void cleanup_module()
{
printk("Short is the life of a kernel module\n");
}
编译结果如下:
#gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -o start.o start.c
start.c: In function `init_module':
start.c:13: warning: implicit declaration of function `printk'
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18): In function `_start':
../sysdeps/i386/elf/start.S:77: undefined reference to `main'
/tmp/ccM33akw.o(.text+0xf): In function `init_module':
: undefined reference to `printk'
/tmp/ccM33akw.o(.text+0x2c): In function `cleanup_module':
: undefined reference to `printk'
collect2: ld returned 1 exit status

implicit declaration是怎么回事啊?
模块的版本不匹配该怎么解决啊?我用的是redhat9.0,编译时说该程序是被内核版本4.2.20编译的,但现在的版本是4.2.20-8,可我就是在这个系统上编译的啊?
附带问一下:怎么把gcc编译输出的内容重定向到文件中去啊?
发表于 2003-5-31 11:26:19 | 显示全部楼层
u need -I/usr/src/linux. make sure u have ../linux dir.


gcc .... &>s  (s is u filename, no space between & and >)
 楼主| 发表于 2003-5-31 19:38:55 | 显示全部楼层

看我现在编译及运行的结果

[root@Lazybones root]# gcc -Wall -O2 -DMODULE -D__KERNEL__ -c -I/usr/src/linux-2.4.20-8 -o start.o start.c
start.c: In function `init_module':
start.c:11: warning: implicit declaration of function `printk'
[root@Lazybones root]# insmod start.o
start.o: kernel-module version mismatch
        start.o was compiled for kernel version 2.4.20
        while this kernel is version 2.4.20-8.

还是有这样的问题啊(我的是redhat9.0)?cheungming老兄,你说的是解决哪个问题的啊,就是包括那个linux文件夹的?原来文件有问题,现在改正如下:
#include <linux/kernel.h>

#include <linux/module.h>
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

int init_module()
{
        printk("<1>Hello,world-this is the kernel speaking\n");
        return 0;
}

void cleanup_module()
{
        printk("<1>Short is the life of a kernel module\n");
}

编译就出上面的错,但是能够强制安装成功,不知版本匹配错误该怎么解决?

附带问题我终于知道了,非常感谢,真是大好人啊
 楼主| 发表于 2003-5-31 19:47:46 | 显示全部楼层

还有那个printk隐含声明的问题

我在其它模块中也遇到这两种问题,如menmen,read等函数等
这些函数在9.0中是包含在哪些头文件里啊?
发表于 2003-7-20 01:39:08 | 显示全部楼层

第一个问题

第一个问题,gcc的-I参数加错了:你用的是-I/usr/src/linux-2.4.20-8,这样会导致gcc直接到/usr/src/linux-2.4.20-8下面找头文件,比如去找/usr/src/linux-2.4.20-8/linux/version.h,这样当然找不到,于是就又到系统默认目录/usr/include下面找,结果找到了/usr/include/linux/version.h。但是两个version.h是不一样的,前面那个说版本是2.4.20-8,后面那个说版本是2.4.20,于是就出现了版本不一致的问题。正确的做法应该是-I/usr/src/linux-2.4.20-8/include,不要忘了后面的/include。
发表于 2003-7-20 01:49:33 | 显示全部楼层

第二个问题

第二个问题,头文件顺序错误:
modversion.h的作用是通过宏定义,把所有需要校验和的内核符号加上校验和,比如它会#define printk printk_R12345678,这样,在include了modversion.h之后出现的所有printk(包括函数声明和函数调用)就会自动变成带校验和的版本了。而你原来是先include了kernel.h再include  modversion.h,于是kernel.h中只是声明了printk,没有声明printk_R12345678,这就是出现“隐含声明”的原因。正确的做法是先include  modversion.h再include  kernel.h和module.h。
另外,还要在一开始include  config.h,这样CONFIG_MODVERSIONS才会有意义。
发表于 2003-7-20 02:01:32 | 显示全部楼层

修改后的源码和编译命令

源码:

  1. //#define __NO_VERSION__
  2. #include <linux/version.h>
  3. #include <linux/config.h>
  4. #if CONFIG_MODVERSIONS==1
  5. #define MODVERSIONS
  6. #include <linux/modversions.h>
  7. #endif
  8. #include <linux/module.h>
  9. #include <linux/kernel.h>

  10. int init_module()
  11. {
  12.     printk("Hello,world-this is the kernel speaking\n");
  13.     return 0;
  14. }

  15. void cleanup_module()
  16. {
  17.     printk("Short is the life of a kernel module\n");
  18. }
复制代码

编译命令:
gcc -Wall -DMODULE -D__KERNEL__ -DLINUX -c -o start.o start.c -I /usr/src/linux-2.4/include/
另外,__NO_VERSION__宏好像已经不用了,反正编译出来的结果和有没有这个宏没有关系。不知哪位大侠帮忙解释一下这个问题?谢谢了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表