(I'm not quite sure how to phrase this, as I think I may be making poor assumptions about the nature of the kernel.)
In a microkernel that is running drivers as user mode processes, do user applications usually use IPC to make requests (such as file open/read/close/etc)?
Say (somehow) the file system driver gets a request to read a certain file. It needs to then request that its associated data device reads a certain location for a certain length of bytes (in whatever units, perhaps sectors). Now just to be a bit more specific, lets say the requested file is on an ATA harddrive. So then the file system driver has to make a request to the ATA driver (maybe the file system driver doesn't know that the device is, it just has some sort of identifier number).
Do microkernels often keep track of requests such as these, and have drivers pass along some kind of handle? Couldn't the ATA driver still bring everything down from user mode by giving the Busmaster DMA wrong addresses (say, by having overwrite the scheduler's code?) ?
Should microkernels attempt to keep physical page addresses from device drivers of known varieties by having requests to such devices as some sort of request structure in the kernel, and then have device drivers able to syscall to put physical addresses within the requests range into memory mapped registers owned by the driver?
Thanks,
-Mike
User mode drivers & physical page safety
Re: User mode drivers & physical page safety
The following just applies to my microkernel. Since "microkernel" is no fixed concept but just a direction, every microkernel does it in a different way, I think.
My user-application can use open, read, write, ioctl and close to talk with drivers. They open a specific "file" in the VFS which is handled in a special way by the kernel. The kernel converts the mentioned requests into messages, sends them to the driver, waits for a response and passes it back to the app.Hangin10 wrote:In a microkernel that is running drivers as user mode processes, do user applications usually use IPC to make requests (such as file open/read/close/etc)?
My filesystem-process is accessed by the kernel the same way as just mentioned for the drivers. There is always a root-partition. The device of the root-partition is given to fs via a multiboot-parameter. Additional devices/partitions can be added via mount which also passes the driver-path to fs with which the device or partition can be accessed. So there are no handles or similar passed around but just a path which is resolved by fs and leads to an inode on some device. The device-number and inode-number is passed back to the kernel which stores it in the global-file-table. So if the app calls read with a file-descriptor the device-number and inode-number is fetched from the GFT by the kernel and passed to fs.Hangin10 wrote:Do microkernels often keep track of requests such as these, and have drivers pass along some kind of handle?
I'm not using DMA yet but AFAIK there is no way that user-apps can bring anything down in my system. Because the requests that are sent to the drivers or to fs are made by the kernel. The drivers, of course, have to validate some parameters such as offset and length when reading or writing. Besides that there are no "dangerous" parameters passed to drivers such as pointers to which they directly write or similar.Hangin10 wrote:Couldn't the ATA driver still bring everything down from user mode by giving the Busmaster DMA wrong addresses (say, by having overwrite the scheduler's code?) ?
Re: User mode drivers & physical page safety
Hi,
For my previous OS, there was no way for a device driver to determine physical addresses, except for using a special "allocate RAM for DMA use" kernel function. The intent here is to force device drivers to only ever use specially allocated buffers for DMA (and to allow the kernel to support IOMMU without needing to change any of the device drivers). This does have performance implications though - for e.g. the device driver can't transfer data to/from any other physical pages, which means the data needs to be copied to/from the special buffer first (where this extra copying causes additional overhead). For my purposes, I'm willing to sacrifice performance for extra protection/security (but it's a choice you'd need to make based on your own goals).
Cheers,
Brendan
For my OS applications use messaging (IPC) to talk to the VFS, the VFS uses messaging to talk to file system drivers, file system drivers uses messaging to talk to storage device drivers. The kernel doesn't know or care about any of this - the kernel only has "send_message()" and "get_message()" functions.Hangin10 wrote:In a microkernel that is running drivers as user mode processes, do user applications usually use IPC to make requests (such as file open/read/close/etc)?
DMA and bus-mastering devices can still bring everything down. However there are some things you can do. For example (for my OS), for "ISA DMA" (e.g. serial ports, parallel ports, floppy controllers and old sound cards) the device driver asks the kernel to setup the DMA transfer and the kernel can do suitable checks before programming the DMA controller. Also, for newer systems have IOMMUs (mainly intended for virtualization) - for the next version of my OS I'm hoping to use the IOMMU to prevent incorrect DMA use.Hangin10 wrote:Couldn't the ATA driver still bring everything down from user mode by giving the Busmaster DMA wrong addresses (say, by having overwrite the scheduler's code?) ?
I'm not too sure I understood what you're asking here...Hangin10 wrote:Should microkernels attempt to keep physical page addresses from device drivers of known varieties by having requests to such devices as some sort of request structure in the kernel, and then have device drivers able to syscall to put physical addresses within the requests range into memory mapped registers owned by the driver?
For my previous OS, there was no way for a device driver to determine physical addresses, except for using a special "allocate RAM for DMA use" kernel function. The intent here is to force device drivers to only ever use specially allocated buffers for DMA (and to allow the kernel to support IOMMU without needing to change any of the device drivers). This does have performance implications though - for e.g. the device driver can't transfer data to/from any other physical pages, which means the data needs to be copied to/from the special buffer first (where this extra copying causes additional overhead). For my purposes, I'm willing to sacrifice performance for extra protection/security (but it's a choice you'd need to make based on your own goals).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: User mode drivers & physical page safety
I guess my idea is similar, but much less secure. The kernel would translate requests for read / write of blocks (devices like ATA) into a structure in the kernel that has the start physical location for the data to go, the size of the operation, and whether it is read / write. When the driver gets the read / write message, that includes a handle to the kernel request structure, which the driver can call the kernel to have the physical target + an offset placed into a memory address. The offset being out of range of the request would be most (possibly all) of the protection the kernel provides (besides the whole user space thing).Brendan wrote:I'm not too sure I understood what you're asking here...Hangin10 wrote:Should microkernels attempt to keep physical page addresses from device drivers of known varieties by having requests to such devices as some sort of request structure in the kernel, and then have device drivers able to syscall to put physical addresses within the requests range into memory mapped registers owned by the driver?
For my previous OS, there was no way for a device driver to determine physical addresses, except for using a special "allocate RAM for DMA use" kernel function. The intent here is to force device drivers to only ever use specially allocated buffers for DMA (and to allow the kernel to support IOMMU without needing to change any of the device drivers). This does have performance implications though - for e.g. the device driver can't transfer data to/from any other physical pages, which means the data needs to be copied to/from the special buffer first (where this extra copying causes additional overhead). For my purposes, I'm willing to sacrifice performance for extra protection/security (but it's a choice you'd need to make based on your own goals).
This isn't much better than just giving the driver physical addresses, but at least the driver doesn't necessarily have to look at what address the kernel gave it.