MIPS32路由器:内核模块未调用module_init [英] MIPS32 router: module_init not called for kernel module

查看:180
本文介绍了MIPS32路由器:内核模块未调用module_init的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm developing a kernel module that I want to run on my router. The router model is DGN2200v2 by Netgear. It's running Linux 2.6.30 on MIPS. My problem is that when I load my module it seems that my module_init isn't getting called. I tried to narrow it down by modifying my module_init to return -3 (which indicates an error?) and insmod still reports success. I can see my module in the output of lsmod, but I don't see my printk output using dmesg.

对于初学者来说,我想创建尽可能简单的模块:

For starters, I wanted to create the simplest possible module:

#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:

This is the Makefile I'm using:

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.

As you can see, I'm using Buildroot which I (hopefully) configured correctly. I can paste my .config if needed.

我在模块上运行了objdump,但没有发现问题.特别是,module_init符号似乎指向与my_init函数相同的位置,并且似乎具有我期望它的代码:

I ran objdump on my module and didn't find a problem. In particular, the module_init symbol seems to point to the same place as my my_init function, and it seems to have the code I expect it to:

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的输出也符合我的期望(与modinfo的输出相同,与在路由器上找到的另一个.ko相同,除了我的模块具有的srcversion,但路由器上的另一个模块没有) :

modinfo output also matches what I expect (same modinfo output as for another .ko that's found on the router, except for the srcversion which my module has but the other module on the router doesn't):

filename:       /home/user/module/module.ko
srcversion:     B0BADBA395A121CF49B74DC
depends:        
vermagic:       2.6.30 mod_unload MIPS32_R1 32BIT 

我完全有可能在Buildroot配置中弄乱了某些东西,或者某些东西与路由器的CPU类型不完全匹配,但是我的初始化代码太少了,以至于我对可能出了什么问题的想法一无所知

It's entirely possible that I messed something up in my Buildroot configuration, or something doesn't quite match the CPU type of the router, but my init code is so minimal that I'm out of ideas as to what could be wrong.

推荐答案

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

It turns out that the problem was related to a different kernel configuration between my development environment and the router. Specifically, my kernel was using CONFIG_UNUSED_SYMBOLS whereas the router's was not.

即使在琐碎的模块中也引起问题的原因是,当内核加载模块时,它不仅在模块的符号表中查找module_init符号.而是从模块(从.gnu.linkonce.this_module部分)读取module结构,然后通过该结构调用init模块.

The reason this caused a problem even in a trivial module is that when the kernel loads a module it doesn't only look up the module_init symbol in the module's symbol table. Rather, it reads the module struct from the module (from the .gnu.linkonce.this_module section), and then calls the init module through that struct.

module结构中的init函数指针的偏移量取决于内核配置,这解释了为什么在配置不同的情况下内核找不到init函数的原因.

The offset of the init function pointer inside the module struct depends on the kernel configuration, which explains why the kernel can't find the init function if the configuration is different.

感谢萨姆·普罗岑科(Sam Protsenko)花了很多时间来帮助我解决这个问题!

Thanks to Sam Protsenko for investing a lot of time in helping me crack this!

这篇关于MIPS32路由器:内核模块未调用module_init的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆