第一个简单的内核编程实验:hello.c
内核编程入门,就以最为简单的hello.c为例。
环境:Redhat 9.0,内核版本2.4.20-8。
虽然现在2.6.x的内核很早就就发布了,但是毕竟很多公司还在使用2.4.x的内核。作为新手,从2.4.x的内核入手是可行的。原因有如下几条:
(1)2.4.x比较成熟。可能你遇到的绝大多数问题,网上都有解决方案。在这个过程中,你可以节省大量的时间,同时还可以对比网上的解决方案,加深认识,总结解决问题的方法,调整自己的学习方法和思路。
(2)事物的发展总不可能是一蹴而就的。了解发展的历程,对深入理解问题有很大的好处。所以在2.4.x的内核的基础上学习2.6.x的内核,就能够体会到2.6.x的内核在哪些方面要出色,或者为什么要采取这种改进技术。相信理论清晰了,即时2.6.x的内核也会容易上手。
下面总结了第一个内核程序hello.c的学习过程。
(一)第一阶段:尽量简单
/*
* hello.c
*/
#define MODULE
#include <linux/module.h>
int init_module(void)
{
printk( "Hello World!\n ");
return 0;
}
void cleanup_module(void)
{
printk( "Goodbye!\n ");
}
执行,出现错误一:
[root@lqm drivers]# gcc -c hello.c
[root@lqm drivers]# insmod hello.o
hello.o: kernel-module version mismatch
hello.o was compiled for kernel version 2.4.20
while this kernel is version 2.4.20-8.
这是因为内核源代码版本和编译器版本不一致造成的。
(1)编译器版本/usr/include/linux/version.h
#define UTS_RELEASE "2.4.20 "
#define LINUX_VERSION_CODE 132116
#define KERNEL_VERSION(a,b,c) (((a) < < 16) + ((b) < < 8) + (c))
(2)内核源代码版本/usr/src/linux-2.4.20-8/include/linux/version.h
/usr/src/linux-2.4.20-8/include/linux
[root@lqm linux]# cat version.h
#include <linux/rhconfig.h>
#if defined(__module__smp)
#define UTS_RELEASE "2.4.20-8smp "
#elif defined(__module__BOOT)
#define UTS_RELEASE "2.4.20-8BOOT "
#elif defined(__module__bigmem)
#define UTS_RELEASE "2.4.20-8bigmem "
#else
#define UTS_RELEASE "2.4.20-8 "
#endif
#define LINUX_VERSION_CODE 132116
#define KERNEL_VERSION(a,b,c) (((a) < < 16) + ((b) < < 8) + (c))
可以采取修改编译器版本号与内核源代码版本号一致的办法来解决这个问题,即修改/usr/include/linux/version.h中 #define UTS_RELEASE "2.4.20 "
为 #define UTS_RELEASE "2.4.20-8 "
执行,出现错误二:
[root@lqm drivers]# gcc -c hello.c
[root@lqm drivers]# insmod hello.o
Warning: loading hello.o will taint the kernel: no license
See http://www.tux.org/lkml/#export-tainted for information about tainted modules
Module hello loaded, with warnings
[root@lqm drivers]# tail