M6: FAT read/write filesystem server, mounted into the VFS
Add a FAT12/16/32 filesystem the VFS mounts at /mnt/usb, reading and writing a USB stick through the block device. Verified end to end under QEMU: the fat server mounts the volume, the VFS routes /mnt/usb to it, and a client lists the root and reads a file (the ELF magic of /mnt/usb/system/kernel). - engine.zig: the FAT engine over a BlockDevice interface — mount (a bare FAT or, as QEMU's VVFAT and most real sticks present it, an MBR-partitioned disk), FAT chain walk (12/16/32), cluster allocation, directory traversal with long-name read, and file read / write / create. Host-tested against a RAM-backed FAT16 image (create, cluster-spanning write, mid-file overwrite, read-back, list). - on-disk.zig: the align(1) boot-sector / directory / long-name / FSInfo structs and the cluster-count FAT-type detection. - fat.zig: the server — wraps the .block device (a DMA bounce buffer) in a BlockDevice, mounts the FAT, serves the vfs-protocol as a backend, and mounts itself into the VFS at /mnt/usb. Spawned by init as a boot service. - runtime.block: the block-device client (geometry / read / write by physical address, so whole sectors never cross IPC). - Raise the kernel service-name registry (maximum_services) 8 -> 16: it is indexed directly by ServiceId, and fat = 8 was being rejected, so the fat server exited before registering. - VFS: an absolute path with no matching mount is now not-found rather than silently created in the flat ramfs — so /mnt/usb fails cleanly until mounted. Tests: fat-mount (the full stack: block -> FAT -> VFS mount -> list + file read) passes; host units cover the engine and on-disk structs; the vfs, shutdown, and USB regression suite stays green (10/10).
This commit is contained in:
@@ -250,6 +250,8 @@ pub fn build(b: *std.Build) void {
|
||||
// The USB transfer protocol, so runtime.usb (the class-driver client) can speak
|
||||
// it, the way runtime.input speaks the input protocol.
|
||||
runtime_module.addImport("usb-transfer-protocol", usb_transfer_protocol_module);
|
||||
// The block protocol, so runtime.block (the block-device client) can speak it.
|
||||
runtime_module.addImport("block-protocol", block_protocol_module);
|
||||
|
||||
// The power protocol: system power's domain-named surface (docs/power.md).
|
||||
const power_protocol_module = b.addModule("power-protocol", .{
|
||||
@@ -392,6 +394,10 @@ pub fn build(b: *std.Build) void {
|
||||
// with Bulk-Only Transport + SCSI, and serves the block protocol under `.block`.
|
||||
const usb_storage_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "usb-storage", "system/drivers/usb-storage/usb-storage.zig");
|
||||
usb_storage_exe.root_module.addImport("block-protocol", block_protocol_module);
|
||||
// The FAT filesystem server: mounts the block device and serves it into the VFS
|
||||
// at /mnt/usb. Its engine (engine.zig / on-disk.zig) is imported relatively.
|
||||
const fat_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "fat", "system/services/fat/fat.zig");
|
||||
const fat_test_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "fat-test", "system/services/fat/fat-test.zig");
|
||||
const pci_bus_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "pci-bus", "system/drivers/pci-bus/pci-bus.zig");
|
||||
// The PCI bus driver decodes each function's class triple to human names in its
|
||||
// boot log (class/subclass/prog-IF), so pull in the shared pci-class reference.
|
||||
@@ -453,6 +459,10 @@ pub fn build(b: *std.Build) void {
|
||||
mk_run.addFileArg(usb_hid_mouse_exe.getEmittedBin());
|
||||
mk_run.addArg("usb-storage");
|
||||
mk_run.addFileArg(usb_storage_exe.getEmittedBin());
|
||||
mk_run.addArg("fat");
|
||||
mk_run.addFileArg(fat_exe.getEmittedBin());
|
||||
mk_run.addArg("fat-test");
|
||||
mk_run.addFileArg(fat_test_exe.getEmittedBin());
|
||||
mk_run.addArg("pci-bus");
|
||||
mk_run.addFileArg(pci_bus_exe.getEmittedBin());
|
||||
mk_run.addArg("crash-test");
|
||||
@@ -487,6 +497,7 @@ pub fn build(b: *std.Build) void {
|
||||
.{ usb_hid_keyboard_exe, "system/drivers" },
|
||||
.{ usb_hid_mouse_exe, "system/drivers" },
|
||||
.{ usb_storage_exe, "system/drivers" },
|
||||
.{ fat_exe, "system/services" },
|
||||
}) |entry| {
|
||||
const step = b.addInstallArtifact(entry[0], .{ .dest_dir = .{ .override = .{ .custom = entry[1] } } });
|
||||
b.getInstallStep().dependOn(&step.step);
|
||||
@@ -640,6 +651,8 @@ pub fn build(b: *std.Build) void {
|
||||
"system/drivers/usb-storage/scsi.zig", // SCSI CDB encodings (big-endian)
|
||||
"system/services/vfs/path.zig", // mount-prefix path matching
|
||||
"system/services/vfs/protocol.zig", // NodeKind / DirectoryEntry sizes + op values
|
||||
"system/services/fat/on-disk.zig", // FAT on-disk struct sizes + type detection
|
||||
"system/services/fat/engine.zig", // FAT read/write over a RAM-backed image
|
||||
}) |root| {
|
||||
const mod_tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
|
||||
Reference in New Issue
Block a user