1、启动 qemu
qemu-system-x86_64 -kernel ~/study/linux-4.19.157/arch/x86/boot/bzImage -initrd ~/study/initrd-busybox.img -append "console=ttyS0 nokaslr" -nographic -S -s
2、调试内核启动过程
在本ubuntu下打开另一个terminal,利用gdb连接本地的gdbserver 1234端口
gdb //开启gdb
file ~/study/linux-4.19.157/vmlinux //load Linux符号表
target remote:1234 //远程连接监听在TCP 1234的gdb server
b rest_init //在rest_init 函数设置断点
c //continue,继续执行代码
如遇到如下错误,则可参考3.安装gdb进行解决:
执行成功则打印如下(左侧是qemu,右侧是gdb):
在右侧按c,继续启动qemu。 ctrl + a然后按x可退出qemu。
3、调试sleep命令
- 在启动gdb的terminal,对do_nanosleep()函数打断点:
(gdb) b do_nanosleep
Breakpoint 2 at 0xffffffff81a2a380: file kernel/time/hrtimer.c, line 1681.
(gdb) c
Continuing.
- 在qemu启动成功后,执行sleep 1,然后会进入暂停:
/bin # sleep 1
- 此时可看到右侧启动gdb的terminal有如下打印,停在了断点处:
Breakpoint 2, do_nanosleep (t=0xffffc90000237e80, mode=HRTIMER_MODE_REL)
at kernel/time/hrtimer.c:1681
1681 {
- 再输入bt可打印此时的堆栈:
(gdb) bt
#0 do_nanosleep (t=0xffffc90000237e80, mode=HRTIMER_MODE_REL) at kernel/time/hrtimer.c:1681
#1 0xffffffff81121658 in hrtimer_nanosleep (rqtp=<optimized out>, mode=HRTIMER_MODE_REL, clockid=1) at kernel/time/hrtimer.c:1745
#2 0xffffffff81121951 in __do_sys_nanosleep (rmtp=<optimized out>, rqtp=<optimized out>) at kernel/time/hrtimer.c:1779
#3 __se_sys_nanosleep (rmtp=<optimized out>, rqtp=<optimized out>) at kernel/time/hrtimer.c:1766
#4 __x64_sys_nanosleep (regs=<optimized out>) at kernel/time/hrtimer.c:1766
#5 0xffffffff810043da in do_syscall_64 (nr=<optimized out>, regs=0x1 <irq_stack_union+1>) at arch/x86/entry/common.c:293
#6 0xffffffff81c00088 in entry_SYSCALL_64 () at arch/x86/entry/entry_64.S:238
#7 0x0000000000000000 in ?? ()