From bbec8dbf377eb52575406e2494fc9f19918d0be9 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sat, 20 Jul 2024 13:45:49 +0200 Subject: [PATCH] creating libk, working compile time kprintf, adding toString functions --- :w | 39 +++++++ build.zig | 10 +- sources/drivers/index.zig | 2 +- sources/drivers/power/acpi.zig | 3 +- sources/drivers/power/rsdt.zig | 3 +- sources/kernel/arch/x86/gdt.zig | 1 - sources/kernel/io/out.zig | 118 ------------------- sources/kernel/kmain.zig | 6 +- sources/libk/index.zig | 3 + sources/libk/io/io.zig | 3 + sources/libk/io/out.zig | 126 +++++++++++++++++++++ sources/{kernel => libk}/memory/memory.zig | 0 sources/libk/strings/strings.zig | 4 + sources/libk/strings/to_string.zig | 77 +++++++++++++ 14 files changed, 267 insertions(+), 128 deletions(-) create mode 100644 :w delete mode 100644 sources/kernel/io/out.zig create mode 100644 sources/libk/index.zig create mode 100644 sources/libk/io/io.zig create mode 100644 sources/libk/io/out.zig rename sources/{kernel => libk}/memory/memory.zig (100%) create mode 100644 sources/libk/strings/strings.zig create mode 100644 sources/libk/strings/to_string.zig diff --git a/:w b/:w new file mode 100644 index 0000000..dea811d --- /dev/null +++ b/:w @@ -0,0 +1,39 @@ +const builtin = @import("builtin"); +const is_test = builtin.is_test; + +comptime +{ + if(!is_test) + { + switch(builtin.cpu.arch) + { + .x86 => _ = @import("arch/x86/boot.zig"), + else => unreachable, + } + } +} + +const drivers = @import("drivers"); +const libk = @import("libk"); + +pub const logs = @import("log.zig"); +pub const kpanic = @import("panic.zig").kpanic; + +pub const arch = if(!is_test) switch(builtin.cpu.arch) +{ + .x86 => @import("arch/x86/arch.zig"), + else => unreachable, +}; + +export fn kmain() void +{ + @setCold(true); + arch.init(); + drivers.initDrivers(); + logs.klogln("Welcome to RatiOS !"); + const caca: i32 = 1048; + const caca2: i32 = 1048; + const caca3: i32 = 1048; + libk.io.kprintf("caca ;{};, ;{};, ;{};\n", .{ &caca, &caca2, &caca3 }); + drivers.shutdownDrivers(); +} diff --git a/build.zig b/build.zig index e683d11..a6ea3c3 100644 --- a/build.zig +++ b/build.zig @@ -11,7 +11,7 @@ pub fn build(b: *std.Build) void .os_tag = .freestanding, }), .optimize = .Debug, - //.strip = true, + .strip = true, .code_model = .kernel, .pic = false, .error_tracing = false, @@ -22,8 +22,16 @@ pub fn build(b: *std.Build) void .root_source_file = .{ .src_path = .{ .owner = b, .sub_path = "sources/drivers/index.zig" } } }); + const libk_module = b.addModule("libk", .{ + .root_source_file = .{ .src_path = .{ .owner = b, .sub_path = "sources/libk/index.zig" } } + }); + drivers_module.addImport("kernel", &kernel.root_module); + drivers_module.addImport("libk", libk_module); kernel.root_module.addImport("drivers", drivers_module); + kernel.root_module.addImport("libk", libk_module); + libk_module.addImport("kernel", &kernel.root_module); + libk_module.addImport("drivers", drivers_module); b.installArtifact(kernel); diff --git a/sources/drivers/index.zig b/sources/drivers/index.zig index df3c01d..f661412 100644 --- a/sources/drivers/index.zig +++ b/sources/drivers/index.zig @@ -11,7 +11,7 @@ pub fn initDrivers() void kernel.logs.beginSection(); kb.init(); vga.init("RatiOS 0.2", vga.computeColor(vga.Color.BLACK, vga.Color.LIGHT_GREY), vga.computeColor(vga.Color.WHITE, vga.Color.DARK_GREY), vga.computeColor(vga.Color.LIGHT_BLUE, vga.Color.DARK_GREY)); - power.init(); + //power.init(); kernel.logs.endSection(); kernel.logs.klogln("[Drivers Manager] loaded drivers"); } diff --git a/sources/drivers/power/acpi.zig b/sources/drivers/power/acpi.zig index 0a8f0b3..0795561 100644 --- a/sources/drivers/power/acpi.zig +++ b/sources/drivers/power/acpi.zig @@ -1,4 +1,5 @@ const kernel = @import("kernel"); +const libk = @import("libk"); const rsdt = @import("rsdt.zig"); const xsdt = @import("xsdt.zig"); @@ -107,7 +108,7 @@ fn getRSDP() !*u32 fn checkHeader(ptr: *u32, sig: []const u8) bool { - if(kernel.memory.memcmp(@as([*]u8, @ptrCast(ptr)), @as([*]u8, @ptrCast(@constCast(sig))), 4) != 0) + if(libk.memory.memcmp(@as([*]u8, @ptrCast(ptr)), @as([*]u8, @ptrCast(@constCast(sig))), 4) != 0) return false; var check_ptr: [*]u8 = @ptrCast(ptr); var len: usize = @as(*usize, @ptrFromInt(@intFromPtr(ptr) + 1)).*; diff --git a/sources/drivers/power/rsdt.zig b/sources/drivers/power/rsdt.zig index 17a650e..9c44445 100644 --- a/sources/drivers/power/rsdt.zig +++ b/sources/drivers/power/rsdt.zig @@ -1,4 +1,5 @@ const kernel = @import("kernel"); +const libk = @import("libk"); pub const RSDP = struct { @@ -14,7 +15,7 @@ pub fn checkRSDP(ptr: *u32) !*u32 const rsdp: *RSDP = @as(*RSDP, @ptrCast(ptr)); const sig = "RSD PTR "; var check: u32 = 0; - if(kernel.memory.memcmp(sig, @as([*]u8, @ptrCast(rsdp)), 8) == 0) + if(libk.memory.memcmp(sig, @as([*]u8, @ptrCast(rsdp)), 8) == 0) { // Check checksum of rsdp const bptr: [*]u8 = @ptrCast(ptr); diff --git a/sources/kernel/arch/x86/gdt.zig b/sources/kernel/arch/x86/gdt.zig index 82e61bd..3d944bd 100644 --- a/sources/kernel/arch/x86/gdt.zig +++ b/sources/kernel/arch/x86/gdt.zig @@ -1,4 +1,3 @@ -pub const console = @import("../../io/out.zig"); const boot = @import("boot.zig"); const GDTEntry = packed struct diff --git a/sources/kernel/io/out.zig b/sources/kernel/io/out.zig deleted file mode 100644 index 912b758..0000000 --- a/sources/kernel/io/out.zig +++ /dev/null @@ -1,118 +0,0 @@ -const vga = @import("drivers").vga; - -pub fn kputs(message: []const u8) void -{ - vga.putString(message); -} - -const ArgTypes = enum -{ - Int, - Float, - Char, - String, - Pointer, - Null -}; - -pub fn kprintf(fmt: [*:0]const u8, ...) callconv(.C) c_int -{ - var ap = @cVaStart(); - defer @cVaEnd(&ap); - - var arg_insert: bool = false; - var arg_type: ArgTypes = .Null; - var number_char_printed: i32 = 0; - - var i: usize = 0; - while(fmt[i] != 0) - { - if(fmt[i] == '{') - { - arg_insert = true; - i += 1; - continue; - } - - if(arg_insert) - { - if(fmt[i] == '}') - { - if(arg_type == .Null) - return -1; - - switch(arg_type) - { - ArgTypes.Char => - { - vga.putChar(@cVaArg(&ap, u8)); - number_char_printed += 1; - }, - ArgTypes.Int => number_char_printed += putNb(@cVaArg(&ap, i32)), - ArgTypes.Float => _ = @cVaArg(&ap, f32), - ArgTypes.String => _ = @cVaArg(&ap, *u8), - ArgTypes.Pointer => _ = @cVaArg(&ap, *u32), - else => {}, - } - - arg_insert = false; - arg_type = .Null; - } - else if(arg_type != .Null) - return -1 - else - { - switch(fmt[i]) - { - 'c' => arg_type = .Char, - 'i' => arg_type = .Int, - 'f' => arg_type = .Float, - 'p' => arg_type = .Pointer, - 's' => arg_type = .String, - - else => return -1, - } - } - } - else - { - vga.putChar(fmt[i]); - number_char_printed += 1; - } - i += 1; - } - return number_char_printed; -} - -pub fn putNb(nbr: i64) i32 -{ - var print_size: i32 = 0; - - if(nbr <= -2147483648) - { - vga.putString("-2147483648"); - return 11; - } - else if(nbr >= 2147483647) - { - vga.putString("2147483647"); - return 10; - } - else if(nbr < 0) - { - vga.putChar('-'); - print_size += putNb(-nbr); - } - else if(nbr >= 10) - { - print_size += putNb(@divFloor(nbr, 10)); - vga.putChar(@intCast(@mod(nbr, 10) + @as(u8, 48))); - print_size += 1; - } - else - { - vga.putChar(@intCast(nbr + 48)); - print_size += 1; - } - return print_size; -} diff --git a/sources/kernel/kmain.zig b/sources/kernel/kmain.zig index 84a5c10..18798b7 100644 --- a/sources/kernel/kmain.zig +++ b/sources/kernel/kmain.zig @@ -14,11 +14,10 @@ comptime } const drivers = @import("drivers"); +const libk = @import("libk"); pub const logs = @import("log.zig"); pub const kpanic = @import("panic.zig").kpanic; -pub const console = @import("io/out.zig"); -pub const memory = @import("memory/memory.zig"); pub const arch = if(!is_test) switch(builtin.cpu.arch) { @@ -32,8 +31,5 @@ export fn kmain() void arch.init(); drivers.initDrivers(); logs.klogln("Welcome to RatiOS !"); - const caca: i32 = 1048; - _ = console.kprintf("caca ;{i};, ;{f};, ;{s};\n", caca); - _ = console.putNb(caca); drivers.shutdownDrivers(); } diff --git a/sources/libk/index.zig b/sources/libk/index.zig new file mode 100644 index 0000000..c51739a --- /dev/null +++ b/sources/libk/index.zig @@ -0,0 +1,3 @@ +pub const memory = @import("memory/memory.zig"); +pub const io = @import("io/io.zig"); +pub const strings = @import("strings/strings.zig"); diff --git a/sources/libk/io/io.zig b/sources/libk/io/io.zig new file mode 100644 index 0000000..84f7c3c --- /dev/null +++ b/sources/libk/io/io.zig @@ -0,0 +1,3 @@ +pub const kputs = @import("out.zig").kputs; +pub const kputNb = @import("out.zig").kputNb; +pub const kprintf = @import("out.zig").kprintf; diff --git a/sources/libk/io/out.zig b/sources/libk/io/out.zig new file mode 100644 index 0000000..f78f33b --- /dev/null +++ b/sources/libk/io/out.zig @@ -0,0 +1,126 @@ +const vga = @import("drivers").vga; +const string = @import("../strings/strings.zig"); + +pub fn kputs(message: []const u8) void +{ + vga.putString(message); +} + +const ArgTypes = enum +{ + Int, + Float, + Char, + String, + Pointer, + Null +}; + +pub fn kprintf(comptime fmt: []const u8, args: anytype) void +{ + comptime var arg_idx: usize = 0; + comptime var arg_insert: bool = false; + comptime var arg_type: ArgTypes = .Null; + + inline for(fmt) |c| + { + if(c == '{') + { + arg_insert = true; + continue; + } + + if(arg_insert) + { + if(c == '}') + { + if(arg_type == .Null) + { + if(@TypeOf(args[arg_idx]) == comptime_int) + { + if(args[arg_idx] > 0 and args[arg_idx] < 256) + vga.putChar(args[arg_idx]) + else + putNb(args[arg_idx]); + } + else if(@typeInfo(@TypeOf(args[arg_idx])) == .Array and @typeInfo(@TypeOf(args[arg_idx])).Array.child == u8) + kputs(args[arg_idx]) + else if(@typeInfo(@TypeOf(args[arg_idx])) == .Pointer) + { + const T = @typeInfo(@TypeOf(args[arg_idx])).Pointer; + if(@typeInfo(T.child) == .Array and @typeInfo(T.child).Array.child == u8) + kputs(args[arg_idx]) + else + { + kputs("0x"); + kputs(string.toStringBase(@intFromPtr(args[arg_idx]), 16)); + } + } + else switch(@TypeOf(args[arg_idx])) + { + i8, u8, => vga.putChar(args[arg_idx]), + i16, u16, i32, u32, i64, u64, isize, usize => putNb(args[arg_idx]), + f16, f32, f64, comptime_float => {}, + else => @compileError("could not manage auto detected type : " ++ @typeName(@TypeOf(args[arg_idx])) ++ "; please add type identifier between brackets"), + } + } + switch(arg_type) + { + .Char => vga.putChar(args[arg_idx]), + .Int => putNb(args[arg_idx]), + .Float => {}, + .String => kputs(args[arg_idx]), + .Pointer => { kputs("0x"); kputs(string.toStringBase(@intFromPtr(args[arg_idx]), 16)); }, + else => {}, + } + + arg_insert = false; + arg_idx += 1; + arg_type = .Null; + } + else if(arg_type != .Null) + @compileError("too much type identifiers between the brackets") + else + { + switch(c) + { + 'c' => arg_type = .Char, + 'i' => arg_type = .Int, + 'f' => arg_type = .Float, + 'p' => arg_type = .Pointer, + 's' => arg_type = .String, + + else => @compileError("invalid type identifier between the brackets"), + } + } + } + else + vga.putChar(c); + } + + comptime + { + if(args.len != arg_idx) + @compileError("unused arguments"); + } +} + +pub fn putNb(nbr: i64) void +{ + if(nbr <= -2147483648) + vga.putString("-2147483648") + else if(nbr >= 2147483647) + vga.putString("2147483647") + else if(nbr < 0) + { + vga.putChar('-'); + putNb(-nbr); + } + else if(nbr >= 10) + { + putNb(@divFloor(nbr, 10)); + vga.putChar(@intCast(@mod(nbr, 10) + @as(u8, 48))); + } + else + vga.putChar(@intCast(nbr + 48)); +} diff --git a/sources/kernel/memory/memory.zig b/sources/libk/memory/memory.zig similarity index 100% rename from sources/kernel/memory/memory.zig rename to sources/libk/memory/memory.zig diff --git a/sources/libk/strings/strings.zig b/sources/libk/strings/strings.zig new file mode 100644 index 0000000..4897fc9 --- /dev/null +++ b/sources/libk/strings/strings.zig @@ -0,0 +1,4 @@ +pub const toString = @import("to_string.zig").toString; +pub const toStringBase = @import("to_string.zig").toStringBase; +pub const toStringBuffer = @import("to_string.zig").toStringBuffer; +pub const toStringBufferBase = @import("to_string.zig").toStringBufferBase; diff --git a/sources/libk/strings/to_string.zig b/sources/libk/strings/to_string.zig new file mode 100644 index 0000000..ff7f2cf --- /dev/null +++ b/sources/libk/strings/to_string.zig @@ -0,0 +1,77 @@ +const kernel = @import("kernel"); + +fn countDigitsInBase(number: i64, base: u8) u8 +{ + var count: u8 = 0; + var tmp: i64 = number; + while(tmp > 0) + { + tmp = @divFloor(tmp, base); + count += 1; + } + return count; +} + +pub fn toStringBufferBase(buffer: []u8, value: anytype, base: u8) ![]u8 +{ + switch(@TypeOf(value)) + { + i8, u8, i16, u16, i32, u32, i64, u64, isize, usize, comptime_int => + { + const digits_count = countDigitsInBase(value, base); + if(digits_count > buffer.len) + return error.NotEnoughPlace; + var i: usize = digits_count; + if(value == 0) + { + buffer[0] = '0'; + return buffer; + } + var v = value; + while(i > 0) : (i -= 1) + { + if(@mod(v, base) > 9) + buffer[i] = @truncate((@mod(v, base) - 10) + 'a') + else + buffer[i] = @truncate(@mod(v, base) + '0'); + v = @divFloor(v, base); + } + }, + f16, f32, f64, comptime_float => + { + }, + else => @compileError("could not manage type : " ++ @typeName(@TypeOf(value))), + } + return buffer; +} + +pub fn toStringBuffer(buffer: []u8, value: anytype) ![]u8 +{ + return try toStringBufferBase(buffer, value, 10); +} + +pub fn toStringBase(value: anytype, base: u8) []const u8 +{ + switch(@TypeOf(value)) + { + i8, u8, i16, u16, i32, u32, i64, u64, isize, usize, comptime_int => + { + const buffer: [22]u8 = [_]u8{ 0 } ** 22; + return toStringBufferBase(@constCast(buffer[0..buffer.len]), value, base) catch |err| switch(err) + { + error.NotEnoughPlace => return "", + else => unreachable + }; + }, + f16, f32, f64, comptime_float => + { + }, + else => @compileError("could not manage type : " ++ @typeName(@TypeOf(value))), + } + return ""; +} + +pub fn toString(value: anytype) []const u8 +{ + return toStringBase(value, 10); +}