You are to write the driver that will implement the the basic UNIX file interface using the memory system. You will write code to implement the filesystem, and make several design decisions that will determine the structure and performance of the driver. In essence you will write code for the read, write, open, close and other high level filesystem functions. Each function will translate the call into low-level operations on the device (see below).
The key to this assignment if figuring out what you need to do to implement these functions. You are specifically not given guidance on how to do it. You need to (a) maintain information about current files in the file system, (b) allocate parts if the memory system to place data, (c) copy data into and out of the devices needed to serve reads and writes. How you do this is up to you, but think carefull about it before beginning to code. What is important is that the code you write will be built upon the whole semester.
You will implement your driver on top of the Lion Cloud device cluster, which is a collection of virtual storage devices that communicate over a kind of virtual bus/network connection. You will begin by powering on the bus, probing to find out how many devices are available (there are a maximum of 16), then allocating space on the devices as the application creates and writes file data to the devices. Each device is uniquely identified by is device Id (whose type is LcDeviceId) which is discovered during the probe process. Each device has a two-level addressing scheme, where it has a number of sectors (s) containing blocks (b); therefore each device has s*b total blocks. A block is a region of memory ofbytes, as declared in the (see header file.
You communicate with the devices system by sending requests and receiving responses through a set of packed registers. These registers are set within a 64-bit value to encode the opcode and arguments to the hardware device. The opcode is laid out as follows:
Bits Register ------ -------------------------------------------------- 0-3 B0 - first 4 bit register 4-7 B1 - second 4 bit register 8-15 C0 - first 8 bit register 16-23 C1 - second 8 bit register 24-31 C2 - third 8 bit register 32-47 D0 - first 16 bit register 48-63 D1 - second 16 bit register
To execute an opcode, create a 64 bit value (LCloudRegisterFrame) and pass it any needed buffers to the bus function defined in:
All messages use the following registers:
|Register||Request Value||Response Value|
|b0||0 when message sent to devices||1 when message sent from devices|
|b1||0 when sending to devices||1 is acknowledge/success from device, any other value represents failure code from device|
|c0||always the operation code (see LcOperationCode type in)||The same code as sent.|
The operation code () indicates what operation is being requested (when sending) or completed (when receiving from the device). The following operations are available:
|Operation||Description||Remaining register use|
|LC_POWER_ON||Initialize interface to the device cluster||All other registers (c1, c2, d0, d1) should be 0 on both send and receive|
|LC_DEVPROBE||Probe the bus to see what devices are||All other registers should be 0 on both send. On receive, d0 contains a bit mask of present devices, where device there are a possible 16 devices, where the bit 2^x=1 indicates that device ID x is present. For example if the 2^4 (16) is present, then you know a device with ID 4 is on the bus.|
|LC_BLOCK_XFER||Transfer a block to the device|
|LC_POWER_OFF||Power off the device||All other registers should be 0 on both send and receive|