Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151582
  • 博文数量: 25
  • 博客积分: 1632
  • 博客等级: 上尉
  • 技术积分: 324
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-02 21:19
文章分类

全部博文(25)

文章存档

2011年(13)

2010年(12)

我的朋友

分类: LINUX

2010-04-03 00:12:25

 
要实现hello world也需要做下基本的工作,首先就是内核树的建立.在内核树建立的基础上来进行.
首先建立hello.c和Makefile文件,他们最好在一个文件夹里面.
//hello.c
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
下面是Makefile文件:
obj-m := hello.o
KERNELDIR := /lib/modules/2.6.28/build
PWD := $(shell pwd)
modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
Makefile文件需要将
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 和$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install退到最左端然后用"TAB"来空格.
# gedit hello.c
# make
make -C /lib/modules/2.6.28/build  M=/workdir/LDD3/driver/hello  modules
make[1]: Entering directory `/workdir/LDD3/kernel/linux-2.6.28'
  CC [M]  /workdir/LDD3/driver/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /workdir/LDD3/driver/hello/hello.mod.o
  LD [M]  /workdir/LDD3/driver/hello/hello.ko
make[1]: Leaving directory `/workdir/LDD3/kernel/linux-2.6.28'
# ls
Makefile  Makefile~  Module.symvers  hello.c  hello.c~  hello.ko  hello.mod.c  hello.mod.o  hello.o  modules.order
# insmod hello.ko
insmod: error inserting 'hello.ko': -1 Invalid module format
出现上面的情况口,查看日志文件
# cat /var/log/messages
Apr  2 21:22:18 emboard-desktop syslogd 1.5.0#1ubuntu1: restart.
Apr  2 21:43:56 emboard-desktop -- MARK --
Apr  2 22:03:57 emboard-desktop -- MARK --
Apr  2 22:23:57 emboard-desktop -- MARK --
Apr  2 22:38:20 emboard-desktop kernel: [ 6910.938421] Clocksource tsc unstable (delta = 4693232077 ns)
Apr  2 22:38:22 emboard-desktop kernel: [ 6911.090586] Time: acpi_pm clocksource has been installed.
Apr  2 23:04:04 emboard-desktop -- MARK --
Apr  2 23:24:06 emboard-desktop -- MARK --
Apr  2 23:44:06 emboard-desktop -- MARK --
Apr  2 23:58:22 emboard-desktop kernel: [11713.696567] hello: disagrees about version of symbol struct_module
Apr  2 23:58:50 emboard-desktop kernel: [11741.863228] hello: disagrees about version of symbol struct_module
可能是内核版本的问题.
解决办法一:
修改Makefile
obj-m := hello.o
#KERNELDIR := /lib/modules/2.6.28/build
KERNELDIR := /lib/modules/2.6.24-19-generic/build
PWD := $(shell pwd)
modules:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
将"build"路径换成系统的,当然这个办法不能解决我们所要达到的目的,但是可以试下!
# make
make -C /lib/modules/2.6.24-19-generic/build M=/workdir/LDD3/driver/hello  modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-19-generic'
  CC [M]  /workdir/LDD3/driver/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /workdir/LDD3/driver/hello/hello.mod.o
  LD [M]  /workdir/LDD3/driver/hello/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-19-generic'
# insmod hello.ko
#
# insmod hello.ko
insmod: error inserting 'hello.ko': -1 File exists
可见已经成功了,但是没出现"hello word"
# rmmod hello.ko
#
# rmmod hello.ko
ERROR: Module hello does not exist in /proc/modules
# cat /var/log/messages
Apr  2 21:22:18 emboard-desktop syslogd 1.5.0#1ubuntu1: restart.
Apr  2 21:43:56 emboard-desktop -- MARK --
Apr  2 22:03:57 emboard-desktop -- MARK --
Apr  2 22:23:57 emboard-desktop -- MARK --
Apr  2 22:38:20 emboard-desktop kernel: [ 6910.938421] Clocksource tsc unstable (delta = 4693232077 ns)
Apr  2 22:38:22 emboard-desktop kernel: [ 6911.090586] Time: acpi_pm clocksource has been installed.
Apr  2 23:04:04 emboard-desktop -- MARK --
Apr  2 23:24:06 emboard-desktop -- MARK --
Apr  2 23:44:06 emboard-desktop -- MARK --
Apr  2 23:58:22 emboard-desktop kernel: [11713.696567] hello: disagrees about version of symbol struct_module
Apr  2 23:58:50 emboard-desktop kernel: [11741.863228] hello: disagrees about version of symbol struct_module
Apr  3 00:24:07 emboard-desktop -- MARK --
从上面也没看到!可见这个办法是可以实现模块动态加载,但是达不到我们想要的效果.
但是可以在这里看到.
# cat /var/log/syslog
Apr  3 14:55:25 emboard-desktop kernel: [ 3982.870441] Hello, world
Apr  3 14:55:31 emboard-desktop kernel: [ 3989.359755] Goodbye, cruel world
方法二:可以试着去掉内核的模块版本的支持.
进入内核目录:
# make menuconfig 
 
 
进入上图选中的那个选项,进入:
去掉上图选中的那个选项.
然后编译内核:
#  make
#  make bzImage
#  make modules
#  make modules_install 
编译成功后,然后进入hello文件夹:
# ls
Makefile  Module.symvers  hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  modules.order
可以看到上次编译过的文件,现在你可以手动删除:
# rm Module.symvers
# rm hello.ko      
# rm hello.mod.c
# rm hello.mod.o
# rm hello.o    
# rm modules.order
# ls
Makefile  hello.c
然后查看Makefile文件内核树的路径是否是上面编译的路径:
# gedit Makefile
obj-m := hello.o
KERNELDIR := /lib/modules/2.6.28/build
PWD := $(shell pwd)
modules:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
确认后,然后执行make:
# make
make -C /lib/modules/2.6.28/build  M=/workdir/LDD3/driver/hello  modules
make[1]: Entering directory `/workdir/LDD3/kernel/linux-2.6.28'
  CC [M]  /workdir/LDD3/driver/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /workdir/LDD3/driver/hello/hello.mod.o
  LD [M]  /workdir/LDD3/driver/hello/hello.ko
make[1]: Leaving directory `/workdir/LDD3/kernel/linux-2.6.28'
# ls
Makefile  Module.symvers  hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  modules.order
# insmod hello.ko
# rmmod hello.ko
但是执行后仍然看不到打印信息,但是可以通过下面的方式来判断,hello.ko已经加载了
# insmod hello.ko
# insmod hello.ko
insmod: error inserting 'hello.ko': -1 File exists
# lsmod     
Module                  Size  Used by
hello                   2304  0
ipv6                  267780  8
af_packet              23812  2
可见hello已经加载了.
不能打印出信息,有待调试.
# cat /var/log/messages
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572359] WARNING: at /build/buildd/linux-2.6.24/mm/vmalloc.c:331 __vunmap()
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572368] Pid: 8888, comm: insmod Tainted: GF       2.6.24-19-generic #1
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572391]  [sys_init_module+0x151/0x19c0] sys_init_module+0x151/0x19c0
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572440]  [_atomic_dec_and_lock+0x47/0x70] _atomic_dec_and_lock+0x47/0x70
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572454]  [] printk+0x0/0x20
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572528]  [sysenter_past_esp+0x6b/0xa9] sysenter_past_esp+0x6b/0xa9
Apr  3 14:32:41 emboard-desktop kernel: [ 2620.572553]  =======================
这个是最后几行,可能问题就出在这里,现在不能确定是什么原因!
最后在google上找到原因:
#dmesg   or   #cat /var/log/syslog
[358018.485127] Trying to vfree() bad address (f8c150b0)
[358018.485153] WARNING: at /build/buildd/linux-2.6.24/mm/vmalloc.c:331 __vunmap()
[358018.485157] Pid: 14125, comm: insmod Tainted: GF        2.6.24-19-386 #1
[358018.485172]  [] sys_init_module +0x155/0x15a0
[358018.485288]  [] sysenter_past_esp+0x6b/0xa9
[358018.485330]  =======================
1. insmod Tainted: GF 没碰见过,查了一下有篇很好的文章说kernel tainted的。
其中提到了G和F的意思,和/proc/sys/kernel/tainted
G : The opposite of ' P ': the kernel has been tainted (for a reason indicated by a different flag), but all modules loaded into it were licensed under the G PL or a license compatible with the GPL.
F : A module was loaded using the F orce option "-f " of insmod or modprobe , which caused a sanity check of the versioning information from the module (if present) to be skipped.
/proc/sys/kernel/tainted flag:
If the kernel supports the /proc/sys/kernel/tainted flag then insmod will OR the tainted flag with '1' when loading a module without a GPL license. A warning is issued if the kernel supports tainting and a module is loaded without a license. A warning is always issued for modules which have a MODULE_LICENSE() that is not GPL compatible, even on older kernels that do not support tainting. This minimizes warnings when a new modutils is used on older kernels.
insmod -f (force) mode will OR the tainted flag with '2' on kernels that support tainting. It always issues a warning.
2. Trying to vfree() bad address错误:
该错误出于mm/vmalloc.c的vfree()函数。见
可能是在模块初始化失败后,释放分配的内存,发现是错误的地址造成。
3. sys_init_module
4. NUMA:
Non-Uniform Memory Access or Non-Uniform Memory Architecture (NUMA)
#cat /proc/vmallocinfo
 

Final Result:
module编译用的kernel与host的kernel相差太大,所以失败了,以后再追原因。在内核一致的host上,没有问题。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wdove/archive/2010/03/01/5335596.aspx
所以现在还是换成2.6.24的内核吧!浪费怎么多时间,吸取一个教训吧!不过,我觉得走的弯路多了,以后碰到问题也就少了,至少证明有的方法是行不通的了.
好了换成2.6.24的内核试试吧!方法还是一样!只是将内核编译后修改下Makefile的路径就可以了!
所以又重新下载了linux-2.6.24这个版本的内核,因为我的操作系统的内核也是2.6.24.xx.xx的!
按照建立内核树的方法,建立了内核树!
最后修改了Makefile文件如下:
# Makefile2.6
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationship of files and target modules are listed here.
 obj-m +=hello.o
else
 PWD :=$(shell pwd)
 KEVER ?=$(shell uname -r)
 KDIR :=/workdir/emboard-workdir/LDD3/kernel/linux-2.6.24
default:
 make -C $(KDIR) M=$(PWD) modules
clean:
 rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *symvers *~
endif
也同样注意,需要用TAB来对齐的命令.
然后
# ls                  
Makefile  hello.c
# make
make -C /workdir/emboard-workdir/LDD3/kernel/linux-2.6.24 M=/workdir/emboard-workdir/LDD3/driver/hello modules
make[1]: Entering directory `/workdir/emboard-workdir/LDD3/kernel/linux-2.6.24'
  CC [M]  /workdir/emboard-workdir/LDD3/driver/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /workdir/emboard-workdir/LDD3/driver/hello/hello.mod.o
  LD [M]  /workdir/emboard-workdir/LDD3/driver/hello/hello.ko
make[1]: Leaving directory `/workdir/emboard-workdir/LDD3/kernel/linux-2.6.24'
# ls
Makefile  Module.symvers  hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o
# insmod hello.ko
#
但是没有出先信息啊!
# cat /var/log/syslog
最后看到hello,world!说明成功了.
Apr  4 21:39:14 emboard kernel: [ 1742.786969] Hello, world
# rmmod hello.ko
同样最后也出现这样的提示信息.
Apr  4 21:39:12 emboard kernel: [ 1740.039785] Goodbye, cruel world
这样说明成功模块动态加载成功!
***************************************2*******************************************
阅读(2954) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~