A protocol is now defined through envelope.Define rather than beside it.
Every packet begins with the same 16-byte prefix: a Header of {operation,
target} for a request or event, a Status for a reply. The header is folded
into each protocol's own layout, never stacked on top of it — Define walks
a spec's types and refuses one that carries a Header or Status field, so
the rule cannot be missed by reading. Operations number from 16, leaving
describe, enumerate, subscribe and unsubscribe reserved and answerable the
same way everywhere; describe the envelope answers itself, and an unknown
verb is -ENOSYS without a provider writing a line.
The size floor becomes something protocols can compile against: 256 bytes
for a call, 64 for a push, matching the kernel's own limits, checked at the
Define call with the prefix counted in. A protocol that outgrows either
fails the build with the reason and the remedy — shrink, or move the bulk
to shared memory, because packets never fragment. Events carry the header
too and number in their own space, so appending an operation can never
renumber a shipped event.
Beside it, the client half of the model: a Channel is what opening a
/protocol name yields, wrapping the endpoint capability so a program holds
a conversation rather than a handle. Nothing speaks through either yet —
the vfs protocol gains NodeKind.protocol and the convention that an open
reply may carry a capability, and that is the whole runtime change.
Suite 107/107, unchanged: P1 converts nothing.
55 lines
2.9 KiB
Zig
55 lines
2.9 KiB
Zig
//! The "protocol" library domain: the wire protocols — each service's public
|
|
//! interface, exposed as its own module (docs/driver-model.md). Both sides of
|
|
//! every conversation depend on the contract by name; neither reaches into the
|
|
//! other's files. Pure flat wire types: no protocol module imports anything.
|
|
//!
|
|
//! One module here is not a protocol but the shape the others are written in:
|
|
//!
|
|
//! envelope : the packet prefix + comptime Define (docs/os-development/protocol-namespace.md)
|
|
//!
|
|
//! vfs-protocol : the VFS server <-> the file layer (unistd/stdio)
|
|
//! input-protocol : the input fan-out service <-> sources + subscribers
|
|
//! block-protocol : a filesystem <-> a block driver (usb-storage)
|
|
//! usb-transfer-protocol : a USB class driver <-> the xHCI bus driver
|
|
//! device-manager-protocol : the device manager <-> drivers + discovery
|
|
//! display-protocol : the compositor's client-facing surface
|
|
//! scanout-protocol : the compositor -> a native scanout driver (docs/display-v2.md)
|
|
//! power-protocol : system power's domain-named surface (docs/power.md)
|
|
|
|
const std = @import("std");
|
|
|
|
pub fn build(b: *std.Build) void {
|
|
for ([_]struct { name: []const u8, root: []const u8 }{
|
|
// Not a protocol, hence not `-protocol`: the envelope is what a
|
|
// protocol is defined *through*.
|
|
.{ .name = "envelope", .root = "envelope/envelope.zig" },
|
|
.{ .name = "vfs-protocol", .root = "vfs/vfs-protocol.zig" },
|
|
.{ .name = "input-protocol", .root = "input/input-protocol.zig" },
|
|
.{ .name = "block-protocol", .root = "block/block-protocol.zig" },
|
|
.{ .name = "usb-transfer-protocol", .root = "usb-transfer/usb-transfer-protocol.zig" },
|
|
.{ .name = "device-manager-protocol", .root = "device-manager/device-manager-protocol.zig" },
|
|
.{ .name = "display-protocol", .root = "display/display-protocol.zig" },
|
|
.{ .name = "scanout-protocol", .root = "scanout/scanout-protocol.zig" },
|
|
.{ .name = "power-protocol", .root = "power/power-protocol.zig" },
|
|
}) |protocol| {
|
|
_ = b.addModule(protocol.name, .{ .root_source_file = b.path(protocol.root) });
|
|
}
|
|
|
|
// Standalone `zig build test` for this domain alone; the root build keeps
|
|
// its aggregate test step.
|
|
const test_step = b.step("test", "Run the protocol unit tests");
|
|
for ([_][]const u8{
|
|
"envelope/envelope.zig", // framing round trips, verb numbering, dispatch, the floors
|
|
"vfs/vfs-protocol.zig", // NodeKind / DirectoryEntry sizes + op values
|
|
"display/display-protocol.zig", // pack(): native pixel encoding per format
|
|
}) |root| {
|
|
const protocol_tests = b.addTest(.{
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path(root),
|
|
.target = b.resolveTargetQuery(.{}),
|
|
}),
|
|
});
|
|
test_step.dependOn(&b.addRunArtifact(protocol_tests).step);
|
|
}
|
|
}
|