知道 Linux 如何确定应该在内核模块中打印哪个字符串吗?

Any idea how Linux determines which string should be printed in a kernel module?

给出最基本的内核模块

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h>

static int __init my_mod_init(void) {
    printk("Hello World!");
    printk("Goodbye World!");
    return 0;
}
static void __exit my_mod_exit(void) { }

module_init(my_mod_init);
module_exit(my_mod_exit);

MODULE_LICENSE("GPL");

GCC 生成以下 armv7 程序集 (objdump)

dummy.ko:     file format elf32-littlearm

Disassembly of section .init.text:

00000000 <init_module>:
   0:   e92d4010    push    {r4, lr}
   4:   e3000000    movw    r0, #0
   8:   e3400000    movt    r0, #0
   c:   ebfffffe    bl  0 <printk>
  10:   e3000000    movw    r0, #0
  14:   e3400000    movt    r0, #0
  18:   ebfffffe    bl  0 <printk>
  1c:   e3a00000    mov r0, #0
  20:   e8bd8010    pop {r4, pc}

Disassembly of section .exit.text:

00000000 <cleanup_module>:
   0:   e12fff1e    bx  lr

rodata 部分如下所示:

Contents of section .rodata.str1.4:
 0000 48656c6c 6f20576f 726c6421 00000000  Hello World!....
 0010 476f6f64 62796520 576f726c 642100    Goodbye World!. 

我至少希望第 0x10 行和 0x14 行的 r0 类似于 mov r0, #16ldr r0, [pc, #12]。第二个printk函数如何通知打印"Goodbye World!"?

A .ko 显然类似于 .o - 可重定位目标文件,而不是 ELF 可执行文件或共享目标文件。

因此机器代码中只有占位符,实际地址仅在加载时根据重定位信息填写。

反汇编 objdump -dr 以显示带有符号名称的重定位。 (或objdump -drWC,与拆卸.o时相同。