我正在学习如何在Rust中编写一个操作系统的Phil-Opp Tutorials,在对它进行了一些修改之后,我想在屏幕上显示真实的图形。
我想我应该从使用线性帧缓冲区开始,使用VESA。我在osdev.org上找到了一些教程here和here,但它们一直在谈论“函数代码”和es:di
。第二个链接说:
函数:获取VESA BIOS信息
功能代码:0x4F00
描述:返回VESA BIOS信息,包括制造商、支持的模式、可用的视频内存等。。。输入:AX=0x4F00
输入:ES:DI=Segment:Offset指向存储VESA BIOS信息结构的位置的指针。
输出:AX=0x004F成功时,其他值表示不支持VESA BIOS。
无论如何,上面的函数返回以下结构并将其存储在ES:DI中,就像它们在条目中一样。在条目中,ES:DI应包含指向以下结构的指针:vbe_info_structure: .signature db "VBE2" ; indicate support for VBE 2.0+ .table_data: resb 512-4 ; reserve space for the table below
虽然我看过一些汇编语言教程,但我不知道“函数代码”是什么。据我所知,如果我mov ax, 0x4f00
,并创建一个类似于上面的结构,它将神奇地覆盖该结构,然后我可以将其作为参数传递给Rust代码?如何设置或需要设置我的es:di
?(通过研究,我认为它只是自动设置在现代处理器上)
我应该在内联程序集中做这些事情吗?我应该使用UEFI重写内核吗?如果你能举例说明如何在Rust代码中访问vbe_info_结构(我正在运行long mode
)。
这是目前为止我的boot.asm
文件,但它还不起作用:https://gist.github.com/nebrelbug/5a0042d4de32f942bb72e71fe282bdd2。谢谢!
最佳答案
在boot.asm文件中,您有:
get_vesa_info:
mov ax, 0x4f00
mov [es:di], vbe_info_structure
int 0x10
ret
第三行必须替换为
mov di, vbe_info_structure
说明:现在,它试图在es:di所指的地址(在您的例子中是未定义的)写入常量vbe_info_结构。相反,您需要的是将地址vbe_info_结构加载到di中,然后将其传递给int 0x10例程。
顺便说一下,int 0x10执行几个函数。为了告诉它您要调用哪个,您在ax寄存器中传递“函数代码”。将函数代码看作函数的名称(程序集中没有名称,只有数字和地址)。
另外,您需要正确设置es。也可以
push ds
pop es
假设ds已经指向section.data,或者使用汇编程序指令(
assume es section.data
?--不确定,我已经很久没有使用汇编程序了)。或者像这样:
mov ax, @section.data
mov es, ax
当然,这应该在将0x4f00加载到ax之前完成。