Linux kernel MIPS32路由器:内核模块未调用模块_init
我正在开发一个我想在我的路由器上运行的内核模块。路由器型号为Netgear的DGN2200v2。它在MIPS上运行Linux 2.6.30。我的问题是,当我加载模块时,似乎没有调用我的Linux kernel MIPS32路由器:内核模块未调用模块_init,linux-kernel,mips,busybox,mips32,buildroot,Linux Kernel,Mips,Busybox,Mips32,Buildroot,我正在开发一个我想在我的路由器上运行的内核模块。路由器型号为Netgear的DGN2200v2。它在MIPS上运行Linux 2.6.30。我的问题是,当我加载模块时,似乎没有调用我的module\u init。我试图通过修改我的module_init以返回-3(这表示错误?)来缩小它的范围,insmod仍然报告成功。我可以在lsmod的输出中看到我的模块,但使用dmesg看不到我的printk输出 首先,我想创建最简单的模块: #包括 #包括 #包括 静态int my_init(void) {
module\u init
。我试图通过修改我的module_init
以返回-3(这表示错误?)来缩小它的范围,insmod
仍然报告成功。我可以在lsmod
的输出中看到我的模块,但使用dmesg
看不到我的printk
输出
首先,我想创建最简单的模块:
#包括
#包括
#包括
静态int my_init(void)
{
printk(KERN_EMERG“init_module()调用\n”);
返回-3;
}
静态void my_清理(void)
{
printk(KERN_EMERG“cleanup_module()调用\n”);
}
模块_init(我的_init);
模块退出(我的清理);
这是我正在使用的Makefile:
TOOLCHAIN=/home/user/buildroot-2016.08/output/host/usr/bin/mips-buildroot-linux-uclibc-
ARCH=mips
CC = $(TOOLCHAIN)gcc
KBUILD_CFLAGS:=.
EXTRA_CFLAGS := -I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/include\
-I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/arch/mips/include/asm/mach-mipssim\
-I/home/user/buildroot-2016.08/output/build/linux-headers-2.6.30/arch/mips/include/asm/mach-generic\
-fno-pic -mno-abicalls -O2
obj-m := module.o
KDIR := /home/user/buildroot-2016.08/output/build/linux-headers-2.6.30
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
我正在运行make
就像这样:
make ARCH=mips CROSS_COMPILE=/home/user/buildroot-2016.08/output/host/usr/bin/mips-buildroot-linux-uclibc-
成功通过
如您所见,我使用的是Buildroot,我(希望)配置正确。如果需要,我可以粘贴我的.config
我在模块上运行了objdump,没有发现问题。特别是,module_init符号似乎指向与my_init函数相同的位置,并且它似乎具有我期望的代码:
module.ko: file format elf32-tradbigmips
module.ko
architecture: mips:isa32, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
private flags = 50001001: [abi=O32] [mips32] [not 32bitmode] [noreorder]
MIPS ABI Flags Version: 0
ISA: MIPS32
GPR size: 32
CPR1 size: 0
CPR2 size: 0
FP ABI: Soft float
ISA Extension: None
ASEs:
None
FLAGS 1: 00000001
FLAGS 2: 00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .MIPS.abiflags 00000018 00000000 00000000 00000038 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
1 .reginfo 00000018 00000000 00000000 00000050 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
2 .note.gnu.build-id 00000024 00000018 00000018 00000068 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .text 00000040 00000000 00000000 00000090 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 .rodata.str1.4 00000038 00000000 00000000 000000d0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .modinfo 0000005c 00000000 00000000 00000108 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .data 00000000 00000000 00000000 00000170 2**4
CONTENTS, ALLOC, LOAD, DATA
7 .gnu.linkonce.this_module 0000014c 00000000 00000000 00000170 2**2
CONTENTS, ALLOC, LOAD, RELOC, DATA, LINK_ONCE_DISCARD
8 .bss 00000000 00000000 00000000 000002c0 2**4
ALLOC
9 .comment 00000040 00000000 00000000 000002c0 2**0
CONTENTS, READONLY
10 .pdr 00000040 00000000 00000000 00000300 2**2
CONTENTS, RELOC, READONLY
11 .gnu.attributes 00000010 00000000 00000000 00000340 2**0
CONTENTS, READONLY
12 .mdebug.abi32 00000000 00000000 00000000 00000350 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l d .MIPS.abiflags 00000000 .MIPS.abiflags
00000000 l d .reginfo 00000000 .reginfo
00000018 l d .note.gnu.build-id 00000000 .note.gnu.build-id
00000000 l d .text 00000000 .text
00000000 l d .rodata.str1.4 00000000 .rodata.str1.4
00000000 l d .modinfo 00000000 .modinfo
00000000 l d .data 00000000 .data
00000000 l d .gnu.linkonce.this_module 00000000 .gnu.linkonce.this_module
00000000 l d .bss 00000000 .bss
00000000 l d .comment 00000000 .comment
00000000 l d .pdr 00000000 .pdr
00000000 l d .gnu.attributes 00000000 .gnu.attributes
00000000 l d .mdebug.abi32 00000000 .mdebug.abi32
00000000 l df *ABS* 00000000 module.c
00000000 l F .text 0000002c my_init
0000002c l F .text 00000014 my_cleanup
00000000 l .rodata.str1.4 00000000 $LC0
0000001c l .rodata.str1.4 00000000 $LC1
00000000 l df *ABS* 00000000 module.mod.c
00000000 l O .modinfo 00000023 __mod_srcversion23
00000024 l O .modinfo 00000009 __module_depends
00000030 l O .modinfo 0000002c __mod_vermagic5
00000000 g O .gnu.linkonce.this_module 0000014c __this_module
0000002c g F .text 00000014 cleanup_module
00000000 g F .text 0000002c init_module
00000000 *UND* 00000000 printk
Disassembly of section .MIPS.abiflags:
00000000 <.MIPS.abiflags>:
0: 00002001 movf a0,zero,$fcc0
4: 01000003 0x1000003
...
10: 00000001 movf zero,zero,$fcc0
14: 00000000 nop
Disassembly of section .reginfo:
00000000 <.reginfo>:
0: a2000014 sb zero,20(s0)
...
14: 00007fef 0x7fef
Disassembly of section .note.gnu.build-id:
00000018 <.note.gnu.build-id>:
18: 00000004 sllv zero,zero,zero
1c: 00000014 0x14
20: 00000003 sra zero,zero,0x0
24: 474e5500 c1 0x14e5500
28: c8e5d654 lwc2 $5,-10668(a3)
2c: cb477d3d lwc2 $7,32061(k0)
30: dfa48d71 ldc3 $4,-29327(sp)
34: c2ea16da ll t2,5850(s7)
38: f6bcae7d sdc1 $f28,-20867(s5)
Disassembly of section .text:
00000000 <init_module>:
0: 27bdffe8 addiu sp,sp,-24
4: 3c040000 lui a0,0x0
4: R_MIPS_HI16 $LC0
8: 3c020000 lui v0,0x0
8: R_MIPS_HI16 printk
c: afbf0014 sw ra,20(sp)
10: 24420000 addiu v0,v0,0
10: R_MIPS_LO16 printk
14: 0040f809 jalr v0
18: 24840000 addiu a0,a0,0
18: R_MIPS_LO16 $LC0
1c: 8fbf0014 lw ra,20(sp)
20: 2402fffd li v0,-3
24: 03e00008 jr ra
28: 27bd0018 addiu sp,sp,24
完全有可能是我在Buildroot配置中弄错了什么,或者与路由器的CPU类型不太匹配,但是我的init代码太少了,我不知道会出什么问题。事实证明,问题与我的开发环境和路由器之间的不同内核配置有关。具体来说,我的内核使用了
CONFIG\u UNUSED\u符号
,而路由器没有
即使在一个普通模块中,这也会导致问题,原因是当内核加载一个模块时,它不仅在模块的符号表中查找module\u init
符号。相反,它从模块(从.gnu.linkonce.this_module
部分)读取模块
结构,然后通过该结构调用init
模块
模块
结构内部的init
函数指针的偏移量取决于内核配置,这解释了如果配置不同,内核无法找到init
函数的原因
感谢Sam Protsenko花了很多时间帮助我破解这个难题 首先,两个模块函数都必须将
void
作为参数。在纯C中,function()
和function(void)
是两个不同的签名。第二个错误:您需要添加代码>在每个module_init()
和module_exit()
@SamProtsenko之后感谢您的建议,Sam。不幸的是,即使在修复了这两个问题(我相应地修改了问题中的源代码)之后,我也得到了相同的结果。关于什么可能是错误的,或者如何排除故障,还有其他想法吗?您提到:我可以在lsmod的输出中看到我的模块,我倾向于相信这一点(我的意思是,模块毕竟是加载的)。因此,尝试用类似于BUG()
或BUG\u ON()
的内容替换init函数中的printk()
。这样,您将立即看到效果(加载模块后)。另外,尝试比较加载模块前后的dmesg
输出。其中可能有一些提示。@SamProtsenko添加了一个BUG()
调用,作为my_init
方法的第一行,不会更改任何内容-在将任何内容打印到dmesg
中时,模块仍然会成功加载。实际上,insmod
调用的结果是,dmesg
的输出中没有新行。有没有关于如何进一步排除故障的想法?请尝试添加模块许可证(GPL),如前所述。
filename: /home/user/module/module.ko
srcversion: B0BADBA395A121CF49B74DC
depends:
vermagic: 2.6.30 mod_unload MIPS32_R1 32BIT