Due May 4, 2012 at 12:00 pm, 60 pts.
For this project, you'll implement a fifo character device as a loadable
kernel module. A fifo is a device which can store a finite number of
characters, in our case 32 (defined by
returning them in the order in which they were written. Of course, more
than 32 characters can be written to the fifo, but it can only store 32 at
a time. Note that reads ``drain'' the fifo.
The fifo you implement will have several processing modes, settable by invoking ioctls. There are two input modes:
STOP: Writes to the fifo will not overwrite unread data in the fifo.
OVERWRITE: Writes to the fifo will overwrite unread data.
WHISPER: All uppercase letters should be converted to lowercase.
NORMAL: Perform no character processing.
SHOUT: All lowercase letters should be converted to uppercase.
Refer to Section 7.1 of The Linux Kernel Module Programming Guide
fifodev.h(see the course web site) as is, to ensure interoperability. Your module is expected to interoperate with
testFifo.c(see the course web site) as is.
fifodev.h, you should implement the following ioctls:
IOCTL_SET_IMODE, which takes
OVERWRITEas a parameter and returns nothing.
IOCTL_SET_PMODE, which takes
SHOUTas a parameter and returns nothing.
IOCTL_WRITE_FIFO, which takes a pointer to a
buffer_descriptoras a parameter and returns the number of characters written to the fifo from the buffer. In
STOPmode, the return value should be the actual number of characters written to the fifo. In
OVERWRITEmode, the return value should be the length provided in the
buffer_descriptor, assuming no errors occur. The current processing mode should be applied to all characters written to the fifo.
IOCTL_READ_FIFO, which takes a pointer to a
buffer_descriptoras a parameter and returns the number of characters read from the fifo to the buffer. Obviously, the return value can be no greater than
buffer_descriptoris a type defined in
fifodev.hfor interfacing with the two read/write ioctls. As described in
fifodev.h, it is a struct consisting of the starting address of a character buffer and the buffer's length in characters.
NORMALmodes. Neither open nor close operations should affect fifo state, other than to ensure that at most one process can access the fifo at a time.
fifo_dev. Refer to the comments at the head of
buffer_descriptorfrom user address space to kernel address space will require using
copy_from_user(). You would be wise to check the value returned by this function.
put_user(). Writing a character from the buffer to the fifo will require using
get_user(). You would be wise to check the values returned by these functions.
testFifo.cfor an incomplete fifo device test suite. You can refer to this for examples of how to invoke the
IMODEioctls. I will be testing your modules against a stronger version of this test suite, so it would be to your advantage to think hard about what tests are missing and add them to the test suite I've given you. If you torture your module prior to turning it in, it's more likely to survive the torture to which I'm sure to subject it.
STOPmodes. You can then test the fifo using the shell:
% echo "aBc" > fifo_dev % echo "123 > fifo_dev % cat fifo_dev aBc 123 %Note that
echoappends a newline character. Therefore, each of the
echos above writes four characters to the fifo. If you don't want the trailing newline, use
% echo -n "aBc" > fifo_dev % echo "123 > fifo_dev % cat fifo_dev aBc123 %Note that the
echo -nabove wrote just three characters to the fifo.
OVERWRITEmode this way:
int file = open(DEVICE_FILE_NAME, O_RDWR); ioctl(file, IOCTL_SET_IMODE, OVERWRITE); close(file);It would be wise to assert that
file >= 0before using
filefollowing the call to
Once you've passed all your tests from the shell, move on to using
printk()s to monitor module operation, gating them with
#ifdef DEBUGpreprocessor directives:
/* Uncomment the following #define to enable debugging messages. */ /* #define DEBUG */ ... #ifdef DEBUG printk(KERN_INFO, "Time for ice cream.\n"); #endifNote that preprocessor directives should begin in the first column of a line, whereas the code affected by the directives is expected to be indented normally.
Email your module source file and any other relevant source file(s) to
kelliher[at]goucher.edu by 12:00 pm on the 4th. Please note that
this is a hard deadline.