内核配置需要添加编译信息。
# 开启kernel debug info
Kernel hacking --->
[*] Kernel debugging
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debuggin
# 关闭地址随机化
kernel features ---->
[] Randomize the address of the kernel image (KASLR)
建议关闭地址随机化,否则会出现gdb中无法在断点处停下来的情况(尤其是qemu中)。可以参考:https://blog.csdn.net/gatieme/article/details/104266966
在目标板上开启gdbserver模式(虚拟soc中加上gdb调试的选项);在host上启动gdb客户端后连接虚拟soc提供的gdb服务(终端不会有输出),命令如下:
# 启动gdb,工具链中gdb的路径,并读取符号表
# vmlinux相当于elf文件,具有符号表。Image文件相当于bin文件。
aarch64-linux-gnu-gdb ./linux-5.18/vmlinux
# 连接gdb server, 7777 为端口号,
tar remote localhost:7777
# 设置断点
b start_kernel
# 运行
c
在目标板的串口则会有对应的输出信息。
内核通过python脚本定义了一组gdb命令,可方便其对内核的调试,如通过该脚本可以打印dmesg,percpu变量,通过pid打印其对应的task_struct结构体等。
内核编译时要除了4.1的配置,还需要开启CONFIG_GDB_SCRIPTS支持。
> Kernel hacking > Compile-time checks and compiler options
[*] Provide GDB scripts for kernel debugging
# 同时要保证内核地址随机化关闭,Reduce debugging information 关闭
[ ] Reduce debugging information
编译后在linux内核主目录(vmlinux同级目录)下会生成文件:vmlinux-gdb.py。在gdb中可以读取该文件。
# 启动gdb,工具链中gdb的路径,并读取符号表
# vmlinux相当于elf文件,具有符号表。Image文件相当于bin文件。
aarch64-linux-gnu-gdb ./linux-5.18/vmlinux
# 设置路径
add-auto-load-safe-path ./linux-5.10.142
# 加载vmlinux-gdb.py
source ./vmlinux-gdb.py
# 连接gdb server, 77777 为端口号,目标板的gdbserver的端口号对应
tar remote localhost:7777
# 通过lx-symbols命令加载内核和模块的符号表
lx-symbols
# 就可以使用扩展指令了
# 查看支持的扩展指令
apropos lx
# 设置断点
b start_kernel
# 运行
c
使用’apropos lx’查看常用的支持的扩展指令:
function lx_clk_core_lookup -- Find struct clk_core by name
function lx_current -- Return current task.
function lx_device_find_by_bus_name -- Find struct device by bus and name (both strings)
function lx_device_find_by_class_name -- Find struct device by class and name (both strings)
function lx_module -- Find module by name and return the module variable.
function lx_per_cpu -- Return per-cpu variable.
function lx_rb_first -- Lookup and return a node from an RBTree
function lx_rb_last -- Lookup and return a node from an RBTree.
function lx_rb_next -- Lookup and return a node from an RBTree.
function lx_rb_prev -- Lookup and return a node from an RBTree.
function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable.
function lx_thread_info -- Calculate Linux thread_info from task variable.
function lx_thread_info_by_pid -- Calculate Linux thread_info from task variable found by pid
lx-clk-summary -- Print clk tree summary
lx-cmdline -- Report the Linux Commandline used in the current kernel.
lx-configdump -- Output kernel config to the filename specified as the command
lx-cpus -- List CPU status arrays
lx-device-list-bus -- Print devices on a bus (or all buses if not specified)
lx-device-list-class -- Print devices in a class (or all classes if not specified)
lx-device-list-tree -- Print a device and its children recursively
lx-dmesg -- Print Linux kernel log buffer.
lx-fdtdump -- Output Flattened Device Tree header and dump FDT blob to the filename
lx-genpd-summary -- Print genpd summary
lx-iomem -- Identify the IO memory resource locations defined by the kernel
lx-ioports -- Identify the IO port resource locations defined by the kernel
lx-list-check -- Verify a list consistency
lx-lsmod -- List currently loaded modules.
lx-mounts -- Report the VFS mounts of the current process namespace.
lx-ps -- Dump Linux tasks.
lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules.
lx-timerlist -- Print /proc/timer_list
lx-version -- Report the Linux Version of the current kernel.