First of all, I have to thank the developers of the others filesystems supported by RTEMS (FAT, RFS, NFS, IMFS) whose source helped me a lot while developing ISO9660.
The test application
To let the operating system know that the new file-system exists, we have to fill the file-system table. The file-system table is an array of rtems_filesystem_table_t listing the supported file-systems and an entry point to initialize a new mount point. As far as I know, there is two possibility to fill this table :
- Using an RTEMS supported file-system and the associated configure macros (CONFIGURE_FILESYSTEM_XXX)
- Calling rtems_filesystem_register() (see this link)
I choose the first solution which is for me the best one since the file-system is aimed to be eventually integrated in trunk, and thus I didn't investigate the second one.
To let the magic happens I created a local version of confdefs.h included in my test application and I add ISO9660 related defines in it. That way I can develop the simple test application like a classic one except I include the hacked confdefs.h instead of the RTEMS header.
I can now write down my application, which should be able to :
- Embed a generated ISO to test a file mount
- Mount the filesystem from the QEMU emulated drive /dev/hdb or the previous ISO file untarred in the IMFS root
- Launch a shell to debug the new filesystem
I put all the ISO9660 file-system related code in a iso9660 subdirectory which could be easily moved for future integration (see SVN repository in the links).
File-system interface
The RTEMS virtual file-system API consists in a set of function pointers pointing to handlers for various operations on the file-system. The main handlers set is stored in a rtems_filesystem_operations_table. If some entries are not defined by a file-system implementation they can point to default handlers provided by the VFS which does nothing except returning the correct error code (ENOSYS in general to indicate that the function is not implemented).
While filling the file-system table I specified one of these handlers : the one called when mounting a volume with this file-system in order to initialize it (known as fsmount_me_h in the filesystem operation table).
In the ISO9660 implementation I put together all these handlers in iso9660_init.c .
This initialization handler receive two parameter, the mount table entry concerning the volume we're mounting and a unspecified data available to the user. The interesting one is the mount table entry, this is in this structure that we can store various data related to the filesystem by storing a pointer to whatever we want.
For ISO9660 the file-system information are stored in a iso9660_fs_info_t structure : type of mount (do the actual iso9660 volume is located on a block device or in a file ?), device descriptor, media block size, iso9660 volume informations (from the primary volume descriptor). Since this pointer will be accessible from almost all the others handlers it's important to store all data describing a particular mount in it.
The iso volume information are processed thanks to iso9660_init_volume_info() which determine which access layer to use to access the data on the volume. Since ISO9660 volumes can be initialized from either a file (e.g: a .iso file located on another filesystem) or a block device (e.g: a CD-ROM drive), I developed two access layers in the same manner as RFS :
- The block device layer which rely on libblock and the ATA layer to access the data. This layer has to deal with the media block size : each read operation on the device is operated at the block layer : we have to read blocks of 512 bytes.
- The device I/O layer operate directly at byte layer through open/read/close system calls, the block management is made by the filesystem containing the file we're accessing.
The file-system interface defines handlers for others various operations. At the moment the ISO9660 implementation defines the following handlers :
- evalpath : The hander have to parse a path and define the node associated with this path. The node can contain every information needed and is used among the various type handlers.
- node_type : in charge of defining the standard RTEMS node type for a particular node (e.g : file, directory, device, link, ...).
- freenode : Called when a node is destroyed to free all the structures allocated by a filesystem implementation when defining a node.
For ISO9660 each node contains the record informations associated with a given directory or file.
No comments:
Post a Comment