Brendan wrote:
Hi,
physecfed wrote:
From what I read, the IOPB is quite literally a bitfield, with one bit corresponding to allowed/restricted port accesses for the process specified by that GDT entry (took me awhile to get that far, the Intel SDM and docs are a little bit too verbose to make reading them not a chore).
It is a pure bitfield (with one bit per IO port, and where anything larger than a byte access require permission to access each byte - e.g. reading a dword from IO port 0x1234 requires permission to access the IO ports 0x1234, 0x1235, 0x1236, 0x1237). Also note that the IO permission bitmap doesn't need to be a full 65536 bits (8 KiB), and only needs large enough for the IO ports you want to allow rounded up to the next 32 (e.g. if you only want to allow access to IO port 0x0001, then you need an IO permission bitmap with 32 bits).
The simplest way of doing this is to have one TSS per CPU and copy the IO permission bitmap into it during task switches (and change IO permission bitmap's size to zero to avoid copying if the task isn't allowed to access any IO ports, which is the most common case). There's "clever" ways to avoid that copying, but they're probably not worth the hassle.
Also note that you don't necessarily need to pick one option - you can use multiple different options and switch between them (either dynamically based on performance feedback, or via. user config, or..).
physecfed wrote:
Now, when you speak of ISA devices, do you mean via 8257 DMA (hardware/emulated) controllers? If I'm not attempting to develop for ISA devices or bus standards requiring that sort of setup, could I simply implement IOMMU protection to allow the drivers to directly access certain, limited areas of memory?
Yes, I mean the old 8257 DMA. I don't know what hardware you're targeting; but there's 3 cases - "ancient" (where you actually have ISA cards in ISA slots on the motherboard), "less ancient" (where you don't have ISA slots or true ISA devices; but things like serial and parallel ports and floppy controller are built into the chipset and use the old ISA DMA controller), and "modern" (where serial ports, parallel ports and floppy controller have all been replaced by USB so you don't need the old ISA DMA controller for anything).
If you do have IOMMU then you could probably use IOMMU to restrict the old ISA DMA (and enhance it - to break the "first 16 MiB of RAM" limitation).
Note that the main problem/s with IOMMU is that there's still a lot of computers that don't have the necessary hardware (Intel treated it as "only for people that want to pay extra for virtualisation support" for a long time), and Intel and AMD do it differently, and it can end up intertwined with code to support virtual machines.
Cheers,
Brendan
I'm tending to think (without having read more on the subject first, which I should probably do) that I'll likely err on the side of setting up memory management for MMIO and system calls for I/O port use. At least in the case of the I/O ports, it might make it a little more intuitive security- and containment-wise if the kernel gets to mediate I/O port use, and at any rate seeing as the I/O port manner of throughput is slower than memory-mapped things, I doubt the kernel will make its one user very angry, at least at the beginning.
As to the hardware I'm planning on targeting - who knows at this point! Being a realist, by the time my kernel hits the point where it can scratch the surface of modern hardware capability, my current 6-core CAD workstation will probably be mothballed. I like the idea of targeting old hardware for its simplicity, but every time I sit down to find some old cheap floppy drive-carrying junker machine on eBay to use as a OS dev rig, I then think of more and more niceties and "useful" features until I eventually just end up at a modern machine anyway.
At any rate, I want to involve myself pretty thoroughly in the theory at first so I have a good idea of the core components and notions behind a microkernel before I set out. That way, if I complete the quest, I end up with a microkernel rather than some hybrid kernel full of ugliness and expletive-laced comments. Needless to say, I'm looking to acquire a bunch of books by Tanenbaum that discuss MINIX and its architecture.
Do you prefer to plan from theory and "higher-level" architecture first, or do you tend to enjoy jumping into the code first and shaping the work-in-progress?