我正在开发一个要在路由器上运行的内核模块。路由器型号为 Netgear 的 DGN2200v2。它在 MIPS 上运行 Linux 2.6.30。我的问题是,当我加载我的模块时,似乎我的 module_init没有被调用。我试图通过修改我的 module_init 来缩小范围。返回 -3(表示错误?)和 insmod仍然报告成功。我可以在 lsmod 的输出中看到我的模块,但我没有看到我的 printk使用 dmesg 输出.

对于初学者,我想创建最简单的模块:

#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/init.h> 
 
static int my_init(void) 
{ 
    printk(KERN_EMERG "init_module() called\n"); 
    return -3; 
} 
 
static void my_cleanup(void) 
{ 
    printk(KERN_EMERG "cleanup_module() called\n"); 
} 
 
module_init(my_init); 
module_exit(my_cleanup); 

这是我正在使用的 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 
modinfo输出也符合我的预期(与在路由器上找到的另一个 .ko 相同的 modinfo 输出,除了我的模块具有但路由器上的另一个模块没有的 srcversion):
filename:       /home/user/module/module.ko 
srcversion:     B0BADBA395A121CF49B74DC 
depends:         
vermagic:       2.6.30 mod_unload MIPS32_R1 32BIT  

完全有可能是我在 Buildroot 配置中搞砸了某些东西,或者某些东西与路由器的 CPU 类型不完全匹配,但是我的初始化代码是如此之少,以至于我不知道可能出了什么问题。

请您参考如下方法:

事实证明,问题与我的开发环境和路由器之间的不同内核配置有关。具体来说,我的内核使用了 CONFIG_UNUSED_SYMBOLS而路由器不是。

即使在一个微不足道的模块中也会导致问题的原因是,当内核加载一个模块时,它不仅仅查找module_init。模块符号表中的符号。相反,它读取 module来自模块的结构(来自 .gnu.linkonce.this_module 部分),然后调用 init通过该结构的模块。
init 的偏移量module 中的函数指针struct 依赖于内核配置,这就解释了为什么内核找不到 init配置不同时的功能。

感谢 Sam Protsenko 投入大量时间帮助我破解这个问题!


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!