system+init+memory: Add basic IPC code
This commit is contained in:
parent
f7ed375e8e
commit
f41ad7e747
@ -3,9 +3,9 @@ const system = @import("system");
|
|||||||
const vm = system.vm;
|
const vm = system.vm;
|
||||||
const syscalls = system.syscalls;
|
const syscalls = system.syscalls;
|
||||||
const buffer = system.ring_buffer;
|
const buffer = system.ring_buffer;
|
||||||
|
const heap = system.heap;
|
||||||
|
|
||||||
// FIXME: Make arch-specific.
|
const PAGE_SIZE = vm.PAGE_SIZE;
|
||||||
const PAGE_SIZE = 4096;
|
|
||||||
|
|
||||||
fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer {
|
fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer {
|
||||||
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
||||||
@ -33,6 +33,44 @@ fn discoverThreadLimit() u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setupKernelRingBufferForThread(mapper: *const vm.MemoryMapper, pid: u64, virt: u64) !void {
|
||||||
|
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
||||||
|
|
||||||
|
try vm.map(mapper, virt, phys, @intFromEnum(vm.Flags.User) | @intFromEnum(vm.Flags.ReadWrite) | @intFromEnum(vm.Flags.NoExecute));
|
||||||
|
|
||||||
|
try syscalls.setEventQueue(pid, phys.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setupRingBufferForThread(mapper: *const vm.MemoryMapper, base: u64, virt: u64) !buffer.RingBuffer {
|
||||||
|
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
||||||
|
|
||||||
|
try vm.map(mapper, virt, phys, @intFromEnum(vm.Flags.User) | @intFromEnum(vm.Flags.ReadWrite) | @intFromEnum(vm.Flags.NoExecute));
|
||||||
|
|
||||||
|
const data: [*]u8 = @ptrCast(phys.virtualPointer(u8, base));
|
||||||
|
|
||||||
|
return buffer.RingBuffer.init(data, PAGE_SIZE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setupThread(pid: u64, base: u64) !system.ipc.Connection {
|
||||||
|
const space = try syscalls.getAddressSpace(pid);
|
||||||
|
const mapper = vm.MemoryMapper.create(.{ .address = space }, base);
|
||||||
|
|
||||||
|
const ipc_base = 0x1000; // FIXME: Find a good place in the address space and guarantee this is free.
|
||||||
|
|
||||||
|
try setupKernelRingBufferForThread(&mapper, pid, ipc_base + system.ipc.KERNEL_BUFFER_ADDRESS_OFFSET);
|
||||||
|
// INIT_WRITE and INIT_READ are inverted here because when the process writes, init reads.
|
||||||
|
const read_buffer = try setupRingBufferForThread(&mapper, base, ipc_base + system.ipc.INIT_WRITE_BUFFER_ADDRESS_OFFSET);
|
||||||
|
const write_buffer = try setupRingBufferForThread(&mapper, base, ipc_base + system.ipc.INIT_READ_BUFFER_ADDRESS_OFFSET);
|
||||||
|
|
||||||
|
const connection: system.ipc.Connection = .{ .pid = pid, .read_buffer = read_buffer, .write_buffer = write_buffer };
|
||||||
|
|
||||||
|
try syscalls.setThreadArguments(pid, base, ipc_base);
|
||||||
|
|
||||||
|
try syscalls.startThread(pid);
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
export fn _start(base: u64, address: u64) callconv(.C) noreturn {
|
export fn _start(base: u64, address: u64) callconv(.C) noreturn {
|
||||||
setTokens();
|
setTokens();
|
||||||
|
|
||||||
@ -42,15 +80,25 @@ export fn _start(base: u64, address: u64) callconv(.C) noreturn {
|
|||||||
const threads = discoverThreadLimit();
|
const threads = discoverThreadLimit();
|
||||||
syscalls.print(threads);
|
syscalls.print(threads);
|
||||||
|
|
||||||
|
const pid: u64 = 2;
|
||||||
|
var connection = setupThread(pid, base) catch {
|
||||||
|
while (true) {}
|
||||||
|
};
|
||||||
|
|
||||||
const event_queue = setupKernelRingBuffer(base) catch {
|
const event_queue = setupKernelRingBuffer(base) catch {
|
||||||
while (true) {}
|
while (true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = event_queue;
|
system.ipc.setKernelBuffer(event_queue);
|
||||||
|
|
||||||
var counter: u64 = 0;
|
var counter: u64 = 0;
|
||||||
|
|
||||||
while (true) : (counter += 4) {
|
while (true) : (counter += 4) {
|
||||||
|
var data: u8 = undefined;
|
||||||
|
if (connection.read_buffer.read(@ptrCast(&data), 1)) {
|
||||||
|
syscalls.print(data);
|
||||||
|
}
|
||||||
|
|
||||||
syscalls.sleep(1000);
|
syscalls.sleep(1000);
|
||||||
syscalls.print(counter);
|
syscalls.print(counter);
|
||||||
}
|
}
|
||||||
|
38
system/lib/ipc.zig
Normal file
38
system/lib/ipc.zig
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const buffer = @import("ring_buffer.zig");
|
||||||
|
const vm = @import("arch/vm.zig");
|
||||||
|
|
||||||
|
pub const Connection = struct {
|
||||||
|
pid: u64,
|
||||||
|
read_buffer: buffer.RingBuffer,
|
||||||
|
write_buffer: buffer.RingBuffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const KERNEL_BUFFER_ADDRESS_OFFSET = 0x0000;
|
||||||
|
pub const INIT_WRITE_BUFFER_ADDRESS_OFFSET = 0x1000;
|
||||||
|
pub const INIT_READ_BUFFER_ADDRESS_OFFSET = 0x2000;
|
||||||
|
|
||||||
|
var kernel_buffer: ?buffer.RingBuffer = null;
|
||||||
|
|
||||||
|
pub fn setKernelBuffer(buf: buffer.RingBuffer) void {
|
||||||
|
kernel_buffer = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getKernelBuffer() ?buffer.RingBuffer {
|
||||||
|
return kernel_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PAGE_SIZE = vm.PAGE_SIZE;
|
||||||
|
|
||||||
|
fn createPageBufferFromAddress(address: u64) buffer.RingBuffer {
|
||||||
|
const data: [*]u8 = @ptrFromInt(address);
|
||||||
|
|
||||||
|
return buffer.RingBuffer.init(data, PAGE_SIZE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readInitBuffers(base_address: u64) Connection {
|
||||||
|
kernel_buffer = createPageBufferFromAddress(base_address + KERNEL_BUFFER_ADDRESS_OFFSET);
|
||||||
|
const read_buffer = createPageBufferFromAddress(base_address + INIT_READ_BUFFER_ADDRESS_OFFSET);
|
||||||
|
const write_buffer = createPageBufferFromAddress(base_address + INIT_WRITE_BUFFER_ADDRESS_OFFSET);
|
||||||
|
|
||||||
|
return .{ .pid = 0, .read_buffer = read_buffer, .write_buffer = write_buffer };
|
||||||
|
}
|
@ -2,4 +2,5 @@ pub const kernel = @import("kernel.zig");
|
|||||||
pub const ring_buffer = @import("ring_buffer.zig");
|
pub const ring_buffer = @import("ring_buffer.zig");
|
||||||
pub const syscalls = @import("syscalls.zig");
|
pub const syscalls = @import("syscalls.zig");
|
||||||
pub const vm = @import("arch/vm.zig");
|
pub const vm = @import("arch/vm.zig");
|
||||||
|
pub const ipc = @import("ipc.zig");
|
||||||
pub const heap = @import("heap.zig");
|
pub const heap = @import("heap.zig");
|
||||||
|
@ -9,8 +9,15 @@ fn setTokens() void {
|
|||||||
syscalls.setTokens(syscalls.getThreadId(), tokens) catch {};
|
syscalls.setTokens(syscalls.getThreadId(), tokens) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn _start(_: u64, _: u64) callconv(.C) noreturn {
|
export fn _start(_: u64, ipc_base: u64) callconv(.C) noreturn {
|
||||||
setTokens();
|
setTokens();
|
||||||
|
|
||||||
|
var connection = system.ipc.readInitBuffers(ipc_base);
|
||||||
|
|
||||||
|
const byte: u8 = 127;
|
||||||
|
|
||||||
|
_ = connection.write_buffer.write(@ptrCast(&byte), 1);
|
||||||
|
syscalls.yield();
|
||||||
|
|
||||||
while (true) {}
|
while (true) {}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user