1 year ago
#271220
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