I've been working on my kernel again recently, and I seem to have come across a pretty grey area as far as my knowledge is concerned.
Basically, I can't see how IO requests can be easily forwarded from the kernel to a device driver. This is a microkernel-ish system where the drivers would run in user-mode, hence making kernel buffers inaccessible to them.
Say, for example, that an application memory maps a file X to a particular region of address space. It then attempts to read a portion of this file, which results in a page fault. By my current design, my memory manager would detect that the attempted address is part of the region mapping file X, and it would scan the page cache for this part of the file. Having not found the page in the page cache, it would allocate a fresh page, and somehow issue a request to the file system in user-mode to read from the file into that particular physical page. This is the part I am having trouble understanding.
The only solution I can think of is to have the kernel call the read handler in the user-mode driver, then have the user mode driver 'request' the physical memory it needs to satisfy the request from the kernel. The kernel, somehow noticing that the driver is requesting memory for that particular IO operation involving file X, returns the physical page which was previously allocated for it. The driver would then initiate a DMA read into that page.
The thing is, I don't know if that would be possible, because the block size of the device might be bigger than the page size. Does that mean I will need more than one physical page for the transfer?
I'll be very grateful for any comments/help on this subject. I'm also willing to answer any questions you may have on my design and implementation, so fire away!
Cheers,
The Senaus
Making IO Requests to Device Drivers
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re:Making IO Requests to Device Drivers
I'm muddling through the same scenario in my own design. My thinking is that there should be a "pager protocol" between the ukernel and whatever user-mode pagers are allowed to interact with the kernel (I guess the file system might be one of them in your case).
When the kernel handles a page fault, it would grab some information from the faulting PTE that would tell it what pager to talk to, as well as what page that pager should retrieve. It would then act as a client of the pager, sending the request via IPC according to the rules of the pager protocol. The pager would then do its thing and send the requested page back to the kernel via IPC (either copy-on-write of the relevant PTE, or a direct transfer from the pager's address space to the kernel). The "do its thing" part I haven't spent much time thinking about yet. I'm assuming that the pager itself would allocate the physical page, or re-use an old one, and just DMA into that.
When the kernel handles a page fault, it would grab some information from the faulting PTE that would tell it what pager to talk to, as well as what page that pager should retrieve. It would then act as a client of the pager, sending the request via IPC according to the rules of the pager protocol. The pager would then do its thing and send the requested page back to the kernel via IPC (either copy-on-write of the relevant PTE, or a direct transfer from the pager's address space to the kernel). The "do its thing" part I haven't spent much time thinking about yet. I'm assuming that the pager itself would allocate the physical page, or re-use an old one, and just DMA into that.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager