此类的所有其余分配均基于为远程连接的云设备(称为Lion Cloud设备)创建和扩展用户空间设备驱动程序。您将编写和调试的绝大多数代码将是在虚拟设备(已提供)之上提供文件系统接口。在最高级别,您会将文件系统命令转换为设备操作(请参见下面的LC设备接口规范)。文件系统命令包括打开,读取,写入,查找,关闭和关闭写入文件系统驱动程序的文件。这些操作使用与普通UNIX I / O操作基本相同的参数执行相同的功能,但需要注意的是它们将文件内容定向到LC存储设备而不是本地主机/ OS文件系统。
注意:此作业描述提供了作业的概述。关联的幻灯片(以及课堂演示)为项目提供了更多信息,提示和指导。在完成此作业时,也请参阅这些材料。
系统和项目概述
您将要编写一个位于虚拟应用程序和虚拟化硬件设备之间的基本设备驱动程序。该应用程序利用您将提供的称为LionCloud驱动程序的抽象。该系统的设计如下图所示:
LionCloud设备是存储设备的软件模拟。它具有基本协议,可通过该协议通过一系列寄存器和数据传输区域与之通信。您将与此设备通信,并以块形式放置和获取数据。您将提供所有代码来与这些设备通信并实现简单的平面文件系统(无目录)。
下面详细介绍,我们可以看到三层。提供了lcloud_sim应用程序,它将使用基本的UNIX文件操作(打开,读取,…)调用设备驱动程序功能。您将编写设备驱动程序代码以实现文件OS操作。您的代码将通过设置寄存器并通过连接到更多虚拟云设备的虚拟总线传递数据来与虚拟设备通信。
应用程序(称为模拟器)和虚拟LionCloud设备的所有代码均已提供给您。还提供了许多实用程序功能来帮助调试和测试程序,以及创建可读的输出。样本工作量已生成,将用于广泛测试程序。使用所有这些工具(需要一些时间才能弄清楚)的学生会发现,以后的作业将变得更容易完成。
LionCloud文件系统(lcloud)
您将编写使用内存系统实现基本UNIX文件接口的驱动程序。您将编写代码来实现文件系统,并做出一些设计决定,这些决定将决定驱动程序的结构和性能。本质上,您将为读取,写入,打开,关闭和其他高级文件系统功能编写代码。每个功能会将调用转换为设备上的低级操作(请参见下文)。
您将为此任务实现的功能是: LcFHandle lcopen(const char * path); -此功能将在文件系统中打开一个文件(例如,命名路径)。如果文件不存在,则应创建该文件并将其设置为零长度。如果确实存在,则应将其打开并将其读/写位置设置为第一个字节(位置0)。请注意,文件系统中没有子目录,只有文件(因此您可以将路径视为唯一的文件名)。该函数应返回用于后续操作的唯一文件句柄;如果发生故障,则返回-1。
int lcclose(LcFHandle fh); -此函数关闭先前打开的文件句柄引用的文件。如果文件句柄不正确或文件先前未打开,则该函数应该失败(并返回-1)。
int lcread(LcFHandle fh,char * buf,size_t len); -此函数应从文件句柄在当前位置引用的文件中读取计数字节。请注意,如果文件中没有足够的字节,该函数应读取到文件末尾并返回读取的字节数。如果有足够的字节来完成读取,则该函数应返回count。如果文件句柄不正确或文件先前未打开,则该函数应该失败(并返回-1)。
int lcwrite(LcFHandle fh,char * buf,size_t len);复制代码-函数应将计数字节写入文件句柄引用的文件中。如果写入超出文件末尾,则应增加大小。函数应始终返回写入的字节数,例如count。如果文件句柄不正确或文件先前未打开,则该函数应该失败(并返回-1)。
int lcseek(LcFHandle fh,size_t off); -该函数应将文件中的当前位置设置为loc,其中0是文件中的第一个字节(loc是从文件开头开始的绝对位置)。如果loc超出文件末尾,文件句柄错误或文件先前未打开,则函数应失败(并返回-1)。
int lcshutdown(void); -该功能应关闭系统,包括关闭设备电源并关闭所有文件。 如果确定实现这些功能需要做什么,此分配的关键。具体来说,您没有得到有关如何操作的指导。您需要(a)维护有关文件系统中当前文件的信息,(b)在内存系统中放置数据的地方分配部分,(c)将数据复制到用于读取和写入所需的设备中或从其中复制数据。如何执行此操作取决于您,但是在开始编码之前请仔细考虑。重要的是,您编写的代码将在整个学期内构建
狮子云设备集群(LionCloud)
您将在Lion Cloud设备群集之上实现驱动程序,Lion Cloud设备群集是通过某种虚拟总线/网络连接进行通信的虚拟存储设备的集合。首先,打开总线电源,探查有多少可用设备(最多16个),然后在应用程序创建文件数据并将其写入设备时在设备上分配空间。每个设备由在探测过程中发现的设备ID(类型为LcDeviceId)唯一标识。每个设备都有两级寻址方案,其中有多个包含块(b)的扇区。因此,每个设备总共有s * b个块。块是LC_DEVICE_BLOCK_SIZE字节的内存区域,如在(请参阅lcloud_controller.h头文件中所声明的)声明。
您可以通过一组打包的寄存器发送请求和接收响应来与设备系统通信。这些寄存器设置在64位值内,以对硬件设备的操作码和参数进行编码。操作码的布局如下: 位寄存器 —— ——————————————– —— 0-3 B0-前4位寄存器 4-7 B1-第二个4位寄存器 8-15 C0-前8位寄存器 16-23 C1-第二个8位寄存器 24-31 C2-第三个8位寄存器 32-47 D0-前16位寄存器 48-63 D1-第二个16位寄存器 要执行操作码,请创建一个64位值(LCloudRegisterFrame),并将所有需要的缓冲区传递给cart_controller.h中定义的总线函数: LCloudRegisterFrame lcloud_io_bus(LCloudRegisterFrame frm,void * xfer); 所有消息都使用以下寄存器: 注册请求值响应值 b0 0消息发送到设备时1消息从设备发送时 b1 0当发送到设备1是来自设备的确认/成功时,其他任何值代表来自设备的失败代码 c0始终是操作代码(请参阅lcloud_controller.h中的LcOperationCode类型)与发送的代码相同。 操作码(LcOperationCode)指示正在请求(发送时)或已完成(从设备接收时)的操作。提供以下操作: 操作说明剩余寄存器使用 LC_POWER_ON初始化到设备群集的接口所有其他寄存器(c1,c2,d0,d1)在发送和接收时均应为0 LC_DEVPROBE探测总线以查看设备是什么。所有其他寄存器在两次发送时都应为0。接收时,d0包含当前设备的位掩码,其中设备可能有16个设备,其中位2 ^ x = 1表示存在设备ID x。例如,如果存在2 ^ 4(16),则说明总线上有ID为4的设备。 LC_BLOCK_XFER将块传送到设备 c1-要读取的设备的设备ID c2-用于写入的LC_XFER_WRITE,用于读取的LC_XFER_READ d0-从中读取/写入的扇区 d1-从中读取/写入的块 LC_POWER_OFF关闭设备电源所有其他寄存器在发送和接收时均应为0