如Margaret和Roi在上述注释中所述,memblock_alloc_range_nid()
用__init
注释.只有在启动后的内核初始化期间,才需要使用__init
、__head
和类似宏注释的函数.内核完成初始化后,包含所有这些函数的特殊内存部分将从内存中取消映射,因为它们不再需要.
如果要调试任何此类函数,必须很早中断,例如在start_kernel()
时,然后可以判断该函数或设置断点并执行continue
次以命中它.
重要提示:在QEMU命令行选项中添加-S
(大写),使其在启动内核之前停止并等待调试器,并在使用-append "nokaslr"
禁用KASLR的情况下启动内核(如果已经指定-append
,则添加nokaslr
).
以下GDB脚本应该是您所需要的:
$ cat script.gdb
directory /path/to/kernel-source-dir
file /path/to/kernel-source-dir/vmlinux
target remote localhost:1234
break start_kernel
continue
启动gdb -x script.gdb
(启动QEMU后),当到达start_kernel
断点时,可以为memblock_alloc_range_nid
再添加一个断点,然后为continue
:
0x000000000000fff0 in exception_stacks ()
Breakpoint 1 at 0xffffffff82fbab4c
Breakpoint 1, 0xffffffff82fbab4c in start_kernel ()
(gdb) b memblock_alloc_range_nid
Breakpoint 2 at 0xffffffff82fe2879
(gdb) c
Continuing.
Breakpoint 2, 0xffffffff82fe2879 in memblock_alloc_range_nid ()
(gdb) disassemble
Dump of assembler code for function memblock_alloc_range_nid:
=> 0xffffffff82fe2879 <+0>: push r15
0xffffffff82fe287b <+2>: mov r15,rcx
0xffffffff82fe287e <+5>: push r14
0xffffffff82fe2880 <+7>: mov r14,rdx
0xffffffff82fe2883 <+10>: push r13
0xffffffff82fe2885 <+12>: mov r13d,r9
...