实模式 BIOS 例程和保护模式
我正在做一些操作系统实验。到目前为止,我的所有代码都利用实模式 BIOS 中断来操作硬盘和软盘。但是一旦我的代码启用了CPU的保护模式,所有实模式BIOS中断服务程序将不可用。如何IR/W硬盘和软盘? 我现在需要做一些硬件驱动程序吗?我该如何开始?这是操作系统开发如此困难的原因之一吗?
我知道硬件都是通过读取和写入某些控制或数据寄存器来控制的。例如,我知道硬盘的命令块寄存器范围是从0x1F0到0x1F7。 但是我想知道这么多不同硬件的寄存器地址在PC平台上是否相同?或者我必须在使用它们之前检测到这一点吗?如何检测它们?
由于我不确定如何在保护模式下读/写软盘或硬盘,所以我现在必须使用 BIOS 中断将所有必需的内核文件从软盘加载到内存中。但是如果我的内核文件超出了实模式 1M 空间限制,我该怎么办?
对于任何回复,我表示深深的谢意。
更新
我依稀记得有一种方法可以先切换保护模式,然后再切换回实模式。然后我们就可以在保护模式下使用 BIOS 例程了。也许我记错了。有人记得对吗?
I am doing some OS experiment. Until now, all my code utilized the real mode BIOS interrupt to manipulate hard disk and floppy. But once my code enabled the Protect Mode of the CPU, all the real mode BIOS interrupt service routine won't be available. How could I R/W the hard disk and floppy? Do I need to do some hardware drivers now? How could I start? Is this one of the reasons that an OS is so difficult to develop?
I know that hardwares are all controlled by reading from and writing to certain control or data registers. For example, I know that the Command Block Registers of hard disk range from 0x1F0 to 0x1F7. But I am wondering whether the register addresses of so many different hardwares are the same on the PC platform? Or do I have to detect that before using them? How to detect them??
Since I am not sure about how to R/W floppy or hard disk in Protect Mode, I have to use the BIOS interrupt to load all my necessary kernel file from floppy into memory for now. But what could I do if my kernel file exceeds the real mode 1M space limit?
For any responses I present my deep appreciation.
Update
I vaguely recall that there's a way to switch Protected Mode first and then switched back to real mode. And then we could use the BIOS routine in Protected Mode. Maybe I remember wrong. Did someone remember it right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
虽然可以在保护模式和实模式之间切换,但这几乎肯定不是您想要做的。这就是 286 上的工作方式(相当笨拙,因为它根本不支持从保护模式切换回实模式)。然而,从 386 开始,他们添加了 V86 模式,可以在保护模式下作为任务运行。
如果您想在保护模式下使用 BIOS,这几乎肯定是可行的方法。您基本上可以创建一个 V86 任务,切换到它以使用 BIOS,然后切换回另一个任务以执行保护模式代码。
如果您想尝试一下,您可能需要看看 DJGPP,它是一个 DOS 扩展程序(基本上,就像我刚才描述的那样,用于根据处理磁盘 I/O 等的需要处理 V86 任务的切换)以及相当旧版本的 gcc 的端口,因此您可以编写在其上运行的代码。
DOS 扩展器的商业市场现在基本上已经死亡,因此至少有一个以前的商业 DOS 扩展器(HX) 现已作为开源版本提供。如果您打算使用它,您可能希望将其与 OpenWatcom< /a> 编译器。
编辑:至于如何读取超过 1 MB 的文件(例如),它很简单但很笨拙:以块的形式读取数据,当您完成读取时,您要么重新映射内存,要么复制内容,将您阅读的内容带到您真正想要的地方,然后再阅读另一块。
就与硬件交谈而言:很大程度上取决于您是否只想要在某种程度上起作用的东西,或者您是否想充分利用现有的硬件。只需使用基本的 IDE 端口,您就可以与几乎任何不太古老的硬盘驱动器进行通信,但要充分利用硬件则需要做更多的工作。 IDE/ATAPI 驱动器使用了大约六种不同的 DMA 模式,每种模式的设置都略有不同。其中相当一部分已经足够老了,您可能不关心它们,因此您可能只想直接支持几个最新的,而对于其他任何内容,则退回到基本(非 DMA)传输。
While it's possible to switch between protected mode and real mode, it's almost certainly not what you'd want to do. This is how things were done on the 286 (quite clumsily, since it didn't intentionally support switching from protect mode back to real mode t all). Starting with the 386, however, they added a V86 mode which can run as a task in protected mode.
If you want to use the BIOS from protected mode, this is almost certainly the way to do things. You can basically create a V86 task, switch to it to use the BIOS, then switch back to another task to execute protected mode code.
If you want to play with this, you might want to take a look at DJGPP, which is a DOS extender (basically, a program like I just described to handle the switching into/out of a V86 task as needed to handle disk I/O and such) along with a port of a rather old version of gcc so you can write code that runs on it.
The commercial market for DOS extenders is now essentially dead, so at least one formerly commercial DOS extender (HX) is now available as open source. If you're going to play with that, you'd probably want to use it with the OpenWatcom compiler.
Edit: As far as how you read a file of more than 1 MB (for example), it's simple but clumsy: read the data in chunks, and when you've finished a read you either re-map the memory, or copy the contents, to get what you read to where you really want it, then read another chunk.
As far as talking to the hardware goes: a lot depends on whether you just want something that works to some degree, or if you want to take full advantage of the hardware that's present. Just using the basic IDE ports will let you talk to almost any hard drive that isn't really ancient -- but getting the most out of the hardware is quite a bit more work. IDE/ATAPI drives have used about a half dozen different DMA modes, each of which has to be set up slightly differently. Quite a few of those are old enough you probably don't care about them, so you might want to directly support only a couple of the newest, and for anything else fall back to basic (non-DMA) transfers.
如果您使用旧版 IDE,所有硬件都将以相同的方式进行通信 - 您不必担心编写自定义驱动程序(尽管如果您走得足够远,您会发现即使他们都说它们遵循相同的规范,他们都有自己有趣的怪癖)
http://www.t13.org/ 和 http://www.t10.org 是您可以找到相关规范的地方 - 如果您有勇气,您可以还要编写 SATA 驱动程序 - 您可以在 Intel 网站上找到 AHCI 规范 (http:// /www.intel.com/technology/serialata/ahci.htm)
If you use legacy IDE, all of the hardware will communicate in the same fashion - you don't have to worry about writing custom drivers (though should you get far enough, you will find that even though they all say they follow the same spec, they all have their fun quirks)
http://www.t13.org/ and http://www.t10.org are where you'll find the relevant specs - if you're feeling brave, you could also write a SATA driver - you'll find the AHCI spec on Intel's website (http://www.intel.com/technology/serialata/ahci.htm)
看来你的问题不是如何与硬件对话(设备驱动程序可以解决的问题),因为 BIOS 接口对你来说已经足够了。
相反,您需要知道如何在保护模式环 0(可以无限制地访问 BIOS 调用和所有其他特权指令)和应用程序代码通常所在的保护模式环 3 之间进行通信。这是一个系统调用。几乎所有体系结构都在特权模式下运行中断处理程序,因此软件中断是实现系统调用的一种方式,x86 还提供了为此目的优化的 syscall 指令。
当然,您可以使用平面内存模型在环 0 中运行所有内容,您可以直接访问所有内存。
Ring 0/ring 3 是 x86 术语,但所有具有 MPU 的系统都支持某种特权模式的概念,该模式允许通过物理地址访问内存(对于分离内存 I/O 架构,可以访问所有 I/O 空间) )。
It seems that your question is not how to talk to hardware (the problem device drivers would solve) because the BIOS interfaces are sufficient for you.
Rather, you need to know how to communicate between protected mode ring 0 (which has unlimited access to BIOS calls and all other privileged instructions) and protected mode ring 3 where application code usually lives. This is a system call. Pretty much all architectures run interrupt handlers in privileged mode so a software interrupt is one way of implementing system calls, x86 also provides a
syscall
instruction which is optimized for this purpose.Of course, you could just run everything in ring 0 with a flat memory model where you can access all memory directly.
Ring 0/ring 3 is the x86 terminology, but all systems with an MPU support some concept of a privileged mode which allows access to memory by physical address (and for split memory-I/O architectures, access to all of I/O space).
如果您想要从 32 位模式读取硬盘(或 USB 闪存盘)的代码,您可以从我的操作系统项目中找到一些代码 PwnOS。它不支持 DMA 或其他任何东西,但基本功能可以工作。具体来说, trunk/Core/IO/ATA Driver.asm 包含用于读取 ATA 设备的代码,例如硬盘驱动器(没有幻数!:D)
我决定不编写用于写入设备的代码,因为我不想冒这个险,但它非常相似。这些规范可以在谷歌搜索“cottontail os dev”时找到(您需要 ATA/ATAPI-6 文档),但它们有点难以理解。
如果您对此还有任何疑问,请随时询问。我还有设置为 64 位模式的代码,以及专门为操作系统开发设计的汇编语言编辑器(搜索 Inventor IDE),因为它内置了 16 个汇编语言的汇编和链接位、32 位和 64 位代码位于定义的地址和文件偏移量处。这样,您就可以专注于您感兴趣的部分,而不是琐碎的事情。
If you'd like code to read the harddrive (or USB key) from 32-bit mode, you can find some from my OS project PwnOS. It doesn't support DMA or anything, but the basics work. Specifically, trunk/Core/IO/ATA Driver.asm contains the code for reading an ATA device, e.g. harddrive (without magic numbers! :D)
I decided not to write the code for writing a device, since I didn't want to risk it, but it's very similar. The specs can be found at the first google hit for "cottontail os dev" (you'll want the ATA/ATAPI-6 document), but they're a bit hard to follow.
If you have any more questions about it, feel free to ask. I've got code to get set up into 64-bit mode as well, as well as an assembly language editor that I specifically designed for OS development (search for Inventor IDE), in that it has built-in assembling and linking of 16-bit, 32-bit, and 64-bit code at defined addresses and file offsets. That way, you can focus on the part you're interested in, instead of the fluff.
此处有一组有关保护模式的教程。 tut15和tut16在v86模式下有效运行DOS和BIOS,所有中断都有效。
There's a set of tutorials on Protected Mode here. Tut15 and tut16 effectively run DOS and BIOS in v86 mode, all interrupts work.
V86:是的,要走的路,但如果设置操作系统:
试试这个(专为长模式设计,但应该可以工作。我还没有测试过这个,我看不出它有什么理由不能工作。问题不是 nasm,它是 ld。)
LD H8s 16 位 ELF/aout 引用。这是从 GRUB 加载的标准。
我知道 32 位 CS 已关闭,我需要仔细检查其位置。否则看起来还不错。
这很难找到代码。
--
;修改为32位??
V86: yes the way to go, but if setting up an OS:
try this(designed for long mode but should work.I havent tested this YET, I see no reason it wont work yet.Issue is not nasm, its ld.)
LD H8s 16-bit ELF/aout references.This is standard to load from GRUB.
I kow the 32-bit CS is off, I need to double check its location. Otherwise it looks ok.
This is hard to find code.
--
;modify for 32bit??
如果您正在编写一个操作系统,它确实需要为其需要使用的任何硬件(包括存储设备)提供设备驱动程序。如果您想避免在这么早的阶段需要驱动程序,您可以考虑使用现有的引导加载程序(例如 grub),但最终您还是需要它们。
If you're writing an operating system, it really needs to have device drivers for any hardware it needs to use, including the storage devices. If you want to avoid needing drivers at such an early stage, you could consider using an existing bootloader like grub, but eventually you'll need them anyway.
该项目现在已经是一个老项目了,但是犹他州的 OSKit 项目可能仍然在现代机器上运行,因为其他 20 世纪 90 年代末的操作系统仍然可以在今天的 PC 上找到 RAM 和磁盘驱动器? — 是与任何特定操作系统分开构建的设备驱动程序堆栈,以便您只需编写 C 代码即可开发自己的内核。
有点整洁;你可以编译“你好,世界”。用 C 语言编写 OSKit 并获得一个可以启动并打印“Hello, world”的操作系统。然后停了下来。 :-)
不管怎样,如果你真的在做一个“操作系统实验”,你可能想尝试一下——或者至少使用它的代码作为如何启动和运行某些驱动程序的指南。当然,如果您确实较少进行“操作系统实验”,而更多地进行“了解有关 x86 的晦涩事实”,那么它的作用可能会超出您的预期。 :-)
http://www.cs.utah.edu/flux/oskit/
The project is now an old one, but the OSKit project at Utah — which might still run on modern machines, since other late-1990s operating systems can still find the RAM and disk drives on today's PCs? — was a device-driver stack build separately from any particular operating system so that you could develop your own kernel just by writing C code.
It was kind of neat; you could compile "Hello, world." in C against OSKit and get an OS you could boot that came up and printed "Hello, world." and then halted. :-)
Anyway, if you are really doing an "OS experiment", you might want to try it out — or at least use its code as a guideline for how to get up and running with some drivers. Of course, if you're really doing less of an "OS experiment" and more of a "learn obscure facts about x86", then it might do more than you want. :-)
http://www.cs.utah.edu/flux/oskit/
ATAPI 设备使用相同的端口。您可以模拟 DPMI 以突破 1MB+64k 限制,但是,是的,学习保护模式。
ATAPI devices use the same ports. You can emulate DPMI in order to get past the 1MB+64k limit, but yeah, learn Protected Mode.