From 40b81df753d2426f37f35d7aa3c1dcea82777e74 Mon Sep 17 00:00:00 2001 From: Linuxperoxo Date: Sun, 29 Mar 2026 22:31:06 -0300 Subject: [PATCH 1/2] feat: kparam --- kernel/kernel.zig | 3 +- kernel/kparam/allocator.zig | 12 ++++++++ kernel/kparam/kparam.zig | 27 ++++++++++++++++++ kernel/kparam/parser.zig | 10 +++++++ kernel/kparam/types.zig | 28 +++++++++++++++++++ .../kernel/utils/hashtable/hashtable.zig | 22 +++++++++------ lib/saturn/kernel/utils/utils.zig | 1 + saturn.zig | 1 + 8 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 kernel/kparam/allocator.zig create mode 100644 kernel/kparam/kparam.zig create mode 100644 kernel/kparam/parser.zig create mode 100644 kernel/kparam/types.zig diff --git a/kernel/kernel.zig b/kernel/kernel.zig index 55ab970..ab926a5 100644 --- a/kernel/kernel.zig +++ b/kernel/kernel.zig @@ -15,6 +15,7 @@ pub const config: type = saturn.config; pub const modules: type = saturn.modules; pub const decls: type = saturn.decls; pub const fusioners: type = saturn.fusioners; +pub const kparam: type = saturn.kparam; pub const codes: type = saturn.codes; pub const modsys: type = struct { const core: type = saturn.modsys.core; @@ -54,7 +55,7 @@ comptime { _ = csl; // carregado c sources } -fn saturn_main() callconv(.c) noreturn { +fn saturn_main(kparams: []const u8) callconv(.c) noreturn { // Aqui existe um pequeno detalhe, bem interessante por sinal. // Quando passamos um ponteiro para uma funcao conhecida em tempo // de compilacao para o @call, o compilador precisa considerar que diff --git a/kernel/kparam/allocator.zig b/kernel/kparam/allocator.zig new file mode 100644 index 0000000..3502d83 --- /dev/null +++ b/kernel/kparam/allocator.zig @@ -0,0 +1,12 @@ +// ┌─────────────────────────────────────────────────┐ +// │ (c) 2026 Linuxperoxo • FILE: allocator.zig │ +// │ Author: Linuxperoxo │ +// └─────────────────────────────────────────────────┘ + +const buildByteAllocator = @import("root").lib.memory.sba.buildByteAllocator; + +pub const sba: type = struct { + pub var allocator = buildByteAllocator(null, .{ + .resize = true, + }) {}; +}; diff --git a/kernel/kparam/kparam.zig b/kernel/kparam/kparam.zig new file mode 100644 index 0000000..af85f2a --- /dev/null +++ b/kernel/kparam/kparam.zig @@ -0,0 +1,27 @@ +// ┌──────────────────────────────────────────────┐ +// │ (c) 2026 Linuxperoxo • FILE: kparam.zig │ +// │ Author: Linuxperoxo │ +// └──────────────────────────────────────────────┘ + +const types: type = @import("types.zig"); +const parser: type = @import("parser.zig"); +const allocator: type = @import("allocator.zig"); + +var sys_param: types.Params_T = .{}; + +pub noinline fn params_loader(params: []const u8) void { + const parsed_params: []const types.Param_T = parser.params_parser(params); + for(0..parsed_params.len) |i| { + sys_param.add(parsed_params[i].param, parsed_params[i].value, &allocator.sba.allocator) catch |err| { + _ = err; + // KLOG() + }; + } +} + +pub noinline fn params_search(param: []const u8) types.KParamErr_T!types.Value_T { + return sys_param.search(param) catch |err| switch(err) { + types.Params_T.Err_T.AllocatorFailed => types.KParamErr_T.AllocatorInternalError, + else => types.KParamErr_T.SysParamNotFound, + }; +} diff --git a/kernel/kparam/parser.zig b/kernel/kparam/parser.zig new file mode 100644 index 0000000..ec0d434 --- /dev/null +++ b/kernel/kparam/parser.zig @@ -0,0 +1,10 @@ +// ┌──────────────────────────────────────────────┐ +// │ (c) 2026 Linuxperoxo • FILE: parser.zig │ +// │ Author: Linuxperoxo │ +// └──────────────────────────────────────────────┘ + +const types: type = @import("types.zig"); + +pub inline fn params_parser(params: []const u8) []const types.Param_T { + +} diff --git a/kernel/kparam/types.zig b/kernel/kparam/types.zig new file mode 100644 index 0000000..8345eb6 --- /dev/null +++ b/kernel/kparam/types.zig @@ -0,0 +1,28 @@ +// ┌─────────────────────────────────────────────┐ +// │ (c) 2026 Linuxperoxo • FILE: types.zig │ +// │ Author: Linuxperoxo │ +// └─────────────────────────────────────────────┘ + +const hashtable: type = @import("root").lib.utils.hashtable; + +pub const KParamErr_T: type = error { + SysParamNotFound, + AllocatorInternalError, +}; + +pub const Params_T: type = hashtable.buildHashTable( + []const u8, + Value_T, + 8, + null +); + +pub const Value_T: type = enum(u1) { + yes = 1, + no = 0, +}; + +pub const Param_T: type = struct { + param: []const u8, + value: Value_T, +}; diff --git a/lib/saturn/kernel/utils/hashtable/hashtable.zig b/lib/saturn/kernel/utils/hashtable/hashtable.zig index 926179c..1b00459 100644 --- a/lib/saturn/kernel/utils/hashtable/hashtable.zig +++ b/lib/saturn/kernel/utils/hashtable/hashtable.zig @@ -68,7 +68,7 @@ pub fn buildHashTable( KeyNotFound, }; - table: [table_size orelse 24]ListHead_T = [_]ListHead_T { + table: [table_size orelse 16]ListHead_T = [_]ListHead_T { ListHead_T { .first = null, .last = null, @@ -194,7 +194,7 @@ pub fn buildHashTable( }; } -test "Add" { +test "String Test" { const std: type = @import("std"); const HashTable_T: type = buildHashTable([]const u8, bool, null, null); var gpa = std.heap.GeneralPurposeAllocator(.{}) {}; @@ -204,13 +204,19 @@ test "Add" { try hashtable.add("tty_output_buffer", true, &allocator); try hashtable.add("tty_input_buffer", false, &allocator); - std.debug.print("{any}\n{any}\n", .{ - try hashtable.search("tty_output_buffer"), - try hashtable.search("tty_input_buffer"), - }); + var found: bool = undefined; + + found = try hashtable.search("tty_output_buffer"); + if(found != true) + return error.InvalidData; + + found = try hashtable.search("tty_input_buffer"); + if(found != false) + return error.InvalidData; try hashtable.del("tty_output_buffer", &allocator); + try hashtable.del("tty_input_buffer", &allocator); - //_ = try hashtable.search("tty_output_buffer"); - _ = try hashtable.search("tty_input_buffer"); + if(hashtable.search("tty_output_buffer")) |_| return error.FoundDel else |_| {} + if(hashtable.search("tty_input_buffer")) |_| return error.FoundDel else |_| {} } diff --git a/lib/saturn/kernel/utils/utils.zig b/lib/saturn/kernel/utils/utils.zig index dbbaebc..2eccd74 100644 --- a/lib/saturn/kernel/utils/utils.zig +++ b/lib/saturn/kernel/utils/utils.zig @@ -7,5 +7,6 @@ pub const mem: type = @import("mem/mem.zig"); pub const fmt: type = @import("fmt/fmt.zig"); pub const list: type = @import("list/list.zig"); pub const tree: type = @import("tree/tree.zig"); +pub const hashtable: type = @import("hashtable/hashtable.zig"); pub const c: type = @import("c/c.zig"); pub const compile: type = @import("comptime/comptime.zig"); diff --git a/saturn.zig b/saturn.zig index e60146c..fb6b300 100644 --- a/saturn.zig +++ b/saturn.zig @@ -16,6 +16,7 @@ pub const decls: type = @import("kernel/decls.zig"); pub const ar: type = @import("kernel/ar/ar.zig"); pub const asl: type = @import("kernel/asl/asl.zig"); pub const csl: type = @import("kernel/csl/csl.zig"); +pub const kparam: type = @import("kernel/kparam/kparam.zig"); pub const codes: type = @import("codes.zig"); pub const core: type = struct { From a90f5b6a8732b5299f1d6345497ada1534c28c22 Mon Sep 17 00:00:00 2001 From: Linuxperoxo Date: Wed, 1 Apr 2026 21:38:38 -0300 Subject: [PATCH 2/2] feat: kparam parser --- config/kernel/options.zig | 3 ++ kernel/kernel.zig | 27 ++++++------ kernel/kparam/kparam.zig | 20 +++++---- kernel/kparam/parser.zig | 87 ++++++++++++++++++++++++++++++++++++++- kernel/kparam/types.zig | 4 ++ 5 files changed, 121 insertions(+), 20 deletions(-) diff --git a/config/kernel/options.zig b/config/kernel/options.zig index 520fd18..a341f9b 100644 --- a/config/kernel/options.zig +++ b/config/kernel/options.zig @@ -11,3 +11,6 @@ pub const keyboard_event: types.EventDefaultInstall_T = .{ .bus = 0, .line = 7, pub const mouse_event: types.EventDefaultInstall_T = .{ .bus = 1, .line = 7, .who = 32 }; pub const csi_event: types.EventDefaultInstall_T = .{ .bus = 2, .line = 7, .who = 64}; pub const timer_event: types.EventDefaultInstall_T = .{ .bus = 3, .line = 7, .who = 128}; +pub const kparam_enable: bool = true; +pub const kparam_dynamic: bool = false; +pub const kparam_config_file: ?[]const u8 = null; // default ".kparam.config"; diff --git a/kernel/kernel.zig b/kernel/kernel.zig index ab926a5..0c05080 100644 --- a/kernel/kernel.zig +++ b/kernel/kernel.zig @@ -15,12 +15,15 @@ pub const config: type = saturn.config; pub const modules: type = saturn.modules; pub const decls: type = saturn.decls; pub const fusioners: type = saturn.fusioners; -pub const kparam: type = saturn.kparam; pub const codes: type = saturn.codes; -pub const modsys: type = struct { - const core: type = saturn.modsys.core; +pub const kparam: type = opaque { + pub const params_search = saturn.kparam.params_search; + const params_loader = saturn.kparam.params_loader; +}; +pub const modsys: type = opaque { pub const modules: type = saturn.modsys.modules; pub const smll: type = saturn.modsys.smll; + const core: type = saturn.modsys.core; }; const fusium: type = saturn.fusium; @@ -56,6 +59,14 @@ comptime { } fn saturn_main(kparams: []const u8) callconv(.c) noreturn { + // carregamos e os parametros do kernel que foi passado pelo + // bootloader ou estaticamente na compilacao + if(comptime config.kernel.options.kparam_enable) { + @call(.always_inline, kparam.params_loader, .{ + if(config.kernel.options.kparam_dynamic) kparams else + @embedFile(config.kernel.options.kparam_config_file) + }); + } // Aqui existe um pequeno detalhe, bem interessante por sinal. // Quando passamos um ponteiro para uma funcao conhecida em tempo // de compilacao para o @call, o compilador precisa considerar que @@ -75,14 +86,6 @@ fn saturn_main(kparams: []const u8) callconv(.c) noreturn { // Depois da arquitetura resolver todos os seus detalhes, podemos iniciar // os modulos linkados ao kernel @call(.always_inline, modsys.core.saturn_modules_loader, .{}); - //@call(.always_inline, fusium.saturn_fusium_loader, .{ .after }); - - //modules.__SaturnAllMods__[1].create_device_node() catch { - // asm volatile( - // \\ jmp . - // \\ jmp 0xAA000 - // ); - //}; - + @call(.always_inline, fusium.saturn_fusium_loader, .{ .after }); @call(.always_inline, opaque { pub fn trap() noreturn { while(true) {} } }.trap, .{}); // noreturn fn } diff --git a/kernel/kparam/kparam.zig b/kernel/kparam/kparam.zig index af85f2a..417d236 100644 --- a/kernel/kparam/kparam.zig +++ b/kernel/kparam/kparam.zig @@ -9,10 +9,18 @@ const allocator: type = @import("allocator.zig"); var sys_param: types.Params_T = .{}; -pub noinline fn params_loader(params: []const u8) void { - const parsed_params: []const types.Param_T = parser.params_parser(params); +pub inline fn params_loader(params: []const u8) void { + const parsed_params: []const types.Param_T = parser.params_parser(params) catch |err| { + _ = err; + // KLOG() + return; + }; for(0..parsed_params.len) |i| { - sys_param.add(parsed_params[i].param, parsed_params[i].value, &allocator.sba.allocator) catch |err| { + sys_param.add( + parsed_params[i].param, + parsed_params[i].value, + &allocator.sba.allocator + ) catch |err| { _ = err; // KLOG() }; @@ -20,8 +28,6 @@ pub noinline fn params_loader(params: []const u8) void { } pub noinline fn params_search(param: []const u8) types.KParamErr_T!types.Value_T { - return sys_param.search(param) catch |err| switch(err) { - types.Params_T.Err_T.AllocatorFailed => types.KParamErr_T.AllocatorInternalError, - else => types.KParamErr_T.SysParamNotFound, - }; + return sys_param.search(param) + catch return types.KParamErr_T.SysParamNotFound; } diff --git a/kernel/kparam/parser.zig b/kernel/kparam/parser.zig index ec0d434..ff30fb8 100644 --- a/kernel/kparam/parser.zig +++ b/kernel/kparam/parser.zig @@ -3,8 +3,93 @@ // │ Author: Linuxperoxo │ // └──────────────────────────────────────────────┘ +const builtin: type = @import("builtin"); const types: type = @import("types.zig"); +const allocator: type = @import("allocator.zig"); +const mem: type = @import("root").lib.utils.mem; -pub inline fn params_parser(params: []const u8) []const types.Param_T { +pub inline fn params_parser(params: []const u8) types.KParamErr_T![]const types.Param_T { + var rvalue: bool = false; + var local_index: usize = 0; + var parsed_index: usize = 0; + const parsed_params: []types.Param_T = allocator.sba.allocator.alloc( + types.Param_T, + params_counter(params) + ) catch return types.KParamErr_T.AllocatorInternalError; + errdefer allocator.sba.allocator.free(parsed_params) + catch {}; + + var i: usize = 0; + for(params) |char| { + sw: switch(char) { + ';', '\n' => { + defer { + local_index = i + 1; + parsed_index += 1; + rvalue = false; + } + if(mem.eql(params[local_index..i], @tagName(types.Value_T.yes), .{})) { + parsed_params[parsed_index].value = types.Value_T.yes; + break :sw {}; + } + if(mem.eql(params[local_index..i], @tagName(types.Value_T.no), .{})) { + parsed_params[parsed_index].value = types.Value_T.no; + break :sw {}; + } + return types.KParamErr_T.ParserInvalidValue; + }, + + '=' => { + if(rvalue) return types.KParamErr_T.ParserSyntaxError; + if(local_index >= i) return types.KParamErr_T.ParserMissingParameter; + if((i + 1) == params.len) return types.KParamErr_T.ParserMissingValue; + + switch(params[i + 1]) { + '\n', ' ' => return types.KParamErr_T.ParserMissingValue, + else => {}, + } + + parsed_params[parsed_index].param = params[local_index..i]; + local_index = i + 1; + rvalue = true; + }, + + ' ' => { + if(rvalue) continue :sw '\n'; + local_index += 1; + }, + + else => { + if((i + 1) >= params.len) { + i += 1; + continue :sw '\n'; + } + }, + } + i += 1; + } + return parsed_params; +} + +inline fn params_counter(params: []const u8) usize { + var counter: usize = 0; + for(params) |char| + counter += @intFromBool(char == '='); + return counter; +} + +test "Parsing Test" { + const std: type = @import("std"); + const kernel_param: []const u8 = + \\sysmod_disable_devfs=yes + \\sysmod_enable_devfs=no + ; + + for(try params_parser(kernel_param)) |parsed_param| { + std.debug.print("{s} = {s}\n", .{ + parsed_param.param, + @tagName(parsed_param.value), + }); + } } diff --git a/kernel/kparam/types.zig b/kernel/kparam/types.zig index 8345eb6..7a7ac70 100644 --- a/kernel/kparam/types.zig +++ b/kernel/kparam/types.zig @@ -8,6 +8,10 @@ const hashtable: type = @import("root").lib.utils.hashtable; pub const KParamErr_T: type = error { SysParamNotFound, AllocatorInternalError, + ParserSyntaxError, + ParserInvalidValue, + ParserMissingParameter, + ParserMissingValue, }; pub const Params_T: type = hashtable.buildHashTable(