c - 知道 Linux 如何确定应该在内核模块中打印哪个字符串吗?
问题描述
给定最基本的内核模块
#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!.
我至少预计r0
在 0x10 和 0x14 行会像mov r0, #16
or ldr r0, [pc, #12]
。如何printk
通知第二个函数打印“再见世界!” ?
解决方案
A.ko
显然像.o
- 一个可重定位的对象文件,而不是 ELF 可执行文件或共享对象。
所以机器代码中只有占位符,实际地址仅在加载时根据重定位信息填写。
Disassemble withobjdump -dr
以显示带有符号名称的重定位。(或objdump -drWC
),与您拆卸.o
.
推荐阅读
- c - 为什么函数会在作为指针传递给它的参数上使用“地址”运算符?
- javascript - Ajax 路径适用于一个数组,但不适用于另一个
- excel - 编写一个 excel 公式或 VBA 宏,返回一周/一个月/过去 60 天/过去 90 天进行的某种类型的调用次数
- ios - 如何正确使用 performSegue 功能视图控制器出现几秒钟?
- c# - 具有多重绑定的 WPF 滑块,其中单个属性被延迟
- prestashop - 将购物车复制到另一个购物车以更改 id_cart
- c# - 在服务器上安装后请求重定向到 /Account/Login?ReturnUrl=%2f
- powershell - ReportingServicesTools 模块未进行数字签名
- c - 如何在浮点数中提取小数点后的数字并存储在char数组中
- php - php替换标签或字符之间的一些字符串