From d4d68b06c782ea218e7851d289fcf98810b89cd8 Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:25:09 +0300 Subject: [PATCH 01/10] Added clang-format.sh --- scripts/clang-format.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 scripts/clang-format.sh diff --git a/scripts/clang-format.sh b/scripts/clang-format.sh new file mode 100755 index 0000000..edc4e19 --- /dev/null +++ b/scripts/clang-format.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +pwd=$(pwd) +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd $SCRIPT_DIR/.. + +clang-format --style=file --dump-config +find ./ -iname '*.h' -o -iname '*.c' | xargs clang-format -i --style=file --verbose + +cd $pwd From 309be280678436957c96035d3daef0bece2f325b Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:37:11 +0300 Subject: [PATCH 02/10] Added reflock; enhanced kstring --- kernel/include/kopsize.h | 11 ++ kernel/include/kreflock.h | 55 +++++++ kernel/include/kstring.h | 48 ++++++- kernel/klibc/reflock.c | 97 +++++++++++++ kernel/klibc/string.c | 294 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 500 insertions(+), 5 deletions(-) create mode 100644 kernel/include/kopsize.h create mode 100644 kernel/include/kreflock.h create mode 100644 kernel/klibc/reflock.c create mode 100644 kernel/klibc/string.c diff --git a/kernel/include/kopsize.h b/kernel/include/kopsize.h new file mode 100644 index 0000000..aeea8f7 --- /dev/null +++ b/kernel/include/kopsize.h @@ -0,0 +1,11 @@ +#ifndef __K_OPSIZE +#define __K_OPSIZE + +typedef enum { + OPSIZE_BYTE = 1, + OPSIZE_WORD = 2, + OPSIZE_DWORD = 4, + OPSIZE_QWORD = 8 +} opsize_t; + +#endif \ No newline at end of file diff --git a/kernel/include/kreflock.h b/kernel/include/kreflock.h new file mode 100644 index 0000000..8e38073 --- /dev/null +++ b/kernel/include/kreflock.h @@ -0,0 +1,55 @@ +// NOTE: This file contains code derived from or inspired by: +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef __K_REFLOCK +#define __K_REFLOCK + +#include +#include +#include + +typedef struct { + void (*on_lock)(); + void (*on_unlock)(); + + const bool strict; // if strict, panic if released empty lock + const bool allow_force_unlock; + + uint8_t data[12]; +} reflock_t; + +#define NEW_REFLOCK(_on_lock, _on_unlock, _strict, _allow_force) \ + { \ + _on_lock, _on_unlock, _strict, _allow_force, { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ + } \ + } + +void reflock_make(reflock_t *lock); +bool reflock_validate_magic(reflock_t *lock); + +static inline bool reflock_validate(reflock_t *lock) { + return reflock_validate_magic(lock); +} + +void reflock_acquire(reflock_t *lock); +void reflock_release(reflock_t *lock); +bool reflock_is_locked(reflock_t *lock); +void reflock_force_unlock(reflock_t *lock); + +#endif \ No newline at end of file diff --git a/kernel/include/kstring.h b/kernel/include/kstring.h index 399f653..d2885b2 100644 --- a/kernel/include/kstring.h +++ b/kernel/include/kstring.h @@ -1,11 +1,49 @@ #ifndef __K_STRING #define __K_STRING -#include +#include "kopsize.h" +#include +#include -int strcmp(const char *s1, const char *s2); -char *strcpy(char *dst, const char *src); -char *strcat(char *dst, const char *src); -int strlen(const char *s); +#define string_equal(s1, s2) !strcmp(s1, s2) +#define string_equal_n(s1, s2, n) !strncmp(s1, s2, n) +#define string_for_each(_s, _i) for (size_t _i = 0; _i < strlen(_s); _i++) + +void memset(void *ptr, char c, size_t size); +void memcpy(void *dest, const void *src, size_t size); +void xmemcpy(void *dest, const void *src, size_t size, opsize_t opsize); +int memcmp(const void* ptr1, const void* ptr2, size_t count); + +#define _tolower(c) ((c) | 0x20) + +size_t __attribute__((pure)) strlen(const char *s); + +char *strcpy(char *dest, const char *src); +char *strncpy(char *dest, const char *src, size_t n); + +int __attribute__((pure)) strncmp(const char *s1, const char *s2, size_t n); +int __attribute__((pure)) strcmp(const char *s1, const char *s2); + +char *strchr(char *s, char c); +char *strchr_r(char *s, char c); +char *strstr(char *str, const char *sub); + +char *strltrim(char *str); +char *strrtrim(char *str); +char *strtrim(char *str); + +bool isdigit(char c); +bool isalphac(char c); +bool islowerc(char c); +bool isupperc(char c); +bool isalnumc(char c); + +bool isnumeric(const char *s); +bool isalpha(const char *s); +bool isalnum(const char *s); + +char tolowerc(char c); +char *tolower(char *s); +char *toupper(char *s); #endif diff --git a/kernel/klibc/reflock.c b/kernel/klibc/reflock.c new file mode 100644 index 0000000..5eaa8ce --- /dev/null +++ b/kernel/klibc/reflock.c @@ -0,0 +1,97 @@ +// NOTE: This file contains code derived from or inspired by: +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "kreflock.h" +#include "kstring.h" +#include "sys/panic.h" +#include +#include + +struct reflock_private { + struct { + char *magic; + volatile int refcount; + } data; +}; + +#define REFLOCK_MAGIC "r3f10ck" + +static inline struct reflock_private *reflock_get_private_ptr(reflock_t *lock) { + return (struct reflock_private *)(&lock->data); +} + +void reflock_make(reflock_t *lock) { + struct reflock_private *private = reflock_get_private_ptr(lock); + private->data.magic = REFLOCK_MAGIC; + private->data.refcount = 0; +} + +bool reflock_validate_magic(reflock_t *lock) { + struct reflock_private *private = reflock_get_private_ptr(lock); + return !strcmp(private->data.magic, REFLOCK_MAGIC); +} + +void reflock_acquire(reflock_t *lock) { + struct reflock_private *private = reflock_get_private_ptr(lock); + + if (!reflock_validate_magic(lock)) { + panic("broken reflock (invalid magic)"); + } + + if (!private->data.refcount && lock->on_lock) { + lock->on_lock(); + } + + private->data.refcount++; +} + +void reflock_release(reflock_t *lock) { + struct reflock_private *private = reflock_get_private_ptr(lock); + + if (!reflock_validate_magic(lock)) { + panic("broken reflock (invalid magic field)"); + } + + if (!private->data.refcount) { + if (lock->strict) { + panic("Attempted to release empty strict reflock"); + } + + return; + } + + if (!--private->data.refcount && lock->on_unlock) { + lock->on_unlock(); + } +} + +bool reflock_is_locked(reflock_t *lock) { + return reflock_get_private_ptr(lock)->data.refcount > 0 && + reflock_validate_magic(lock); +} + +void reflock_force_unlock(reflock_t *lock) { + struct reflock_private *private = reflock_get_private_ptr(lock); + + if (!lock->allow_force_unlock) { + panic("Attempted disallowed force-unlock of a reflock"); + } + + private->data.refcount = 0; + lock->on_unlock(); +} diff --git a/kernel/klibc/string.c b/kernel/klibc/string.c new file mode 100644 index 0000000..6a0a1b9 --- /dev/null +++ b/kernel/klibc/string.c @@ -0,0 +1,294 @@ +// NOTE: This file contains code derived from or inspired by AstriX ("The AstriX +// Operating System") at https://codeberg.org/AstriX/AstriX. Copyright (c) +// 2023-2025 NotYourFox, sigsegv SPDX-License-Identifier: GPL-3.0-or-later + +// If this project is made accessible to the general public, it is required to +// obey the terms of GNU General Public License version 3 (or later) for as long +// as this notice applies. +// If you suspect any form of license violation or copyright infringement, +// please reach out to AstriX team at . + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "kstring.h" +#include +#include + +void memset(void *ptr, char c, size_t size) { + for (size_t i = 0; i < size; i++) { + *(char *)(ptr + i) = c; + } +} + +void xmemcpy(void *dest, const void *src, size_t size, opsize_t opsize) { + size_t d0, d1, d2; + + switch (opsize) { + case OPSIZE_BYTE: + asm volatile("rep movsb" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(size), "1"(dest), "2"(src) + : "memory"); + break; + case OPSIZE_WORD: + asm volatile("rep movsw" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(size), "1"(dest), "2"(src) + : "memory"); + break; + case OPSIZE_DWORD: + asm volatile("rep movsd" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(size), "1"(dest), "2"(src) + : "memory"); + break; + case OPSIZE_QWORD: + asm volatile("rep movsd" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(size), "1"(dest), "2"(src) + : "memory"); + break; + default: + asm volatile("rep movsb" + : "=&c"(d0), "=&D"(d1), "=&S"(d2) + : "0"(size * opsize), "1"(dest), "2"(src) + : "memory"); + break; + } +} + +void memcpy(void *dest, const void *src, size_t size) { + xmemcpy(dest, src, size, OPSIZE_BYTE); +} + +int memcmp(const void* ptr1, const void* ptr2, size_t count) { + register const unsigned char* p1 = ptr1; + register const unsigned char* p2 = ptr2; + + while (count-- > 0) { + if (*p1++ != *p2++) { + return p1[-1] < p2[-1] ? -1 : 1; + } + } + + return 0; +} + +size_t __attribute__((pure)) strlen(const char *s) { + int i; + for (i = 0; s[i] != '\0'; i++); + return i; +} + +char *strcat(char *dst, const char *src) { + char *buf = dst; + strcpy(dst + strlen(dst), src); + return buf; +} + +char *strcpy(char *dest, const char *src) { + memcpy(dest, src, strlen(src) + 1); + return dest; +} + +char *strncpy(char *dest, const char *src, size_t n) { + size_t total = n > strlen(src) ? strlen(src) : n; + memcpy(dest, src, total); + dest[total] = 0x00; + + return dest; +} + +int strncmp(const char *s1, const char *s2, size_t n) { + if (n > strlen(s1) || n > strlen(s2)) { + return strlen(s1) > strlen(s2) ? 1 : -1; + } + + return memcmp(s1, s2, n); +} + +int strcmp(const char *s1, const char *s2) { + if (strlen(s1) != strlen(s2)) { + return strlen(s1) > strlen(s2) ? 1 : -1; + } + + return strncmp(s1, s2, strlen(s1)); +} + +char *strltrim(char *str) { + while (*str == ' ' || *str == '\t') { + str++; + } + + return str; +} + +char *strrtrim(char *str) { + char *ptr = str + strlen(str) - 1; + while (*ptr == ' ' || *ptr == '\t') { + *ptr++ = 0x00; + } + + return str; +} + +char *strtrim(char *str) { + str = strltrim(str); + return strrtrim(str); +} + +bool isupperc(char c) { + return (c >= 'A' && c <= 'Z'); +} + +bool isupper(const char *s) { + string_for_each(s, i) { + if (!isupperc(s[i])) { + return false; + } + } + + return true; +} + +bool islowerc(char c) { + return (c >= 'a' && c <= 'z'); +} + +// note: returns false for non-alpha string +bool islower(const char *s) { + string_for_each(s, i) { + if (!islowerc(s[i])) { + return false; + } + } + + return true; +} + +bool isdigit(char c) { + return c >= '0' && c <= '9'; +} + +bool isnumeric(const char *s) { + string_for_each(s, i) { + if (!isdigit(s[i])) { + return false; + } + } + + return true; +} + +bool isalphac(char c) { + return isupperc(c) || islowerc(c); +} + +bool isalpha(const char *s) { + string_for_each(s, i) { + if (!isalphac(s[i])) { + return false; + } + } + + return true; +} + +bool isalnumc(char c) { + return isalphac(c) || isdigit(c); +} + +bool isalnum(const char *s) { + string_for_each(s, i) { + if (!isalphac(s[i]) && !isdigit(s[i])) { + return false; + } + } + + return true; +} + +char toupperc(char c) { + if (!isalnumc(c)) { + return c; + } + + return c & ~0x20; +} + +char tolowerc(char c) { + if (!isalnumc(c)) { + return c; + } + + return _tolower(c); +} + +// NOTE: MODIFIES STRING IN-PLACE + +char *toupper(char *s) { + // note: 'a' > 'A' + string_for_each(s, i) { + if (isupperc(s[i]) || !isalphac(s[i])) { + continue; + } + + s[i] = toupperc(s[i]); + } + + return s; +} + +char *tolower(char *s) { + // note: 'a' > 'A' + string_for_each(s, i) { + if (islowerc(s[i]) || !isalphac(s[i])) { + continue; + } + + s[i] = tolowerc(s[i]); + } + + return s; +} + +char *strchr(char *s, char c) { + for (size_t i = 0; i < strlen(s); i++) { + if (s[i] == c) { + return s + i; + } + } + + return NULL; +} + +char *strchr_r(char *s, char c) { + for (int i = strlen(s) - 1; i >= 0; i--) { + if (s[i] == c) { + return s + i; + } + } + + return NULL; +} + +char *strstr(char *str, const char *sub) { + for (size_t i = 0; i < strlen(str); i++) { + if (!strncmp(str + i, sub, strlen(sub))) { + return str + i; + } + } + + return NULL; +} \ No newline at end of file From be052c9ce785748671cb318950a6fbd657dc5dea Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:37:34 +0300 Subject: [PATCH 03/10] Made proper structure for arch-specific code; added panic --- kernel/arch/amd64/cpu/control.c | 68 ++++++++++++++++++ kernel/arch/amd64/cpu/regs.S | 26 +++++++ kernel/arch/amd64/cpu/regs.c | 11 +++ kernel/arch/amd64/cpu/state.c | 47 +++++++++++++ kernel/arch/amd64/cpu/strace.c | 19 +++++ kernel/arch/include/amd64/cpu/regs.h | 97 ++++++++++++++++++++++++++ kernel/arch/include/amd64/cpu/tables.h | 15 ++++ kernel/include/arch/cpu/control.h | 13 ++++ kernel/include/arch/cpu/state.h | 6 ++ kernel/include/arch/cpu/strace.h | 14 ++++ kernel/include/sys/panic.h | 4 ++ kernel/sys/panic.c | 21 ++++++ 12 files changed, 341 insertions(+) create mode 100644 kernel/arch/amd64/cpu/control.c create mode 100644 kernel/arch/amd64/cpu/regs.S create mode 100644 kernel/arch/amd64/cpu/regs.c create mode 100644 kernel/arch/amd64/cpu/state.c create mode 100644 kernel/arch/amd64/cpu/strace.c create mode 100644 kernel/arch/include/amd64/cpu/regs.h create mode 100644 kernel/arch/include/amd64/cpu/tables.h create mode 100644 kernel/include/arch/cpu/control.h create mode 100644 kernel/include/arch/cpu/state.h create mode 100644 kernel/include/arch/cpu/strace.h create mode 100644 kernel/include/sys/panic.h create mode 100644 kernel/sys/panic.c diff --git a/kernel/arch/amd64/cpu/control.c b/kernel/arch/amd64/cpu/control.c new file mode 100644 index 0000000..70121dc --- /dev/null +++ b/kernel/arch/amd64/cpu/control.c @@ -0,0 +1,68 @@ +// NOTE: This file contains code derived from or inspired by: +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "arch/cpu/control.h" +#include "kreflock.h" +#include "kstdlib.h" + +static inline void __cpu_enable_interrupt() { + asm volatile("sti"); +} + +static inline void __cpu_disable_interrupt() { + asm volatile("cli"); +} + +static reflock_t lock = + NEW_REFLOCK(__cpu_disable_interrupt, __cpu_enable_interrupt, false, true); + +bool cpu_interrupt_lock_acquired() { + if (unlikely(!reflock_validate(&lock))) { + reflock_make(&lock); + } + + return reflock_is_locked(&lock); +} + +void cpu_interrupt_lock_acquire() { + if (unlikely(!reflock_validate(&lock))) { + reflock_make(&lock); + } + + reflock_acquire(&lock); +} + +void cpu_interrupt_lock_release() { + if (unlikely(!reflock_validate(&lock))) { + reflock_make(&lock); + } + + reflock_release(&lock); +} + +void cpu_interrupt_lock_force_release() { + if (unlikely(!reflock_validate(&lock))) { + reflock_make(&lock); + } + + reflock_force_unlock(&lock); +} + +void cpu_halt() { + asm ("hlt"); +} \ No newline at end of file diff --git a/kernel/arch/amd64/cpu/regs.S b/kernel/arch/amd64/cpu/regs.S new file mode 100644 index 0000000..f22bbda --- /dev/null +++ b/kernel/arch/amd64/cpu/regs.S @@ -0,0 +1,26 @@ +#define __ASSEMBLY__ + +.intel_syntax noprefix + +#include "arch/cpu/tables.h" + +.code64 + +.global __asm_update_regs + +get_flags: + pushfd + mov rax, [rsp] + popfd + + ret + +get_rip: + mov rax, [rsp] + ret + +// TODO because I'm not familiar with x86-64 conventions +__asm_update_regs: + ret + +#undef __ASSEMBLY__ \ No newline at end of file diff --git a/kernel/arch/amd64/cpu/regs.c b/kernel/arch/amd64/cpu/regs.c new file mode 100644 index 0000000..0b8742f --- /dev/null +++ b/kernel/arch/amd64/cpu/regs.c @@ -0,0 +1,11 @@ +#include "amd64/cpu/regs.h" +#include "arch/cpu/strace.h" +#include "kstring.h" + +extern void __asm_update_regs(asm_regs_t *regs); + +// work in progress +void update_asm_regs(asm_regs_t *state) { + memset(state, 0x00, sizeof(asm_regs_t)); + return; +} \ No newline at end of file diff --git a/kernel/arch/amd64/cpu/state.c b/kernel/arch/amd64/cpu/state.c new file mode 100644 index 0000000..0dedc2c --- /dev/null +++ b/kernel/arch/amd64/cpu/state.c @@ -0,0 +1,47 @@ +#include "amd64/cpu/regs.h" +#include "khal.h" + +void cpu_state_print() { + asm_regs_t current_state; + + serial_printf("The following register dump is a stub and a work-in-progress.\n"); + + update_asm_regs(¤t_state); + serial_printf("Registers:\n"); + serial_printf("\tRAX: 0x%x RBX: 0x%x RCX: 0x%x RDX: 0x%x\n", + current_state.eax, current_state.ebx, current_state.ecx, + current_state.edx); + serial_printf("\tRBP: 0x%x RSP: 0x%x RSI: 0x%x RDI: 0x%x\n", + current_state.ebp, current_state.esp, current_state.esi, + current_state.edi); + serial_printf("\tCS: 0x%x DS: 0x%x ES: 0x%x FS: 0x%x\n", + current_state.cs, current_state.ds, current_state.es, + current_state.fs); + serial_printf("\tGS: 0x%x SS: 0x%x\n", current_state.gs, + current_state.ss); + serial_printf("\tCR0: 0x%x CR2: 0x%x CR3: 0x%x CR4: 0x%x\n", + current_state.cr0, current_state.cr2, current_state.cr3, + current_state.cr4); + + serial_printf("\tDR0: 0x%x DR1: 0x%x DR2: 0x%x DR3: 0x%x\n", + current_state.dr0, current_state.dr1, current_state.dr2, + current_state.dr3); + serial_printf("\tDR6: 0x%x DR7: 0x%x\n", current_state.dr6, + current_state.dr7); + serial_printf("\tGDTR: base=0x%x, limit=0x%x\n\tLDTR: base=0x%x, " + "limit=0x%x\n\tIDTR: base=0x%x, limit=0x%x\n", + current_state.gdtr.base, current_state.gdtr.limit, + current_state.ldtr.base, current_state.ldtr.limit, + current_state.idtr.base, current_state.idtr.limit); + + // TODO: symbol names + serial_printf("\tRIP: 0x%x", current_state.rip); + + // serial_printf("\tCode: "); + // for (int i = 0; i < 16; i++) { + // serial_printf("%x ", *(uint8_t *)(current_state.rip + i)); + // } + // serial_printf("\n"); + + serial_printf("\n"); +} diff --git a/kernel/arch/amd64/cpu/strace.c b/kernel/arch/amd64/cpu/strace.c new file mode 100644 index 0000000..ee419d2 --- /dev/null +++ b/kernel/arch/amd64/cpu/strace.c @@ -0,0 +1,19 @@ +#include "arch/cpu/strace.h" +#include + +struct stackframe *strace_get() { + struct stackframe *res; + asm("movq %%rbp, %0" : "=r"(res)); + return res; +} + +uint64_t strace_get_framep(int sf_offset) { + struct stackframe *stack = strace_get(); + + // skip get_x86_stack_trace(), 0 points to this function + for (int i = 0; stack && i < sf_offset + 1; i++) { + stack = stack->sp; + } + + return stack->pc; +} \ No newline at end of file diff --git a/kernel/arch/include/amd64/cpu/regs.h b/kernel/arch/include/amd64/cpu/regs.h new file mode 100644 index 0000000..0166359 --- /dev/null +++ b/kernel/arch/include/amd64/cpu/regs.h @@ -0,0 +1,97 @@ +#ifndef __ARCH_CPU_REGS +#define __ARCH_CPU_REGS + +#include "amd64/cpu/tables.h" + +#include + +typedef struct { + uint32_t eflags; + + union { + struct { + uint8_t ah; + uint8_t al; + }; + uint16_t ax; + uint32_t eax; + uint64_t rax; + }; + union { + struct { + uint8_t bh; + uint8_t bl; + }; + uint16_t bx; + uint32_t ebx; + uint64_t rbx; + }; + union { + struct { + uint8_t ch; + uint8_t cl; + }; + uint16_t cx; + uint32_t ecx; + uint64_t rcx; + }; + union { + struct { + uint8_t dh; + uint8_t dl; + }; + uint16_t dx; + uint32_t edx; + uint64_t rdx; + }; + + union { + uint16_t bp; + uint32_t ebp; + uint64_t rbp; + }; + union { + uint16_t sp; + uint32_t esp; + uint64_t rsp; + }; + union { + uint16_t si; + uint32_t esi; + uint64_t rsi; + }; + union { + uint16_t di; + uint32_t edi; + uint64_t rdi; + }; + + uint64_t rip; + + uint16_t cs; + uint16_t ds; + uint16_t es; + uint16_t fs; + uint16_t gs; + uint16_t ss; + + uint32_t cr0; + uint32_t cr2; + uint32_t cr3; + uint32_t cr4; + + uint32_t dr0; + uint32_t dr1; + uint32_t dr2; + uint32_t dr3; + uint32_t dr6; + uint32_t dr7; + + struct desc_table gdtr; + struct desc_table ldtr; + struct desc_table idtr; +} __attribute__((packed)) asm_regs_t; + +extern void update_asm_regs(asm_regs_t *state); + +#endif diff --git a/kernel/arch/include/amd64/cpu/tables.h b/kernel/arch/include/amd64/cpu/tables.h new file mode 100644 index 0000000..b9a0537 --- /dev/null +++ b/kernel/arch/include/amd64/cpu/tables.h @@ -0,0 +1,15 @@ +#ifndef __ARCH_CPU_TABLES +#define __ARCH_CPU_TABLES + +#define DESC_TABLE_SIZE 6 + +#ifndef __ASSEMBLY__ +#include + +struct desc_table { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); +#endif + +#endif \ No newline at end of file diff --git a/kernel/include/arch/cpu/control.h b/kernel/include/arch/cpu/control.h new file mode 100644 index 0000000..a9d0ec7 --- /dev/null +++ b/kernel/include/arch/cpu/control.h @@ -0,0 +1,13 @@ +#ifndef __ARCH_CPU_CONTROL +#define __ARCH_CPU_CONTROL + +#include + +extern bool cpu_interrupt_lock_acquired(); +extern void cpu_interrupt_lock_acquire(); +extern void cpu_interrupt_lock_release(); +extern void cpu_interrupt_lock_force_release(); + +void cpu_halt(); + +#endif \ No newline at end of file diff --git a/kernel/include/arch/cpu/state.h b/kernel/include/arch/cpu/state.h new file mode 100644 index 0000000..fff6a10 --- /dev/null +++ b/kernel/include/arch/cpu/state.h @@ -0,0 +1,6 @@ +#ifndef __K_SYS_CPU_STATE +#define __K_SYS_CPU_STATE + +extern void cpu_state_print(); + +#endif \ No newline at end of file diff --git a/kernel/include/arch/cpu/strace.h b/kernel/include/arch/cpu/strace.h new file mode 100644 index 0000000..2d3c60d --- /dev/null +++ b/kernel/include/arch/cpu/strace.h @@ -0,0 +1,14 @@ +#ifndef __ARCH_CPU_STRACE +#define __ARCH_CPU_STRACE + +#include + +struct stackframe { + struct stackframe *sp; + uint64_t pc; +}; + +extern struct stackframe *strace_get(); +extern uint64_t strace_get_framep(int sf_offset); + +#endif \ No newline at end of file diff --git a/kernel/include/sys/panic.h b/kernel/include/sys/panic.h new file mode 100644 index 0000000..7fc8245 --- /dev/null +++ b/kernel/include/sys/panic.h @@ -0,0 +1,4 @@ +#include + +void __attribute__((noreturn)) panic_int(uint8_t int_no, const char *msg); +void __attribute__((noreturn)) panic(const char *msg); \ No newline at end of file diff --git a/kernel/sys/panic.c b/kernel/sys/panic.c new file mode 100644 index 0000000..735ee64 --- /dev/null +++ b/kernel/sys/panic.c @@ -0,0 +1,21 @@ +#include "khal.h" +#include "arch/cpu/state.h" +#include "arch/cpu/control.h" +#include + +// TODO: make printf-like + +void __attribute__((noreturn)) panic_int(uint8_t int_no, const char *msg) { + serial_printf("\n\rKernel panic (in interrupt) [INT=0x%02X] - %s\n", int_no, + msg); + cpu_state_print(); + + for (;;) cpu_halt(); +} + +void __attribute__((noreturn)) panic(const char *msg) { + serial_printf("\n\rKernel panic - %s\n", msg); + cpu_state_print(); + + for (;;) cpu_halt(); +} \ No newline at end of file From c44b112a0cacc7ae9266b1a52465fcfbd216d60a Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:38:42 +0300 Subject: [PATCH 04/10] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index afb7f5e..7447d04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Code editor files +.vscode + # Prerequisites *.d From 4efda1629e0ebf7d148fa331ed61f9419d886c28 Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:39:01 +0300 Subject: [PATCH 05/10] PLEASE DEPRECATE KSTDINT --- kernel/include/kstdint.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/kernel/include/kstdint.h b/kernel/include/kstdint.h index dff5238..33afcfe 100644 --- a/kernel/include/kstdint.h +++ b/kernel/include/kstdint.h @@ -1,16 +1,20 @@ #ifndef __K_STDINT #define __K_STDINT -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long long int64_t; +#include -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; +// deprecate this, #include from OS instead -typedef uint64_t uintptr_t; +// typedef char int8_t; +// typedef short int16_t; +// typedef int int32_t; +// typedef long long int64_t; + +// typedef unsigned char uint8_t; +// typedef unsigned short uint16_t; +// typedef unsigned int uint32_t; +// typedef unsigned long long uint64_t; + +// typedef uint64_t uintptr_t; #endif \ No newline at end of file From 942bd2308ed53bd119ae747d7c1458ecc4cf7bab Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:39:41 +0300 Subject: [PATCH 06/10] Added likely/unlikely --- kernel/include/kstdlib.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/include/kstdlib.h b/kernel/include/kstdlib.h index 38a4be6..d1f270b 100644 --- a/kernel/include/kstdlib.h +++ b/kernel/include/kstdlib.h @@ -1,6 +1,9 @@ #ifndef __K_STDLIB #define __K_STDLIB +#define unlikely(x) __builtin_expect(x, 0) +#define likely(x) __builtin_expect(x, 1) + #define IGNORE_UNUSED(x) ((void)x) #endif \ No newline at end of file From b7200ff2b18e02a414a7bb6e2c7c6c6cac264d14 Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:40:06 +0300 Subject: [PATCH 07/10] Update .clang-format --- .clang-format | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.clang-format b/.clang-format index 2896996..0308bab 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ -ColumnLimit: 100 +Language: Cpp IndentWidth: 4 UseTab: ForIndentation TabWidth: 4 @@ -6,25 +6,24 @@ SpacesBeforeTrailingComments: 1 NamespaceIndentation: None AlignConsecutiveAssignments: false AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: true +AllowShortBlocksOnASingleLine: Empty AllowShortFunctionsOnASingleLine: Inline AllowShortCaseLabelsOnASingleLine: true -AllowShortIfStatementsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: WithoutElse AllowShortLoopsOnASingleLine: true BreakBeforeBinaryOperators: None BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false ConstructorInitializerAllOnOneLineOrOnePerLine: true -DerivePointerAlignment: true IndentCaseLabels: true KeepEmptyLinesAtTheStartOfBlocks: false PointerAlignment: Right ContinuationIndentWidth: 4 -SpacesInParentheses: false +SpacesInParens: Never SpacesInSquareBrackets: false SpacesInAngles: false -SpaceInEmptyParentheses: true IndentPPDirectives: None IncludeBlocks: Preserve Cpp11BracedListStyle: false -Standard: Cpp11 \ No newline at end of file +Standard: Cpp11 +ReflowComments: false \ No newline at end of file From d6974a03a0b6db6eaffe7b43a7e7dbd6f403bc07 Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:41:00 +0300 Subject: [PATCH 08/10] Add -Ikernel/arch/include to include path and support .S as a GAS extension --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2b74d95..0a7b820 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SRCS := $(shell find kernel/ -name "*.c" -o -name "*.s") OBJS := $(patsubst %.c, %.o, $(patsubst %.s, %.o, $(SRCS))) $(shell mkdir -p $(dir $(OBJS))) -CFLAGS = -m64 -Wall -Werror -std=gnu2x -Ikernel/include -ffreestanding -O0 -fno-stack-protector +CFLAGS = -m64 -Wall -Werror -std=gnu2x -Ikernel/include -Ikernel/arch/include -ffreestanding -O0 -fno-stack-protector -Wno-format ASFLAGS = -64 .PHONY: all run test clean format @@ -23,7 +23,7 @@ kernel/kernel.elf: $(OBJS) %.o: %.c gcc $(CFLAGS) -c -o $@ $< -%.o: %.s +%.o: %.s %.S as $(ASFLAGS) -o $@ $< serial.log: cis-os.iso From 4ea12f34e3c14ef40b3dabc687fac123d8b43041 Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Mon, 13 Jan 2025 23:42:04 +0300 Subject: [PATCH 09/10] Finishing refactoring changes --- kernel/arch/amd64/cpu/control.c | 6 +- kernel/arch/amd64/cpu/state.c | 5 +- kernel/arch/amd64/idt.c | 9 +- kernel/arch/amd64/paging.c | 4 +- kernel/arch/amd64/serial.c | 12 +- kernel/cpio.c | 2 +- kernel/include/3rd/multiboot2.h | 650 +++++++++++++++----------------- kernel/include/kasm.h | 10 +- kernel/include/khal.h | 9 +- kernel/include/kreflock.h | 4 +- kernel/include/kstring.h | 4 +- kernel/kernel.c | 30 +- kernel/klibc/kstring.c | 42 --- kernel/klibc/printf.c | 136 +++---- kernel/klibc/reflock.c | 4 +- kernel/klibc/string.c | 18 +- kernel/multiboot2.c | 151 ++++---- kernel/sys/panic.c | 4 +- 18 files changed, 504 insertions(+), 596 deletions(-) delete mode 100644 kernel/klibc/kstring.c diff --git a/kernel/arch/amd64/cpu/control.c b/kernel/arch/amd64/cpu/control.c index 70121dc..f0f38e2 100644 --- a/kernel/arch/amd64/cpu/control.c +++ b/kernel/arch/amd64/cpu/control.c @@ -1,6 +1,6 @@ // NOTE: This file contains code derived from or inspired by: -// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. -// Copyright (c) 2023-2025 NotYourFox, sigsegv +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv // SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify @@ -64,5 +64,5 @@ void cpu_interrupt_lock_force_release() { } void cpu_halt() { - asm ("hlt"); + asm("hlt"); } \ No newline at end of file diff --git a/kernel/arch/amd64/cpu/state.c b/kernel/arch/amd64/cpu/state.c index 0dedc2c..2e50fc0 100644 --- a/kernel/arch/amd64/cpu/state.c +++ b/kernel/arch/amd64/cpu/state.c @@ -4,7 +4,8 @@ void cpu_state_print() { asm_regs_t current_state; - serial_printf("The following register dump is a stub and a work-in-progress.\n"); + serial_printf( + "The following register dump is a stub and a work-in-progress.\n"); update_asm_regs(¤t_state); serial_printf("Registers:\n"); @@ -43,5 +44,5 @@ void cpu_state_print() { // } // serial_printf("\n"); - serial_printf("\n"); + serial_printf("\n"); } diff --git a/kernel/arch/amd64/idt.c b/kernel/arch/amd64/idt.c index 8748efe..ecef2de 100644 --- a/kernel/arch/amd64/idt.c +++ b/kernel/arch/amd64/idt.c @@ -1,10 +1,11 @@ -#include +#include "kstdint.h" // From https://wiki.osdev.org/Interrupt_Descriptor_Table#Structure_on_x86-64 struct idt_64 { - uint16_t offset_1; // offset bits 0..15 - uint16_t selector; // a code segment selector in GDT or LDT - uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. + uint16_t offset_1; // offset bits 0..15 + uint16_t selector; // a code segment selector in GDT or LDT + uint8_t + ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. uint8_t type_attributes; // gate type, dpl, and p fields uint16_t offset_2; // offset bits 16..31 uint32_t offset_3; // offset bits 32..63 diff --git a/kernel/arch/amd64/paging.c b/kernel/arch/amd64/paging.c index 2ca544d..f36bb88 100644 --- a/kernel/arch/amd64/paging.c +++ b/kernel/arch/amd64/paging.c @@ -1,7 +1,7 @@ -#include +#include "kstdint.h" uint64_t paging_main[3][512] __attribute__((aligned(4096))) = { 0 }; -int paging_init( ) { +int paging_init() { return -1; } \ No newline at end of file diff --git a/kernel/arch/amd64/serial.c b/kernel/arch/amd64/serial.c index d22c49a..6e9a6cc 100644 --- a/kernel/arch/amd64/serial.c +++ b/kernel/arch/amd64/serial.c @@ -1,14 +1,13 @@ -#include -#include +#include "kasm.h" +#include "kstdint.h" void serial_write_byte(uint8_t byte) { // Wait until the transmit holding register is empty - while ((inb(0x3f8 + 5) & 0x20) == 0) - ; + while ((inb(0x3f8 + 5) & 0x20) == 0); outb(0x3f8, byte); } -int serial_init( ) { +int serial_init() { // Disable all interrupts outb(0x3f8 + 1, 0x00); @@ -19,7 +18,8 @@ int serial_init( ) { outb(0x3f8, 0x0C); // Low byte of divisor outb(0x3f8 + 1, 0x00); // High byte of divisor (0 for divisor < 256) - // Disable DLAB and set communication parameters: 8n1 (8 bits, no parity, 1 stop bit) + // Disable DLAB and set communication parameters: 8n1 (8 bits, no parity, 1 + // stop bit) outb(0x3f8 + 3, 0x03); // Enable FIFOs diff --git a/kernel/cpio.c b/kernel/cpio.c index f967fe6..c270444 100644 --- a/kernel/cpio.c +++ b/kernel/cpio.c @@ -1,4 +1,4 @@ -#include +#include "kstdint.h" // We need memory manager and kernel lib first #if 0 diff --git a/kernel/include/3rd/multiboot2.h b/kernel/include/3rd/multiboot2.h index 9ea887b..ce4901f 100644 --- a/kernel/include/3rd/multiboot2.h +++ b/kernel/include/3rd/multiboot2.h @@ -14,70 +14,71 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY - * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #ifndef MULTIBOOT_HEADER #define MULTIBOOT_HEADER 1 /* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 32768 -#define MULTIBOOT_HEADER_ALIGN 8 +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 /* The magic field should contain this. */ -#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 /* This should be in %eax. */ -#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 /* Alignment of multiboot modules. */ -#define MULTIBOOT_MOD_ALIGN 0x00001000 +#define MULTIBOOT_MOD_ALIGN 0x00001000 /* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000008 +#define MULTIBOOT_INFO_ALIGN 0x00000008 /* Flags set in the ’flags’ member of the multiboot header. */ -#define MULTIBOOT_TAG_ALIGN 8 -#define MULTIBOOT_TAG_TYPE_END 0 -#define MULTIBOOT_TAG_TYPE_CMDLINE 1 -#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 -#define MULTIBOOT_TAG_TYPE_MODULE 3 -#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 -#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 -#define MULTIBOOT_TAG_TYPE_MMAP 6 -#define MULTIBOOT_TAG_TYPE_VBE 7 -#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 -#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 -#define MULTIBOOT_TAG_TYPE_APM 10 -#define MULTIBOOT_TAG_TYPE_EFI32 11 -#define MULTIBOOT_TAG_TYPE_EFI64 12 -#define MULTIBOOT_TAG_TYPE_SMBIOS 13 -#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 -#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 -#define MULTIBOOT_TAG_TYPE_NETWORK 16 -#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 -#define MULTIBOOT_TAG_TYPE_EFI_BS 18 -#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 -#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 -#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 - -#define MULTIBOOT_HEADER_TAG_END 0 -#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 -#define MULTIBOOT_HEADER_TAG_ADDRESS 2 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 -#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 -#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 -#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -#define MULTIBOOT_HEADER_TAG_EFI_BS 7 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 -#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 -#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 - -#define MULTIBOOT_ARCHITECTURE_I386 0 -#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 #define MULTIBOOT_HEADER_TAG_OPTIONAL 1 #define MULTIBOOT_LOAD_PREFERENCE_NONE 0 @@ -89,327 +90,290 @@ #ifndef ASM_FILE -typedef unsigned char multiboot_uint8_t; -typedef unsigned short multiboot_uint16_t; -typedef unsigned int multiboot_uint32_t; -typedef unsigned long long multiboot_uint64_t; - -struct multiboot_header -{ - /* Must be MULTIBOOT_MAGIC - see above. */ - multiboot_uint32_t magic; - - /* ISA */ - multiboot_uint32_t architecture; - - /* Total header length. */ - multiboot_uint32_t header_length; - - /* The above fields plus this one must equal 0 mod 2^32. */ - multiboot_uint32_t checksum; -}; - -struct multiboot_header_tag -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_information_request -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t requests[0]; -}; - -struct multiboot_header_tag_address -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t header_addr; - multiboot_uint32_t load_addr; - multiboot_uint32_t load_end_addr; - multiboot_uint32_t bss_end_addr; -}; - -struct multiboot_header_tag_entry_address -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t entry_addr; -}; - -struct multiboot_header_tag_console_flags -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t console_flags; -}; - -struct multiboot_header_tag_framebuffer -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t width; - multiboot_uint32_t height; - multiboot_uint32_t depth; -}; - -struct multiboot_header_tag_module_align -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; -}; - -struct multiboot_header_tag_relocatable -{ - multiboot_uint16_t type; - multiboot_uint16_t flags; - multiboot_uint32_t size; - multiboot_uint32_t min_addr; - multiboot_uint32_t max_addr; - multiboot_uint32_t align; - multiboot_uint32_t preference; -}; - -struct multiboot_color -{ - multiboot_uint8_t red; - multiboot_uint8_t green; - multiboot_uint8_t blue; -}; - -struct multiboot_mmap_entry -{ - multiboot_uint64_t addr; - multiboot_uint64_t len; -#define MULTIBOOT_MEMORY_AVAILABLE 1 -#define MULTIBOOT_MEMORY_RESERVED 2 -#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 -#define MULTIBOOT_MEMORY_NVS 4 -#define MULTIBOOT_MEMORY_BADRAM 5 - multiboot_uint32_t type; - multiboot_uint32_t zero; +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_relocatable { + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; +}; + +struct multiboot_color { + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry { + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; + multiboot_uint32_t zero; }; typedef struct multiboot_mmap_entry multiboot_memory_map_t; -struct multiboot_tag -{ - multiboot_uint32_t type; - multiboot_uint32_t size; +struct multiboot_tag { + multiboot_uint32_t type; + multiboot_uint32_t size; }; -struct multiboot_tag_string -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - char string[0]; +struct multiboot_tag_string { + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; }; -struct multiboot_tag_module -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mod_start; - multiboot_uint32_t mod_end; - char cmdline[0]; +struct multiboot_tag_module { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; }; -struct multiboot_tag_basic_meminfo -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; +struct multiboot_tag_basic_meminfo { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; }; -struct multiboot_tag_bootdev -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t biosdev; - multiboot_uint32_t slice; - multiboot_uint32_t part; +struct multiboot_tag_bootdev { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; }; -struct multiboot_tag_mmap -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t entry_size; - multiboot_uint32_t entry_version; - struct multiboot_mmap_entry entries[0]; +struct multiboot_tag_mmap { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; }; -struct multiboot_vbe_info_block -{ - multiboot_uint8_t external_specification[512]; +struct multiboot_vbe_info_block { + multiboot_uint8_t external_specification[512]; }; -struct multiboot_vbe_mode_info_block -{ - multiboot_uint8_t external_specification[256]; +struct multiboot_vbe_mode_info_block { + multiboot_uint8_t external_specification[256]; }; -struct multiboot_tag_vbe -{ - multiboot_uint32_t type; - multiboot_uint32_t size; +struct multiboot_tag_vbe { + multiboot_uint32_t type; + multiboot_uint32_t size; - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; - struct multiboot_vbe_info_block vbe_control_info; - struct multiboot_vbe_mode_info_block vbe_mode_info; + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; }; -struct multiboot_tag_framebuffer_common -{ - multiboot_uint32_t type; - multiboot_uint32_t size; +struct multiboot_tag_framebuffer_common { + multiboot_uint32_t type; + multiboot_uint32_t size; - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; #define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - multiboot_uint16_t reserved; -}; - -struct multiboot_tag_framebuffer -{ - struct multiboot_tag_framebuffer_common common; - - union - { - struct - { - multiboot_uint16_t framebuffer_palette_num_colors; - struct multiboot_color framebuffer_palette[0]; - }; - struct - { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; -}; - -struct multiboot_tag_elf_sections -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t num; - multiboot_uint32_t entsize; - multiboot_uint32_t shndx; - char sections[0]; -}; - -struct multiboot_tag_apm -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint16_t version; - multiboot_uint16_t cseg; - multiboot_uint32_t offset; - multiboot_uint16_t cseg_16; - multiboot_uint16_t dseg; - multiboot_uint16_t flags; - multiboot_uint16_t cseg_len; - multiboot_uint16_t cseg_16_len; - multiboot_uint16_t dseg_len; -}; - -struct multiboot_tag_efi32 -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64 -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_smbios -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t major; - multiboot_uint8_t minor; - multiboot_uint8_t reserved[6]; - multiboot_uint8_t tables[0]; -}; - -struct multiboot_tag_old_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_new_acpi -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t rsdp[0]; -}; - -struct multiboot_tag_network -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint8_t dhcpack[0]; -}; - -struct multiboot_tag_efi_mmap -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t descr_size; - multiboot_uint32_t descr_vers; - multiboot_uint8_t efi_mmap[0]; -}; - -struct multiboot_tag_efi32_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t pointer; -}; - -struct multiboot_tag_efi64_ih -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint64_t pointer; -}; - -struct multiboot_tag_load_base_addr -{ - multiboot_uint32_t type; - multiboot_uint32_t size; - multiboot_uint32_t load_base_addr; +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer { + struct multiboot_tag_framebuffer_common common; + + union { + struct { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_tag_elf_sections { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +struct multiboot_tag_efi32 { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +struct multiboot_tag_efi32_ih { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64_ih { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_load_base_addr { + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; }; #endif /* ! ASM_FILE */ diff --git a/kernel/include/kasm.h b/kernel/include/kasm.h index 0dba1b8..85dbd01 100644 --- a/kernel/include/kasm.h +++ b/kernel/include/kasm.h @@ -1,7 +1,7 @@ #ifndef __K_ASM #define __K_ASM -#include +#include "kstdint.h" #if defined(__x86_64__) static inline void outb(uint16_t port, uint8_t val) { @@ -35,21 +35,21 @@ static inline unsigned int inl(uint16_t port) { } // https://wiki.osdev.org/Inline_Assembly/Examples -static inline void io_wait( ) { +static inline void io_wait() { outb(0x80, 0); } -static inline void lidt(void* base, uint16_t size) { +static inline void lidt(void *base, uint16_t size) { // This function works in 32 and 64bit mode struct { uint16_t length; - void* base; + void *base; } __attribute__((packed)) IDTR = { size, base }; asm("lidt %0" : : "m"(IDTR)); // let the compiler choose an addressing mode } -static inline uint64_t rdtsc( ) { +static inline uint64_t rdtsc() { uint32_t low, high; asm volatile("rdtsc" : "=a"(low), "=d"(high)); return ((uint64_t)high << 32) | low; diff --git a/kernel/include/khal.h b/kernel/include/khal.h index ac45d20..4539746 100644 --- a/kernel/include/khal.h +++ b/kernel/include/khal.h @@ -1,16 +1,17 @@ #ifndef __K_HAL #define __K_HAL -#include -#include +#include "kasm.h" +#include "kstdint.h" #if defined(__x86_64__) extern uint64_t paging_main[3][512] __attribute__((aligned(4096))); void serial_write_byte(uint8_t byte); -int serial_init( ); -void serial_printf(const char *fmt, ...) ; +int serial_init(); +void __attribute__((format(printf, 1, 2))) +serial_printf(const char *restrict fmt, ...); #else #error "Only AMD64 is supported" diff --git a/kernel/include/kreflock.h b/kernel/include/kreflock.h index 8e38073..b1fd26f 100644 --- a/kernel/include/kreflock.h +++ b/kernel/include/kreflock.h @@ -1,6 +1,6 @@ // NOTE: This file contains code derived from or inspired by: -// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. -// Copyright (c) 2023-2025 NotYourFox, sigsegv +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv // SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify diff --git a/kernel/include/kstring.h b/kernel/include/kstring.h index d2885b2..203a0a0 100644 --- a/kernel/include/kstring.h +++ b/kernel/include/kstring.h @@ -2,8 +2,8 @@ #define __K_STRING #include "kopsize.h" -#include #include +#include #define string_equal(s1, s2) !strcmp(s1, s2) #define string_equal_n(s1, s2, n) !strncmp(s1, s2, n) @@ -12,7 +12,7 @@ void memset(void *ptr, char c, size_t size); void memcpy(void *dest, const void *src, size_t size); void xmemcpy(void *dest, const void *src, size_t size, opsize_t opsize); -int memcmp(const void* ptr1, const void* ptr2, size_t count); +int memcmp(const void *ptr1, const void *ptr2, size_t count); #define _tolower(c) ((c) | 0x20) diff --git a/kernel/kernel.c b/kernel/kernel.c index 56cd91b..4402c7a 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,13 +1,15 @@ -#include -#include -#include +#include "khal.h" +#include "kstdint.h" +#include "kstring.h" +#include "sys/panic.h" int multiboot2_init(uint64_t *addr, uint32_t magic); -void kernel_main64(uint64_t *multiboot2, uint32_t magic, void *esp, uint64_t base) { - serial_init( ); +void kernel_main64(uint64_t *multiboot2, uint32_t magic, void *esp, + uint64_t base) { + serial_init(); serial_printf(":D\n"); - + int status = multiboot2_init(multiboot2, magic); if (status) { @@ -15,18 +17,8 @@ void kernel_main64(uint64_t *multiboot2, uint32_t magic, void *esp, uint64_t bas } else { serial_printf("[ERR]\n"); } - char *str1 = "ABCF"; - char *str2 = "ABCD"; - char buf[7] = ""; - auto cmp_value = strcmp(str1, str2); - - serial_printf("[LOG] STR1 AND STR2 CMP %d\n", cmp_value); - serial_printf("[LOG] STR1 LEN %d\n", strlen(str1)); - strcpy((char*)&buf, str1); - serial_printf("[LOG] STRCPY RESULT: %s\n", buf); - serial_printf("[LOG] STRCPY RESULT LEN %d\n", strlen(buf)); - strcat((char*)&buf, "CAT"); - serial_printf("[LOG] STRCAT RESULT: %s\n", buf); - serial_printf("[LOG] STRCAT RESULT LEN %d\n", strlen(buf)); + + panic("AAAAAAAAAAAAAAAaa"); + for (;;) {} } diff --git a/kernel/klibc/kstring.c b/kernel/klibc/kstring.c deleted file mode 100644 index 397969b..0000000 --- a/kernel/klibc/kstring.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include - -int strcmp(const char *s1, const char *s2) -{ - for (int i = 0;; i++) - { - if (s1[i] > s2[i]) - { - return 1; - } - else if (s1[i] < s2[i]) - { - return -1; // INT сломан, тут он возращает maxValue. - } - if (s1[i] == '\0' || s2[i] == '\0') - { - return 0; - } - } -} - -char *strcpy(char *dst, const char *src) -{ - char *buf = dst; - while ((*dst++ = *src++) != '\0'); // Задаем по байту в dst из src, пока результатом этого не станет NUL - return buf; -} - -int strlen(const char *s) -{ - int i; - for (i = 0; s[i] != '\0'; i++); // Добавляем к i, пока не встретим NUL - return i; -} - -char *strcat(char *dst, const char *src) -{ - char *buf = dst; - strcpy(dst+strlen(dst), src); // Копируем строку в цель со смешением в длинну dst - return buf; -} diff --git a/kernel/klibc/printf.c b/kernel/klibc/printf.c index 7b2885d..f239ce9 100644 --- a/kernel/klibc/printf.c +++ b/kernel/klibc/printf.c @@ -1,80 +1,68 @@ +#include "khal.h" +#include "kstdint.h" #include -#include -#include static char *itoa(uint64_t value, char *buf, uint8_t base) { - char *ptr = buf; - uint64_t temp = value; - do { - uint64_t digit = temp % base; - if (digit < 10) - *ptr = '0' + digit; - else - *ptr = 'A' + (digit - 10); - ptr++; - temp /= base; - } while (temp); - *ptr = '\0'; - // Reverse the string - char *start = buf; - char *end = ptr - 1; - while (start < end) { - char tmp = *start; - *start = *end; - *end = tmp; - start++; - end--; - } - return buf; + char *ptr = buf; + uint64_t temp = value; + do { + uint64_t digit = temp % base; + if (digit < 10) + *ptr = '0' + digit; + else + *ptr = 'A' + (digit - 10); + ptr++; + temp /= base; + } while (temp); + *ptr = '\0'; + // Reverse the string + char *start = buf; + char *end = ptr - 1; + while (start < end) { + char tmp = *start; + *start = *end; + *end = tmp; + start++; + end--; + } + return buf; } -void serial_printf(const char *fmt, ...) { - char buf[32]; - va_list args; - va_start(args, fmt); - while (*fmt) { - if (*fmt == '%') { - fmt++; - switch (*fmt) { - case 's': - { - char *str = va_arg(args, char *); - while (*str) - serial_write_byte(*str++); - } - break; - case 'd': - { - int64_t num = va_arg(args, int64_t); - itoa(num, buf, 10); - serial_printf("%s", buf); - } - break; - case 'u': - { - uint64_t num = va_arg(args, uint64_t); - itoa(num, buf, 10); - serial_printf("%s", buf); - } - break; - case 'x': - { - uint64_t num = va_arg(args, uint64_t); - itoa(num, buf, 16); - serial_printf("%s", buf); - } - break; - case 'c': - serial_write_byte(va_arg(args, int)); - break; - default: - serial_write_byte(*fmt); - break; - } - fmt++; - } else { - serial_write_byte(*fmt++); - } - } - va_end(args); +// TODO: normalize +void __attribute__((format(printf, 1, 2))) serial_printf(const char *fmt, ...) { + char buf[32]; + va_list args; + va_start(args, fmt); + while (*fmt) { + if (*fmt == '%') { + fmt++; + switch (*fmt) { + case 's': { + char *str = va_arg(args, char *); + while (*str) serial_write_byte(*str++); + } break; + case 'd': { + int64_t num = va_arg(args, int64_t); + itoa(num, buf, 10); + serial_printf("%s", buf); + } break; + case 'u': { + uint64_t num = va_arg(args, uint64_t); + itoa(num, buf, 10); + serial_printf("%s", buf); + } break; + case 'x': { + uint64_t num = va_arg(args, uint64_t); + itoa(num, buf, 16); + serial_printf("%s", buf); + } break; + case 'c': serial_write_byte(va_arg(args, int)); break; + default: serial_write_byte(*fmt); break; + } + fmt++; + } else { + serial_write_byte(*fmt++); + } + } + va_end(args); } diff --git a/kernel/klibc/reflock.c b/kernel/klibc/reflock.c index 5eaa8ce..a637b04 100644 --- a/kernel/klibc/reflock.c +++ b/kernel/klibc/reflock.c @@ -1,6 +1,6 @@ // NOTE: This file contains code derived from or inspired by: -// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. -// Copyright (c) 2023-2025 NotYourFox, sigsegv +// AstriX ("The AstriX Operating System") at https://codeberg.org/AstriX/AstriX. +// Copyright (c) 2023-2025 NotYourFox, sigsegv // SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify diff --git a/kernel/klibc/string.c b/kernel/klibc/string.c index 6a0a1b9..99a6971 100644 --- a/kernel/klibc/string.c +++ b/kernel/klibc/string.c @@ -72,17 +72,17 @@ void memcpy(void *dest, const void *src, size_t size) { xmemcpy(dest, src, size, OPSIZE_BYTE); } -int memcmp(const void* ptr1, const void* ptr2, size_t count) { - register const unsigned char* p1 = ptr1; - register const unsigned char* p2 = ptr2; +int memcmp(const void *ptr1, const void *ptr2, size_t count) { + register const unsigned char *p1 = ptr1; + register const unsigned char *p2 = ptr2; - while (count-- > 0) { - if (*p1++ != *p2++) { - return p1[-1] < p2[-1] ? -1 : 1; - } - } + while (count-- > 0) { + if (*p1++ != *p2++) { + return p1[-1] < p2[-1] ? -1 : 1; + } + } - return 0; + return 0; } size_t __attribute__((pure)) strlen(const char *s) { diff --git a/kernel/multiboot2.c b/kernel/multiboot2.c index ac2d7dc..6c72110 100644 --- a/kernel/multiboot2.c +++ b/kernel/multiboot2.c @@ -1,7 +1,7 @@ +#include "khal.h" +#include "kstdint.h" +#include "kstdlib.h" #include <3rd/multiboot2.h> -#include -#include -#include #define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit))) @@ -12,90 +12,93 @@ void handle_basic_meminfo_tag(struct multiboot_tag *tag); void handle_mmap_tag(struct multiboot_tag *tag); int multiboot2_init(uint64_t *addr, uint32_t magic) { - struct multiboot_tag *tag; - uint64_t mbi_addr = (uint64_t)addr; - - if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) { - serial_printf("Invalid magic number: 0x%x\n", (unsigned)magic); - return -1; - } - - if (mbi_addr & 7) { - serial_printf("Unaligned mbi: 0x%x\n", mbi_addr); - return -2; - } - - uint64_t size = *addr; - serial_printf("Announced mbi size 0x%x\n", size); - - tag = (struct multiboot_tag *)(mbi_addr + sizeof(uint64_t)); - - while (tag->type != MULTIBOOT_TAG_TYPE_END) { - if ((uintptr_t)tag % MULTIBOOT_TAG_ALIGN != 0) { - serial_printf("Tag at 0x%x is not aligned correctly\n", (uintptr_t)tag); - break; - } - - switch (tag->type) { - case MULTIBOOT_TAG_TYPE_CMDLINE: - handle_cmdline_tag(tag); - break; - case MULTIBOOT_TAG_TYPE_MODULE: - handle_module_tag(tag); - break; - case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: - handle_basic_meminfo_tag(tag); - break; - case MULTIBOOT_TAG_TYPE_MMAP: - handle_mmap_tag(tag); - break; - case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: - handle_basic_load_base_addr(tag); - break; - default: - serial_printf("Tag at 0x%x | %d\n", (uintptr_t)tag, tag->type); - break; - } - - // Move to the next tag - tag = (struct multiboot_tag *)((uintptr_t)tag) + ((tag->size + 7) & ~7); - } - - return 1; + struct multiboot_tag *tag; + uint64_t mbi_addr = (uint64_t)addr; + + if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) { + serial_printf("Invalid magic number: 0x%x\n", (unsigned)magic); + return -1; + } + + if (mbi_addr & 7) { + serial_printf("Unaligned mbi: 0x%x\n", mbi_addr); + return -2; + } + + uint64_t size = *addr; + serial_printf("Announced mbi size 0x%x\n", size); + + tag = (struct multiboot_tag *)(mbi_addr + sizeof(uint64_t)); + + while (tag->type != MULTIBOOT_TAG_TYPE_END) { + if ((uintptr_t)tag % MULTIBOOT_TAG_ALIGN != 0) { + serial_printf("Tag at 0x%x is not aligned correctly\n", + (uintptr_t)tag); + break; + } + + switch (tag->type) { + case MULTIBOOT_TAG_TYPE_CMDLINE: handle_cmdline_tag(tag); break; + case MULTIBOOT_TAG_TYPE_MODULE: handle_module_tag(tag); break; + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + handle_basic_meminfo_tag(tag); + break; + case MULTIBOOT_TAG_TYPE_MMAP: handle_mmap_tag(tag); break; + case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: + handle_basic_load_base_addr(tag); + break; + default: + serial_printf("Tag at 0x%x | %d\n", (uintptr_t)tag, tag->type); + break; + } + + // Move to the next tag + tag = (struct multiboot_tag *)((uintptr_t)tag) + ((tag->size + 7) & ~7); + } + + return 1; } void handle_cmdline_tag(struct multiboot_tag *tag) { - struct multiboot_tag_string *cmdline = (struct multiboot_tag_string *)tag; - serial_printf("Command line: %s\n", cmdline->string); + struct multiboot_tag_string *cmdline = (struct multiboot_tag_string *)tag; + serial_printf("Command line: %s\n", cmdline->string); } void handle_module_tag(struct multiboot_tag *tag) { - struct multiboot_tag_module *module = (struct multiboot_tag_module *)tag; - serial_printf("Module at 0x%x - 0x%x\n", module->mod_start, module->mod_end); - serial_printf("Module cmdline: %s\n", module->cmdline); + struct multiboot_tag_module *module = (struct multiboot_tag_module *)tag; + serial_printf("Module at 0x%x - 0x%x\n", module->mod_start, + module->mod_end); + serial_printf("Module cmdline: %s\n", module->cmdline); } void handle_basic_meminfo_tag(struct multiboot_tag *tag) { - struct multiboot_tag_basic_meminfo *meminfo = (struct multiboot_tag_basic_meminfo *)tag; - serial_printf("Memory lower: %u KB\n", meminfo->mem_lower); - serial_printf("Memory upper: %u KB\n", meminfo->mem_upper); + struct multiboot_tag_basic_meminfo *meminfo = + (struct multiboot_tag_basic_meminfo *)tag; + serial_printf("Memory lower: %u KB\n", meminfo->mem_lower); + serial_printf("Memory upper: %u KB\n", meminfo->mem_upper); } void handle_basic_load_base_addr(struct multiboot_tag *tag) { - struct multiboot_tag_load_base_addr *base_addr = (struct multiboot_tag_load_base_addr *)tag; - serial_printf("load_base_size: %u\n", base_addr->size); - serial_printf("load_base_addr: 0x%x\n", base_addr->load_base_addr); + struct multiboot_tag_load_base_addr *base_addr = + (struct multiboot_tag_load_base_addr *)tag; + serial_printf("load_base_size: %u\n", base_addr->size); + serial_printf("load_base_addr: 0x%x\n", base_addr->load_base_addr); } void handle_mmap_tag(struct multiboot_tag *tag) { - struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap *)tag; - struct multiboot_mmap_entry *entry; - uint64_t entry_size = mmap->entry_size; - uint64_t entry_count = (mmap->size - sizeof(struct multiboot_tag_mmap)) / entry_size; - - serial_printf("Memory map:\n"); - for (uint64_t i = 0; i < entry_count; i++) { - entry = (struct multiboot_mmap_entry *)((uintptr_t)mmap + sizeof(struct multiboot_tag_mmap) + i * entry_size); - serial_printf(" 0x%x - 0x%x: type %u\n", entry->addr, entry->addr + entry->len, entry->type); - } + struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap *)tag; + struct multiboot_mmap_entry *entry; + uint64_t entry_size = mmap->entry_size; + uint64_t entry_count = + (mmap->size - sizeof(struct multiboot_tag_mmap)) / entry_size; + + serial_printf("Memory map:\n"); + for (uint64_t i = 0; i < entry_count; i++) { + entry = + (struct multiboot_mmap_entry *)((uintptr_t)mmap + + sizeof(struct multiboot_tag_mmap) + + i * entry_size); + serial_printf(" 0x%x - 0x%x: type %u\n", entry->addr, + entry->addr + entry->len, entry->type); + } } \ No newline at end of file diff --git a/kernel/sys/panic.c b/kernel/sys/panic.c index 735ee64..b264a68 100644 --- a/kernel/sys/panic.c +++ b/kernel/sys/panic.c @@ -1,6 +1,6 @@ -#include "khal.h" -#include "arch/cpu/state.h" #include "arch/cpu/control.h" +#include "arch/cpu/state.h" +#include "khal.h" #include // TODO: make printf-like From 166e07834e828ea73d30f880a5f8f3f32db889ae Mon Sep 17 00:00:00 2001 From: NotYourFox Date: Tue, 14 Jan 2025 00:42:40 +0300 Subject: [PATCH 10/10] Revert AT&T syntax in regs.S --- kernel/arch/amd64/cpu/regs.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/arch/amd64/cpu/regs.S b/kernel/arch/amd64/cpu/regs.S index f22bbda..3bae2cc 100644 --- a/kernel/arch/amd64/cpu/regs.S +++ b/kernel/arch/amd64/cpu/regs.S @@ -1,7 +1,5 @@ #define __ASSEMBLY__ -.intel_syntax noprefix - #include "arch/cpu/tables.h" .code64 @@ -10,13 +8,13 @@ get_flags: pushfd - mov rax, [rsp] + movq (%rsp), %rax popfd ret get_rip: - mov rax, [rsp] + movq (%rsp), %rax ret // TODO because I'm not familiar with x86-64 conventions