【发布时间】:2018-07-15 04:39:40
【问题描述】:
我目前正在研究引导加载程序和内核开发(刚刚开始) 我正在关注以下组合 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 部分视频驱动程序之后,我被卡住了,因为屏幕驱动程序确实在屏幕上打印了一些东西,但是由于数据未对齐或其他原因而发生了一些事情。所以接下来我想尝试调试我的程序。这也包含在 repo 的第 14 部分检查点中。所以我为目标 x86_64-elf 构建了 gdb。但是当我尝试使用system-qemu-x86_64 -s -S -fda os-image 运行 qemu 和 gdb 时
然后只需运行gdb 并尝试通过运行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 无法解释我的可执行文件,因为在运行 target remote localhost:1234 然后 symbol-file kernel.elf 之后,终端现在返回
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 确实返回一个值,但该值为 0(我认为这是类型),但是根据我的代码,它应该已经设置为新值。此外,当尝试next 时,它会返回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
有什么想法吗?
【问题讨论】:
-
BOCHS 可能有用:它是另一个 x86 仿真器,但它内置了调试器,而不仅仅是 GDB 远程目标。 (不过,我并没有使用太多,所以 IDK 如果 qemu-system-x86_64 以 EFI 或其他方式以长模式启动,而不是像 PC 传统 BIOS 那样以实模式启动。)
-
在实模式和保护模式之间切换或切换到 64 位长模式时,您通常会看到此错误。 GDB 在所有情况下都不能正确跟踪模式更改,最终会出现此错误。如果调试引导加载程序,我推荐 Bochs,因为它了解模式之间的转换。在某些情况下,您可以在收到此错误后设置新架构,然后重新启动调试会话,但它并不总是有效。我似乎记得写过一个关于这个的答案,但我现在找不到那个答案。
-
OSDev Wiki 上列出了一些其他可能的解决方法:wiki.osdev.org/QEMU_and_GDB_in_long_mode
-
我已经打了补丁,现在g包错误消失了。但是,在运行
target remote localhost:1234然后symbol-file kernel.elf之后,gdb 似乎无法解释我的可执行文件,终端显示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 ?? ()