Linux Kernel & Device Driver Programming: Assignments ↑

Programming Assignment #2
Extending scull, a char pseudo-device

 

Value:       (See the Grading section of the Syllabus.)

Due Date and Time:       (See the Course Calendar.)

Summary:

This is your first exercise that involves writing and debugging code. You will just be modifying the code provided by the textbook author for the char pseudo-device scull, to provide a new type of minor device. The new type of minor device will implement a LIFO (stack) structure. This will not require changing most of the existing code, but I hope you will take the opportunity to look it all over and understand it.

Please take care to read the specifications and follow them. This is not the first time some kind of LIFO device was assigned in this course, but the specifications have been changed. If you ask for help from a student who took this course before, and do what that students tells you instad of paying attention to the current assignment, you will probably get it wrong.

Objectives:

Tasks:

  1. Get a copy of the source code of all the sample programs provided with the textbook. A copy of the tarfile is posted on the course website ( examples.tar.gz). Get a copy of the examples tar-file onto your machine, unzip un-tar it, and go into the scull subdirectory. You can work in this copy of the source directory, or make a scratch copy in another location to do the rest of the assignment.

  2. (optional) It is a good time to get started practicing source code version control. By the time you get to the final project, where you are working in a group, you will really need some kind of version control. There are several tools you can use. One is rcs, and another is cvs. CVS is built on top of rcs, and provides additional functionality. One advantage of cvs over rcs is that you can easily backup your files on a remote machine over ssh. Its not as complicated as it may first seem, and the effort to learn cvs will be well worth it.

  3. If you are using rcs to keep track of your changes, make a subdirectory named RCS and use the ci command to check in the baseline versions of all the source files. Then use the ci -l command to check out writeable copies of all the files. This will make it easier later to see what you have changed, using rcsdiff. If you periodically check in, and then check back out again, your source files you will have a backup copy of your most recent version and a history of all your changes.

    For CVS, see the CVS instructions in a separate file.

  4. Using the provided Makefile, compile the unmodified version of scull as it comes from the text, and run through the tests described under "Playing with the New Devices" on page 70 of the text.

  5. Modify scull to add a new type of device, that implements a LIFO. The new code should retain all the functionality and minor device numbers of the old scull, with one new added device number for the LIFO type. Use the next available unused minor number.

  6. Base your device on the existing scull pipe device. It should retain the same basic data structure, and the same blocking behavior when a process tries to read from an empty device or write to a full device. The difference is that you will only need one pointer since the LIFO read and write actions will all be at the same end of the storage.

  7. The read operation should return the number of requested bytes from the top of the LIFO, reversing the character order as it does so. It should return as many characters as requested, up to the maximum that are in the LIFO. That is, if there were two writes to the LIFO, of "abcde" and "fgh", followed by a read of 5 characters, the value 5 should be returned and the string "hgfed" should be copied to the user's buffer. If the next read requested 5 more characters, the value 3 should be returned and the string "cba" should be copied to the user's buffer. In the absence of more writes, any subsequent blocking read should block until more data is placed into the buffer, and a nonblocking read should return immediately with the standard behavior specified for read with O_NONBLOCK when data is not immediately available (see the man-page).

  8. The write operation should append the string to the end of the LIFO. If the number of bytes provided by the call is more than will fit into the LIFO, the call should write as much as will fit, and then block until there is more space. It should repeat this writing and blocking until the entire string is written, before returning. Note that this is different from the write operation semantics for the existing pipe module.

  9. There should be just one IOCTL operation, and it should have the effect of emptying the LIFO.

  10. You should retain the other functionality of the pipe, including the ability of a LIFO to be shared between processes, except that the open() operation on an existing LIFO should not destroy the content (whereas it does destroy the content of a scull pipe).

  11. As any other design questions come up, for which the precise behavior is not specified here, you may either resolve them according to your best engineering judgement, or discuss them with me.

  12. Test and debug your modified code. You should devise your own tests, to check that the specification above are satisfied. You may be able to do some of the testing using shell scripts, for example using cp, dd, and I/O redirection, as suggested in the text. However, you should really write one or more C test programs, using the direct calls to read, write, etc.

  13. Please have your tests ready to go when you demonstrate your work. (No editing and debugging of tests in real time while I watch!)

Advice:

References:

Delivery Method:

  1. Turn in the following, as hard copy, in class on the due date:

    • Copies of the files that you modified, with the parts you modified pointed out in some clear way (e.g. marked colored highlighter).
    • Copies of test scripts and/or programs you used.
  2. Also e-mail me the electronic copies of the above. For simplicity, I would prefer that everyone send me a uuencoded gzipped tarfile. If your code is in directory prog2, you can do this on a Linux machine that supports mail (e.g., quake) as follows:

    tar cvpf - prog2 | gzip -c | uuencode prog2.tgz | mail -s "prog2" baker@cs.fsu.edu

    This uses tar to create an archive, which it pipes for compression to gzip, which pipes the compressed file to uuencode for conversion to ASCII characters, which pipes it to mail.

    The code above worked fine on websrv, and I expect it should work equally well on quake but if you are mailing from a Solaris machine (Are they finally all phased out of this deparment?) you will either need to leave out the -S "prog2" argument to mail, or use mailx instead. You may also need another argument for uuencode.

    The electronic copy can be later than the hard copy. I would prefer work from the hard copy and the demo for evaluation purposes. (I mainly want the electronic copy for archival purposes, including accreditation. The outside reviewers always ask for copies of student work in each course.)

  3. Sign up of a time slot to demonstrate your code to the instructor.

Assessment:

If you do everything that is required and explain it adequately at the demonstration you will receive a perfect score. Deductions will be made for skipped steps, steps done incorrectly, or inability to explain. Pay attention to the quality of the tests that you prepare for the demonstration.

During the demonstration, I will be looking to verify that you can demonstrate tests for all the required functionality. I will be looking for answers to the following questions:

© 2003, 2004, 2005, 2006 T. P. Baker. ($Id: prog2.html,v 1.1 2008/04/28 17:57:51 baker Exp baker $)