Compressor: Writing the Driver
The goal is to write a driver for the compressor: use the datasheet and everything you have learned implementing the RNG drivers to do so. It is acceptable to use AI responsibly to implement the compressor driver. Once again we assume no concurrent accesses.
User-Space Interface
Your driver must expose the compressor as a single character device /dev/edu-compressor.
Sending data to compress and retrieving compressed data should be done using the ordinary open/read/write/poll system calls.
A user-space program opens the device (optionally with O_NONBLOCK) and then write()s chunks of the raw input stream to submit them for compression, and read()s back the resulting DEFLATE/zlib bytes as they become available.
Compression is asynchronous and the device’s internal buffers are finite, hence write() can legitimately accept fewer bytes than requested (or fail with EAGAIN in non-blocking mode) when the device isn’t ready for more input.
Similarly, read() can return EAGAIN or 0 bytes when no compressed output is ready yet.
This is exactly the situation poll() is meant for: the driver should report POLLOUT when another submission is legal and POLLIN when drained output is available, letting the application interleave feeding input and draining output without busy-waiting.
The driver should also expose a small set of ioctl commands:
- Reset: a command sent by a user-space application to instruct the driver to reset the device.
- Start: sent by the application to instruct the driver to start a new compression stream with a specific compression level.
- Finish: sent by the application to notify the driver that all data to compress has been sent, and that all pre-finish compressed data has been drained.
- Get statistics: sent by the application to request from the driver a data structure containing the values present in the following device registers:
REG_STATUS,REG_ERROR,REG_TOTAL_INPUT,REG_TOTAL_OUTPUT.
This user/kernel interface must use the following 🗎 kernel user-space API header file for its definition.
Please observe how the test program in shared-folder/edu-compressor-test.c uses that interface to interact with the device file /dev/edu-compressor, to further understand how your driver should expose it to user space.
Testing the Driver
Basic functionality can be assessed with a simple user-space test program present in shared-folder/edu-compressor-test.c.
This program compresses a file using the device and decompresses the result using the software zlib implementation available in the VM, to check if the decompressed content matches the original input file.
In the VM, this test program can be compiled as follows:
alpine:~/shared-folder# gcc edu-compressor-test.c -o edu-compressor-test -lz
Note the -lz flag, needed to link against the zlib library.
We can then create a text file to compress:
alpine:~/shared-folder# echo "hello hello hello hello hello hello hello hello" > hello.txt
And run the test program:
alpine:~/shared-folder# ./edu-compressor-test hello.txt hello.z hello-restored.txt
Compressed 48 bytes to 18 bytes using level 6.
Device statistics: input=48 output=18 status=0x00000021 error=0
Verification passed: 'hello.txt' and 'hello-restored.txt' are identical.
Make sure to also test with larger files, with sizes exceeding the device’s input/output buffers (32 KB), to trigger multiple rounds of transactions between the driver and the compressor hardware.