嵌入式系统中linux内核insmod时出现Unable to handle kernel paging request at virtual address xxxx可能的原因
最近的研究当中,需要给一个已知的linux系统编译内核模块,不过没有对方的源码,只知道一个内核版本,所以就想着直接从kernel.org去下载对应版本的源码,先编译内核,再利用编译好的内核信息去编译对应的内核模块。但编译完内核模块发现,insmod并没有出现不兼容的问题,却发生了segment fault的crash,大概长这样:

经过研究发现,其实module已经load成功了,但是在做一些处理工作的时候出现了问题。经过测试发现,其实是kernel配置的问题,如果kernel配置的时候
CONFIG_JUMP_LABEL选项是打开的,编译模块所使用的kernel也需要打开,否则就会出现图中的crash。
这个选项在的说明是:
CONFIG_JUMP_LABEL: │ │ │ │ This option enables a transparent branch optimization that │ │ makes certain almost-always-true or almost-always-false branch │ │ conditions even cheaper to execute within the kernel. │ │ │ │ Certain performance-sensitive kernel code, such as trace points, │ │ scheduler functionality, networking code and KVM have such │ │ branches and include support for this optimization technique. │ │ │ │ If it is detected that the compiler has support for "asm goto", │ │ the kernel will compile such branches with just a nop │ │ instruction. When the condition flag is toggled to true, the │ │ nop will be converted to a jump instruction to execute the │ │ conditional block of instructions. │ │ │ │ This technique lowers overhead and stress on the branch prediction │ │ of the processor and generally makes the kernel faster. The update │ │ of the condition is slower, but those are always very rare. │ │ │ │ ( On 32-bit x86, the necessary options added to the compiler │ │ flags may increase the size of the kernel slightly. ) │ │ │ │ Symbol: JUMP_LABEL [=y] │ │ Type : boolean │ │ Prompt: Optimize very unlikely/likely branches │ │ Location: │ │ -> General setup │ │ Defined at arch/Kconfig:49 │ │ Depends on: HAVE_ARCH_JUMP_LABEL [=y]
大概就是内核针对分支跳转的优化支持,如果内核不支持这个特性而模块使用这个特性的话,或者是模块支持这个特性而内核不支持的话,就会发生crash了。所以,修改内核配置重新编译,问题解决。