2016-10-20 4 views
3

라우터에서 실행할 커널 모듈을 개발 중입니다. 라우터 모델은 Netgear의 DGN2200v2입니다. MIPS에서 Linux 2.6.30을 실행 중입니다. 내 문제는 내 모듈을로드 할 때 내 module_init이 호출되지 않는 것 같습니다. module_init을 -3 (오류를 나타내는?)으로 수정하여 범위를 좁히려 고 시도했으며 insmod은 여전히 ​​성공을보고합니다. lsmod의 출력에서 ​​모듈을 볼 수 있지만 printk 출력이 dmesg을 사용하고 있지 않습니다. 이것은 내가 메이크 사용하고있다MIPS32 라우터 : 커널 모듈에 module_init가 호출되지 않았습니다.

#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); 

:

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를 실행했지만 문제를 찾지 못했습니다. 또한 나는 경우와 (같은 modinfo 출력 예상과 일치

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 출력 : 특히, module_init()라는 기호는 내 my_init 기능과 같은 장소를 가리 키도록 것, 그리고 내가 그것을 기대하는 코드를 갖고있는 것 같아요 그 .ko 다른는 srcversion을 제외하고, 라우터 발견의 내 모듈은 가지고 있지만 라우터의 다른 모듈)하지 않는 :

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

그것은 내 Buildroot 구성에서 뭔가를 엉망 것이 전적으로 가능, 또는 뭔가가 라우터의 CPU 유형과 정확히 일치하지 않지만 내 init 코드는 너무 적습니다. 내가 틀릴 수있는 것에 관해서는 아이디어가 없다.

+0

우선, 두 모듈 함수 모두 param으로 'void'를 가져와야합니다. 순수한 C에서'function()'과'function (void)'는 두 가지 다른 서명입니다. 두 번째 오류 : 각 module_init() 및 module_exit() 뒤에'; '을 추가해야합니다. –

+0

@SamProtsenko 제안에 감사드립니다, 샘.불행히도이 두 가지 문제를 수정 한 후에도 (필자의 질문에 따라 소스 코드를 수정했습니다) 동일한 결과를 얻었습니다. 무엇이 잘못되었거나 문제를 해결할 수 있는지에 대한 다른 생각은 없습니까? – YSK

+1

당신은 '나는 lsmod의 출력에서 ​​내 모듈을 볼 수있다.'라고 말했고, 나는 이것이 모듈이 결국로드되었다는 것을 믿는다. 그래서 당신의 init 함수에서'printk()'를'BUG()'또는'BUG_ON()'으로 대체하려고 시도하십시오. 이렇게하면 (모듈을로드 한 후) 즉시 효과를 볼 수 있습니다. 또한, 모듈을 로딩하기 전후의'dmesg' 결과를 비교해보십시오. 거기에 몇 가지 힌트가있을 수 있습니다. –

답변

2

문제는 내 개발 환경과 라우터 사이의 다른 커널 구성과 관련이있는 것으로 나타났습니다. 특히, 내 커널은 CONFIG_UNUSED_SYMBOLS을 사용했지만 라우터는 그렇지 않습니다.

사소한 모듈에서도 문제가 발생한 이유는 커널이 모듈을로드 할 때 모듈의 심볼 테이블에서 module_init 심볼을 찾지 않기 때문입니다. 오히려 모듈 (.gnu.linkonce.this_module 섹션에서)에서 module 구조체를 읽고 해당 구조체를 통해 init 모듈을 호출합니다.

다음은 module 구조체 내부의 init 함수 포인터의 오프셋 (offset)는 구성이 다른 경우 커널이 init 기능을 찾을 수없는 이유를 설명 커널 구성에 따라 달라집니다.

이 문제를 해결하는데 많은 시간을 투자 한 Sam Protsenko에게 감사드립니다.