How to solve qemu gdb debug error: Remote 'g' packet reply is too long?
How to solve qemu gdb debug error: Remote 'g' packet reply is too long?
我目前正在研究引导加载程序和内核开发(刚开始)
我正在关注的组合
https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf
以及在中找到的代码
https://github.com/cfenollosa/os-tutorial
唯一不同的是我的目标是 x86_64 而不是 i386。我还使用 qemu 来模拟 (qemu-system-x86_64)。
现在,在按照 GitHub 回购到第 16 部分视频驱动程序后,我被卡住了,因为屏幕驱动程序确实在屏幕上打印了一些东西,但由于数据未对齐或其他原因而发生了一些事情。所以接下来我想尝试调试我的程序。这也包含在回购协议的第 14 部分检查点中。所以我为目标 x86_64-elf 构建了 gdb。但是当我尝试使用 system-qemu-x86_64 -s -S -fda os-image
运行 qemu 和 gdb 时
然后 运行 gdb
并尝试通过 运行ning target remote localhost:1234
连接到 qemu,一旦我 运行 收到以下错误消息
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
Remote 'g' packet reply is too long (expected 308 bytes, got 536 bytes):
000000000000000000000000000000000000000000000000630600000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000f0ff0000000000000200000000f00000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000007f03000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000801f0000
关于我遗漏/做错了什么的任何想法?如果需要更多信息,请告诉我。
谢谢
编辑:
我已经应用了@MichaelPetch 提到的补丁,现在 g 数据包错误消失了。但是,看起来 gdb 无法将我的可执行文件解释为 运行ning target remote localhost:1234
之后 symbol-file kernel.elf
,终端现在 returns
Remote debugging using localhost:1234 warning: No executable has been
specified and target does not support determining executable automatically.
Try using the "file" command. 0x0000fb38 in ?? ()
不过我可以在函数和行号上设置断点。但是当尝试使用 print terminal_buffer
打印当前位置应该可用的变量时,我得到
No symbol "terminal_buffer" in current context.
terminal_buffer 是在当前范围内声明的变量。
然而,当我打印一个在我放置断点的函数范围之外声明的变量时,例如一个 int,print
执行 return 一个值,但值为 0 (我认为这是该类型的初始值),但是根据我的代码,它应该已经设置为一个新值。此外,当尝试 next
时,它 returns Cannot find bounds of current function
这让我认为它无法解释某些部分。
在我的引导加载程序中,我使用以下方法将保护模式更改为 运行 64 位内核:
[bits 16]
switch_to_pm:
cli ; 1. disable interrupts
lgdt [gdt_descriptor] ; 2. load the GDT descriptor
mov eax, cr0
or eax, 0x1 ; 3. set 32-bit mode bit in cr0
mov cr0, eax
jmp CODE_SEG:init_pm ; 4. far jump by using a different segment
[bits 32]
init_pm: ; we are now using 32-bit instructions
mov ax, DATA_SEG ; 5. update the segment registers
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000 ; 6. update the stack right at the top of the free space
mov esp, ebp
call BEGIN_PM ; 7. Call a well-known label with useful code
有什么想法吗?
所有问题的原因是您正在编译 64 位代码并 运行在 32 位保护模式下编译它。 64 位代码在该环境中不会 运行 正常。奇怪的是,它通常在尝试写入视频显示器时首先出现。通常事情会打印出来,但并不完全是你想要的方式。不正确解码的指令将导致调试器像您观察到的那样不稳定地工作。
解决问题的一种方法是编译 link 内核作为 32 位可执行文件。您使用的是 64 位编译器,因此您需要添加 -m32
CFLAGS(或您的 GCC 命令行)。如果使用 LD 到 link -melf_i386
将是必需的。用 NASM 组装应该是 -felf32
而不是 -felf64
.
或者,您必须在引导加载程序中将处理器置于 64 位长模式。您可以在 OSDev wiki.
上阅读有关该过程的更多信息
如果调试 32 位代码,您可能需要使用 qemu-system-i386
。你会少一些麻烦。
连接和断开连接
我在 How to debug the Linux kernel with GDB and QEMU?
详细了解了它的工作原理
关键是在 GDB 上连接和断开连接:
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set arch i386:x86-64' \
-ex 'target remote localhost:1234'
相关:Remote 'g' packet reply is too long
我目前正在研究引导加载程序和内核开发(刚开始) 我正在关注的组合 https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf 以及在中找到的代码 https://github.com/cfenollosa/os-tutorial
唯一不同的是我的目标是 x86_64 而不是 i386。我还使用 qemu 来模拟 (qemu-system-x86_64)。
现在,在按照 GitHub 回购到第 16 部分视频驱动程序后,我被卡住了,因为屏幕驱动程序确实在屏幕上打印了一些东西,但由于数据未对齐或其他原因而发生了一些事情。所以接下来我想尝试调试我的程序。这也包含在回购协议的第 14 部分检查点中。所以我为目标 x86_64-elf 构建了 gdb。但是当我尝试使用 system-qemu-x86_64 -s -S -fda os-image
运行 qemu 和 gdb 时
然后 运行 gdb
并尝试通过 运行ning target remote localhost:1234
连接到 qemu,一旦我 运行 收到以下错误消息
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
Remote 'g' packet reply is too long (expected 308 bytes, got 536 bytes):
000000000000000000000000000000000000000000000000630600000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000f0ff0000000000000200000000f00000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000007f03000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000801f0000
关于我遗漏/做错了什么的任何想法?如果需要更多信息,请告诉我。
谢谢
编辑:
我已经应用了@MichaelPetch 提到的补丁,现在 g 数据包错误消失了。但是,看起来 gdb 无法将我的可执行文件解释为 运行ning target remote localhost:1234
之后 symbol-file kernel.elf
,终端现在 returns
Remote debugging using localhost:1234 warning: No executable has been
specified and target does not support determining executable automatically.
Try using the "file" command. 0x0000fb38 in ?? ()
不过我可以在函数和行号上设置断点。但是当尝试使用 print terminal_buffer
打印当前位置应该可用的变量时,我得到
No symbol "terminal_buffer" in current context.
terminal_buffer 是在当前范围内声明的变量。
然而,当我打印一个在我放置断点的函数范围之外声明的变量时,例如一个 int,print
执行 return 一个值,但值为 0 (我认为这是该类型的初始值),但是根据我的代码,它应该已经设置为一个新值。此外,当尝试 next
时,它 returns Cannot find bounds of current function
这让我认为它无法解释某些部分。
在我的引导加载程序中,我使用以下方法将保护模式更改为 运行 64 位内核:
[bits 16]
switch_to_pm:
cli ; 1. disable interrupts
lgdt [gdt_descriptor] ; 2. load the GDT descriptor
mov eax, cr0
or eax, 0x1 ; 3. set 32-bit mode bit in cr0
mov cr0, eax
jmp CODE_SEG:init_pm ; 4. far jump by using a different segment
[bits 32]
init_pm: ; we are now using 32-bit instructions
mov ax, DATA_SEG ; 5. update the segment registers
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp, 0x90000 ; 6. update the stack right at the top of the free space
mov esp, ebp
call BEGIN_PM ; 7. Call a well-known label with useful code
有什么想法吗?
所有问题的原因是您正在编译 64 位代码并 运行在 32 位保护模式下编译它。 64 位代码在该环境中不会 运行 正常。奇怪的是,它通常在尝试写入视频显示器时首先出现。通常事情会打印出来,但并不完全是你想要的方式。不正确解码的指令将导致调试器像您观察到的那样不稳定地工作。
解决问题的一种方法是编译 link 内核作为 32 位可执行文件。您使用的是 64 位编译器,因此您需要添加 -m32
CFLAGS(或您的 GCC 命令行)。如果使用 LD 到 link -melf_i386
将是必需的。用 NASM 组装应该是 -felf32
而不是 -felf64
.
或者,您必须在引导加载程序中将处理器置于 64 位长模式。您可以在 OSDev wiki.
上阅读有关该过程的更多信息如果调试 32 位代码,您可能需要使用 qemu-system-i386
。你会少一些麻烦。
连接和断开连接
我在 How to debug the Linux kernel with GDB and QEMU?
详细了解了它的工作原理关键是在 GDB 上连接和断开连接:
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set arch i386:x86-64' \
-ex 'target remote localhost:1234'
相关:Remote 'g' packet reply is too long