//! system/services/fat/fat-test — a client that proves the FAT mount end to end: //! it waits for the fat server to mount the USB volume at /mnt/usb, lists the //! root directory through the VFS (which routes /mnt/usb to the fat backend), and //! reads a known file off it. Shipped in the initial_ramdisk; the `fat-mount` //! kernel test spawns it alongside init. const std = @import("std"); const runtime = @import("runtime"); fn writeLine(comptime fmt: []const u8, arguments: anytype) void { var line: [128]u8 = undefined; _ = runtime.system.write(std.fmt.bufPrint(&line, fmt, arguments) catch return); } pub fn main(init: runtime.process.Init) void { _ = init; const unistd = @import("posix").unistd; // Wait for /mnt/usb to be mounted — the fat server races us at boot (it must // bring up the whole USB storage chain first). var dir: i32 = -1; var tries: u32 = 0; while (dir < 0 and tries < 1400) : (tries += 1) { dir = unistd.opendir("/mnt/usb"); if (dir < 0) runtime.system.sleep(50); } if (dir < 0) { _ = runtime.system.write("fat-test: /mnt/usb never became available\n"); return; } var count: u32 = 0; var entry: unistd.DirEntry = .{}; while (unistd.readdir(dir, &entry)) { writeLine("fat-test: entry '{s}' kind={d} size={d}\n", .{ entry.name(), entry.kind, entry.size }); count += 1; if (count > 32) break; } unistd.closedir(dir); writeLine("fat-test: listed {d} entries\n", .{count}); // Read a known file off the boot volume through the mount (best effort): the // kernel image is an ELF, so its first bytes are the ELF magic. const fd = unistd.open("/mnt/usb/system/kernel", 0); if (fd >= 0) { var magic: [4]u8 = undefined; const n = unistd.read(fd, &magic); unistd.close(fd); if (n == 4 and magic[0] == 0x7F and magic[1] == 'E' and magic[2] == 'L' and magic[3] == 'F') { _ = runtime.system.write("fat-test: read /mnt/usb/system/kernel ELF magic ok\n"); } else { writeLine("fat-test: /mnt/usb/system/kernel read {d} bytes (not ELF magic)\n", .{n}); } } if (count > 0) { while (true) { _ = runtime.system.write("fat-test: ok\n"); runtime.system.sleep(1000); } } _ = runtime.system.write("fat-test: root listing was empty\n"); } pub const panic = runtime.panic; comptime { _ = &runtime.start._start; }