1 year ago

#271220

test-img

asdo

Kernel panic on simple loadable kernel module

I`m trying to create an elementary loadable kernel module to embedded OpenWRT system on the Ralink 3050 SOC (processor MIPS 24KEs). The target system built with MODULES=y and CONFIG_MODULE_UNLOAD=y options. I work under Ubuntu 20 X86 machine.

#include <linux/init.h> 
#include <linux/module.h> 

MODULE_LICENSE("GPL");
MODULE_AUTHOR("test"); 

int init_module(void) { 
    printk(KERN_INFO "Hello, world!\n"); 
    return 0; 
} 
void cleanup_module(void) { 
    printk(KERN_INFO "Goodbye, world!\n"); 
} 

The first time, I`m was trying to compile module by the built-in OpenWRT buildroot cross-compiler:

make ARCH=mips CROSS_COMPILE=mipsel-openwrt-linux-musl-

The kernel headers included the OpenWRT buildroot were used.

Result, fail: after insmod load module was marked as [permanent]. I.e. the cleanup_module procedure was not seen by the kernel. I assumed that problem in a file structure. I`m was checking the vermagic signature (to an other system module that is workable): It matched.

$modinfo module.ko -> vermagic: 5.10.100 mod_unload MIPS32_R2 32BIT

Just in case, I had rebuilt the target system, may be it`s stochastic errors? But the result is the same…

Then I decided to build a custom cross-compiler and original kernel headers. I had downloaded and installed the binutils 2.38 and gcc 11.2.0 (same as at the OpenWRT buildroot) and was downloaded and prepared the kernel header with same .config file (kernel 5.10.100 – same as on the target system).

Now the next result:
After compilation make ARCH=mips CROSS_COMPILE=mipsel-unknown-linux-gnu- by custom cross compiler the module loads, but any next callers lsmod, rmmod or insmod finished by kernel panic. Looks like, the module corrupts kernel memory. If the module compiled without the cleanup_module procedure, it loads correct but have status [permanent] and can`t be unloaded.

I tried to change the function declaration: used __exit and static specificator – no result.

root@(none):/# lsmod
[  456.197482] CPU 0 Unable to handle kernel paging request at virtual address 034881e0, epc == 80068f78, ra == 80068f64
[  456.218804] Oops[#1]:
[  456.223350] CPU: 0 PID: 1017 Comm: lsmod Not tainted 5.10.100 #0
[  456.235314] $ 0   : 00000000 00000001 00000000 00000001
[  456.245763] $ 4   : 8160200e 80320b64 00000000 00000001
[  456.256206] $ 8   : 00000020 00000002 00000001 00000000
[  456.266645] $12   : 7faff400 77eca2b0 77ec0020 7faff43f
[  456.277090] $16   : 81a440a4 816110d8 034881d0 80320b64
[  456.287534] $20   : 80380000 81a441d0 816110f0 81611100
[  456.297977] $24   : 00000000 80101500
[  456.308420] $28   : 81a46000 81a47d60 00000002 80068f64
[  456.318864] Hi    : 00000000
[  456.324594] Lo    : 0a3d70a4
[  456.330333] epc   : 80068f78 0x80068f78
[  456.337973] ra    : 80068f64 0x80068f64
[  456.345609] Status: 1100e403 KERNEL EXL IE
[  456.353965] Cause : 00800008 (ExcCode 02)
[  456.361946] BadVA : 034881e0
[  456.367679] PrId  : 0001964c (MIPS 24KEc)
[  456.375658] Modules linked in: module rt2800soc rt2800mmio rt2800lib rt2x00soc rt2x00mmio rt2x00lib mac80211 cfg80211 crc_ccitt compat sha256_generic libsha256 seqiv jitterentropy_rng drbg hmac cmac leds_gpio crc32c_generic
[  456.415692] Process lsmod (pid: 1017, threadinfo=1acffaea, task=80d5ed61, tls=77ecbdd4)
[  456.431637] Stack : 81621700 00400cc0 00000000 00000001 ffffffff 800b6700 81847c80 00002000
[  456.448345]         00000000 81a47e18 00000000 a050f4de 81847c80 816110d8 81a440a4 00000000
[  456.465053]         81a47f00 81a47e38 81a47e20 801011d8 00000001 00000001 00000000 00000601
[  456.481760]         816e2904 800c7f98 77ec1000 81a47e8c 80584860 00000000 00000000 00000000
[  456.498467]         81847c80 81a47f00 00000400 00000000 00000000 00000003 00000002 80101630
[  456.515174]         ...
[  456.520050] Call Trace:
[  456.520071] [<800b6700>] 0x800b6700
[  456.531895] [<801011d8>] 0x801011d8
[  456.538848] [<800c7f98>] 0x800c7f98
[  456.545803] [<80101630>] 0x80101630
[  456.552751] [<800c1bdc>] 0x800c1bdc
[  456.559699] [<80018628>] 0x80018628
[  456.566665] [<800df8f0>] 0x800df8f0
[  456.573627] [<800faae8>] 0x800faae8
[  456.580579] [<800de2b0>] 0x800de2b0
[  456.587531] [<800dfbf0>] 0x800dfbf0
[  456.594479] [<800c7e2c>] 0x800c7e2c
[  456.601433] [<8000d36c>] 0x8000d36c

[  456.611364] Сode: 00001025  10000007  26730b64 <8e460010> 24c6000c  0c040199  02202025  8e520000  24020001

UPD

Did you include calls to the module_init() and module_exit() macros to register the functions as init/exit? Seems like you didn't from your example. Also, you should add __init and __exit annotations. See this simple example of mine. – Marco Bonelli

Yes, I tried to use the macro module_init() and module_exit(). It has no result. Anyway, this macro just translates the init and clean function name to the canonical function name: init_module and cleanup_module, like the main function in a user space program. Prefix __init and __exit also has no effect.

Smells like you use a compiler which configuration is not suitable for the kernel. You could try to debug "Unable to handle kernel paging request" error. – Tsyvarev

What is a "compiler configuration" that specifies the user or kernel object file type?

If we look (using readelf -a utility) at the difference between my module and any built-in module, we will see that the entry points of the init_module method in the .rel.gnu.linkonce.this_module section are identical, but the entry points of the cleanup_module are different.

Relocation section '.rel.gnu.linkonce.this_module' at offset 0x594 contains 2 entries:

    Offset     Info    Type            Sym.Value  Sym. Name
    000000d0  00001d02 R_MIPS_32         00000000   init_module
    00000130  00001c02 R_MIPS_32         00000000   cleanup_module
    
    
    Relocation section '.rel.gnu.linkonce.this_module' at offset 0x1c8c contains 2 entries:
     Offset     Info    Type            Sym.Value  Sym. Name
    000000d0  00000a02 R_MIPS_32         00000000   _1
    00000140  00000902 R_MIPS_32         00000000   _0

linux-kernel

cross-compiling

kernel-module

openwrt

mips32

0 Answers

Your Answer

Accepted video resources