我目前正在学习引导程序和内核开发(刚开始)。我正在结合使用以下两个资源:
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-video-driver部分后,我卡住了,因为屏幕驱动程序确实向屏幕打印了一些东西,但是数据似乎存在错位或其他问题。所以下一步我想尝试调试我的程序。这也在存储库的14-checkpoint部分中有所涉及。因此,我为目标x86_64-elf构建了gdb。但是,当我尝试运行
有没有什么想法我错过了/做错了?如果需要更多信息,请让我知道。谢谢。
编辑:我已经应用了@MichaelPetch提到的补丁,现在g packet错误已经消失了。 但是看起来gdb无法解释我的可执行文件,因为在运行
有什么想法吗?
唯一不同的是,我将目标定为x86_64而不是i386。此外,我使用qemu进行仿真(qemu-system-x86_64)。 现在,在遵循GitHub存储库中的16-video-driver部分后,我卡住了,因为屏幕驱动程序确实向屏幕打印了一些东西,但是数据似乎存在错位或其他问题。所以下一步我想尝试调试我的程序。这也在存储库的14-checkpoint部分中有所涉及。因此,我为目标x86_64-elf构建了gdb。但是,当我尝试运行
system-qemu-x86_64 -s -S -fda os-image
以及运行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 packet错误已经消失了。 但是看起来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
有什么想法吗?
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 ?? ()
- Jaap Wijnen