designing driver / fs interface

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
pulsar
Member
Member
Posts: 49
Joined: Wed Nov 22, 2006 1:01 am
Location: chennai

designing driver / fs interface

Post by pulsar »

Hi
Documents regarding file system interface, device interface designing are harder to find. I have been looking through various sources and finally i think i understand how they work. Still when considering design of a new interface, its seems really impossible because driver interface, file system interface and virtual file system are closely related.
Basic framework required to implement driver interface, fs interface are present in the kernel. So how to begin the basic design? mobius source seems quite harder to understand and i dont want to confuse myself with asynchronous I/O. Will it be harder to modify the design to support asynchronous I/O.
I am having some idea :idea: about how to begin.
1. Try to write some mount kind of function to store the mount points and to load the file system driver.
2. The fs driver will return fs object and these fs objects have to be stored in some structures. mount points should have related informations such as the driver, device.
3. Then path traversal function and functions to construct a directory structure
4. General Read and write functions which unpacks the path and calls the appropriate driver.
5. the driver should query the device. So device open, read, write functions must be implemented. Storing devices and device information in some ordered way.
At this point we will have a hardly finished io interface.
After this we should begin to write drivers for some standard devices and filesystems.

Is vfs a separate file system (as in case of mobius) or will the requests pass through the vfs. I have implemented a simpler driver interface similar to one of Therx, (much simpler type) ,Since i wrote kernel in assembly,it was a better choice. Since this kernel is written in C now, i would like to design a rather complex one.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Well, how I did it was this:
Start simple, work from there. First, create structures to gather information about disks and drives, and have a way to register each device you find. In my OS, I wrote the driver for I/O. The OS then called the driver to get a list of PHYSICAL drives that it has access to . For example, my ide driver would return 2 hard drives and a cd drive. My OS would store the device information (things like bytes per sector, sector count, etc), and which driver that reported it, so it can query this driver each time a request comes in for the drive. Each driver has basic support for reading and writing to a sector, and returns each disks size, and a little info (like if it's even writeable or removeable, like a floppy or cd). My OS takes each physical drive and reads the MBR to check if it's a partition table or not, if it is. It then creates a list of "drives" that are available. So hard disk one would report 2 partitions, hard disk two would report 3 partitions, and the cd drive and floppy both report 1 each, so i have a total of 7 drives in my list. Each drive stores it's physical disk ID and offset into this device (as well as some other speciifcs). Then my file system drivers have a stub program, I simply read the first sector of each partition, and pass that to each drivers stub, and it reports whether it will support this FS or not. So, my FAT driver will take the boot sector of a partition, and check for a valid fat table, etc, and return if it is or isn't supported. Now my OS now has, for each drive in the system, which file system driver to use, which physical disk driver to use, how many partitions are in each disk, how to read/write each disk, etc. I can now make a call to each drive to open a file, and it passes this onto the filesystem driver, which knows how to handle the file system, and this driver forwards it's calls to the physical disk driver (since the drive references this). Each physical disk driver has the same interface, as do the file system drivers, although some things may change, it works for now ;).
User avatar
pulsar
Member
Member
Posts: 49
Joined: Wed Nov 22, 2006 1:01 am
Location: chennai

Post by pulsar »

@Ready4Dis: That's what i dont want to do. Still i dont think you are having a driver interface. I dont want to write a driver, i need a way to manage the drivers in my kernel effectively. As i already said this is the way i proceeded with my previous kernel and atlast the driver interface / f/s interface required total redesign. I dont want to redesign it, since there were lot of dependencies in it (and it could make serious flaws in kernel). So i started from the scratch. I have some experience with designing an interface and I dont want to repeat a mistake twice. However it could work, but i dont want to take a risk. In short i want to design a kernel that could be easy to understand and followed by others.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Ohh, I am sorry, I guess I miss-understood what you were asking. Here is how I actually handle said drivers.

I have a standard header for each driver file, similar to this:

Code: Select all

VersionLow db 0x00
VersionHigh db 0x01
DriverType db 0x01 ;I/O driver
SubType db 0x01     ;Fixed Disk

FunctionCount dd 5
FunctionList dd Query
dd ReadSectors
dd WriteSectors
dd DiskInfo
dd Close

FunctionStrings db 'Query',0
db 'ReadSectors',0
db 'WriteSectors',0
db 'DiskInfo',0
db 'Close',0

;Functions here
So, for example, my OS boots, kernel stores a list of drivers, the drivers are stored by category (I/O, System driver, like memroy manager, or multitasking, etc). So, when the kernel starts, it will load this IDE driver (could be a floppy driver also, whatever), and calls Query, which returns the # of devices found, and maybe a pointer to a manufacturer string, etc. Then, you can call DiskInfo with each Disk# found, and it will return info into a structure that store's information like Sector Size, sector count, name/manufacturer,readable/writeable, etc (whatever else you want really). So, now our kernel has a list of all devices it found and all the information about them that we need. It can read and/or write to each device by calling ReadSector(int DeviceIndex, int Sector, int SectorCount, void *Buffer). So, once you write an IDE/ATAPI driver, floppy driver, etc, you can now load them all in your kernel and call their specific functions to see what is available to the system. Now, I can load any driver in a similar manner, using the exact same header, and just changing info about the version, type, etc. Now, once I load all my physical devices, I have my file system drivers, each one has a function to determine if it supports a given file system based on it's first sector of the device. So, then I check for a valid MBR to see if it's got multiple partitions, if so I split it up into multiple 'drives' otherwise i treat it as one. I can then query my file system drivers to see if it supports each drive/partition. This is probably not the best method, but it has worked for me thus far, however I am probably going to redesign it a bit with removeable disks in mind, so i can notify a program when a disk is removed or whatever (not hard, Read/Write sectors can just return a specific value telling it that it doesn't exist anymore, but that's not good because i can't completely unload a driver when it's not in use, so i'm still trying to come up with a nice method for this). Anyways, that's how mine works, all my drivers have the same header, and I can easily sort or search for a loaded driver in the system by Type and/or SubType, for example, if I'm looking for an input device like a keyboard or mouse, i just query each driver with the specific type and subtypes, until i find one or more that return supported devices. In my bootloader, I actually have it load 4 'modules' on bootup, first being the kernel, 2nd is my disk driver for the specific boot media, 3rd is the file system for boot partition/media, and 4th is my memory manager driver. Once they are all loaded, it jumps to the kernel and tells it where each module is loaded, and the kernel then tells the memory manager and driver manager. Now I can easily (by replacing a 1 or 2 of these drivers on the disk) boot from any media with any supported file system. Once the base file system and device driver are loaded, it can then start searching the disk for the rest of the drivers to load. Again, it's a work in progress, and I am probably going to revamp it soon, but it works pretty nicely right now.[/code]
Post Reply