mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 02:16:58 +00:00
src/kernel --> src/
This commit is contained in:
2405
src/core/cmd.c
Normal file
2405
src/core/cmd.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/core/cmd.h
Normal file
31
src/core/cmd.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef CMD_H
|
||||
#define CMD_H
|
||||
|
||||
#include "wm.h"
|
||||
|
||||
extern Window win_cmd;
|
||||
|
||||
void cmd_init(void);
|
||||
void cmd_reset(void);
|
||||
|
||||
// IO Functions
|
||||
void cmd_write(const char *str);
|
||||
void cmd_putchar(char c);
|
||||
void cmd_write_int(int n);
|
||||
void cmd_write_hex(uint64_t n);
|
||||
int cmd_get_cursor_col(void);
|
||||
void cmd_screen_clear(void);
|
||||
|
||||
void cmd_increment_msg_count(void);
|
||||
void cmd_reset_msg_count(void);
|
||||
|
||||
void cmd_handle_resize(Window *win, int w, int h);
|
||||
void cmd_handle_click(Window *win, int x, int y);
|
||||
|
||||
uint32_t cmd_get_config_value(const char *key);
|
||||
void cmd_set_current_color(uint32_t color);
|
||||
|
||||
#endif
|
||||
43
src/core/io.h
Normal file
43
src/core/io.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void outb(uint16_t port, uint8_t val) {
|
||||
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline void outw(uint16_t port, uint16_t val) {
|
||||
asm volatile ("outw %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline uint16_t inw(uint16_t port) {
|
||||
uint16_t ret;
|
||||
asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void outl(uint16_t port, uint32_t val) {
|
||||
asm volatile ("outl %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline uint32_t inl(uint16_t port) {
|
||||
uint32_t ret;
|
||||
asm volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void io_wait(void) {
|
||||
outb(0x80, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
126
src/core/kutils.c
Normal file
126
src/core/kutils.c
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include "kutils.h"
|
||||
#include "wm.h"
|
||||
#include "io.h"
|
||||
|
||||
void k_memset(void *dest, int val, size_t len) {
|
||||
unsigned char *ptr = (unsigned char *)dest;
|
||||
while (len-- > 0) *ptr++ = (unsigned char)val;
|
||||
}
|
||||
|
||||
void k_memcpy(void *dest, const void *src, size_t len) {
|
||||
unsigned char *d = (unsigned char *)dest;
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
while (len-- > 0) *d++ = *s++;
|
||||
}
|
||||
|
||||
size_t k_strlen(const char *str) {
|
||||
size_t len = 0;
|
||||
while (str[len]) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
int k_strcmp(const char *s1, const char *s2) {
|
||||
while (*s1 && (*s1 == *s2)) {
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return *(const unsigned char*)s1 - *(const unsigned char*)s2;
|
||||
}
|
||||
|
||||
void k_strcpy(char *dest, const char *src) {
|
||||
while (*src) *dest++ = *src++;
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
int k_atoi(const char *str) {
|
||||
int res = 0;
|
||||
int sign = 1;
|
||||
if (*str == '-') { sign = -1; str++; }
|
||||
while (*str >= '0' && *str <= '9') {
|
||||
res = res * 10 + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
return res * sign;
|
||||
}
|
||||
|
||||
void k_itoa(int n, char *buf) {
|
||||
if (n == 0) {
|
||||
buf[0] = '0'; buf[1] = 0; return;
|
||||
}
|
||||
int i = 0;
|
||||
int sign = n < 0;
|
||||
if (sign) n = -n;
|
||||
while (n > 0) {
|
||||
buf[i++] = (n % 10) + '0';
|
||||
n /= 10;
|
||||
}
|
||||
if (sign) buf[i++] = '-';
|
||||
buf[i] = 0;
|
||||
for (int j = 0; j < i / 2; j++) {
|
||||
char t = buf[j];
|
||||
buf[j] = buf[i - 1 - j];
|
||||
buf[i - 1 - j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void k_itoa_hex(uint64_t n, char *buf) {
|
||||
const char *digits = "0123456789ABCDEF";
|
||||
if (n == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = 0;
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
while (n > 0) {
|
||||
buf[i++] = digits[n & 0xF];
|
||||
n >>= 4;
|
||||
}
|
||||
buf[i] = 0;
|
||||
for (int j = 0; j < i / 2; j++) {
|
||||
char t = buf[j];
|
||||
buf[j] = buf[i - 1 - j];
|
||||
buf[i - 1 - j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void k_delay(int iterations) {
|
||||
for (volatile int i = 0; i < iterations; i++) {
|
||||
__asm__ __volatile__("nop");
|
||||
}
|
||||
}
|
||||
|
||||
void k_sleep(int ms) {
|
||||
// Timer is ~60Hz, so 1 tick = 16.66ms
|
||||
uint32_t ticks = ms / 16;
|
||||
if (ticks == 0 && ms > 0) ticks = 1;
|
||||
|
||||
uint32_t target = wm_get_ticks() + ticks;
|
||||
while (wm_get_ticks() < target) {
|
||||
__asm__ __volatile__("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
void k_reboot(void) {
|
||||
outb(0x64, 0xFE);
|
||||
}
|
||||
|
||||
void k_shutdown(void) {
|
||||
outw(0xB004, 0x2000); // QEMU older / some pc machines
|
||||
outw(0x604, 0x2000); // QEMU newer (i440fx/q35)
|
||||
outw(0x4004, 0x3400); // VirtualBox fallback
|
||||
}
|
||||
|
||||
void k_beep(int freq, int ms) {
|
||||
if (freq <= 0) return;
|
||||
int div = 1193180 / freq;
|
||||
outb(0x43, 0xB6);
|
||||
outb(0x42, div & 0xFF);
|
||||
outb(0x42, (div >> 8) & 0xFF);
|
||||
outb(0x61, inb(0x61) | 0x03);
|
||||
k_sleep(ms);
|
||||
outb(0x61, inb(0x61) & 0xFC);
|
||||
}
|
||||
|
||||
27
src/core/kutils.h
Normal file
27
src/core/kutils.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef KUTILS_H
|
||||
#define KUTILS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Kernel string utilities
|
||||
void k_memset(void *dest, int val, size_t len);
|
||||
void k_memcpy(void *dest, const void *src, size_t len);
|
||||
size_t k_strlen(const char *str);
|
||||
int k_strcmp(const char *s1, const char *s2);
|
||||
void k_strcpy(char *dest, const char *src);
|
||||
int k_atoi(const char *str);
|
||||
void k_itoa(int n, char *buf);
|
||||
void k_itoa_hex(uint64_t n, char *buf);
|
||||
|
||||
// Kernel timing utilities
|
||||
void k_delay(int iterations);
|
||||
void k_sleep(int ms);
|
||||
void k_reboot(void);
|
||||
void k_shutdown(void);
|
||||
void k_beep(int freq, int ms);
|
||||
|
||||
#endif
|
||||
579
src/core/limine.h
Normal file
579
src/core/limine.h
Normal file
@@ -0,0 +1,579 @@
|
||||
/* BSD Zero Clause License */
|
||||
|
||||
/* Copyright (C) 2022-2023 mintsuki and contributors.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIMINE_H
|
||||
#define _LIMINE_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Misc */
|
||||
|
||||
#ifdef LIMINE_NO_POINTERS
|
||||
# define LIMINE_PTR(TYPE) uint64_t
|
||||
#else
|
||||
# define LIMINE_PTR(TYPE) TYPE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define LIMINE_DEPRECATED __attribute__((__deprecated__))
|
||||
# define LIMINE_DEPRECATED_IGNORE_START \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
# define LIMINE_DEPRECATED_IGNORE_END \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
# define LIMINE_DEPRECATED
|
||||
# define LIMINE_DEPRECATED_IGNORE_START
|
||||
# define LIMINE_DEPRECATED_IGNORE_END
|
||||
#endif
|
||||
|
||||
#define LIMINE_BASE_REVISION(N) \
|
||||
uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) };
|
||||
|
||||
#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0)
|
||||
|
||||
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
|
||||
|
||||
struct limine_uuid {
|
||||
uint32_t a;
|
||||
uint16_t b;
|
||||
uint16_t c;
|
||||
uint8_t d[8];
|
||||
};
|
||||
|
||||
#define LIMINE_MEDIA_TYPE_GENERIC 0
|
||||
#define LIMINE_MEDIA_TYPE_OPTICAL 1
|
||||
#define LIMINE_MEDIA_TYPE_TFTP 2
|
||||
|
||||
struct limine_file {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
uint64_t size;
|
||||
LIMINE_PTR(char *) path;
|
||||
LIMINE_PTR(char *) cmdline;
|
||||
uint32_t media_type;
|
||||
uint32_t unused;
|
||||
uint32_t tftp_ip;
|
||||
uint32_t tftp_port;
|
||||
uint32_t partition_index;
|
||||
uint32_t mbr_disk_id;
|
||||
struct limine_uuid gpt_disk_uuid;
|
||||
struct limine_uuid gpt_part_uuid;
|
||||
struct limine_uuid part_uuid;
|
||||
};
|
||||
|
||||
/* Boot info */
|
||||
|
||||
#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
|
||||
|
||||
struct limine_bootloader_info_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(char *) name;
|
||||
LIMINE_PTR(char *) version;
|
||||
};
|
||||
|
||||
struct limine_bootloader_info_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_bootloader_info_response *) response;
|
||||
};
|
||||
|
||||
/* Stack size */
|
||||
|
||||
#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
|
||||
|
||||
struct limine_stack_size_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct limine_stack_size_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_stack_size_response *) response;
|
||||
uint64_t stack_size;
|
||||
};
|
||||
|
||||
/* HHDM */
|
||||
|
||||
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
|
||||
|
||||
struct limine_hhdm_response {
|
||||
uint64_t revision;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
struct limine_hhdm_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_hhdm_response *) response;
|
||||
};
|
||||
|
||||
/* Framebuffer */
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_RGB 1
|
||||
|
||||
struct limine_video_mode {
|
||||
uint64_t pitch;
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
uint16_t bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
uint8_t red_mask_shift;
|
||||
uint8_t green_mask_size;
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
};
|
||||
|
||||
struct limine_framebuffer {
|
||||
LIMINE_PTR(void *) address;
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
uint64_t pitch;
|
||||
uint16_t bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
uint8_t red_mask_shift;
|
||||
uint8_t green_mask_size;
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
uint8_t unused[7];
|
||||
uint64_t edid_size;
|
||||
LIMINE_PTR(void *) edid;
|
||||
/* Response revision 1 */
|
||||
uint64_t mode_count;
|
||||
LIMINE_PTR(struct limine_video_mode **) modes;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_response {
|
||||
uint64_t revision;
|
||||
uint64_t framebuffer_count;
|
||||
LIMINE_PTR(struct limine_framebuffer **) framebuffers;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_framebuffer_response *) response;
|
||||
};
|
||||
|
||||
/* Terminal */
|
||||
|
||||
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 }
|
||||
|
||||
#define LIMINE_TERMINAL_CB_DEC 10
|
||||
#define LIMINE_TERMINAL_CB_BELL 20
|
||||
#define LIMINE_TERMINAL_CB_PRIVATE_ID 30
|
||||
#define LIMINE_TERMINAL_CB_STATUS_REPORT 40
|
||||
#define LIMINE_TERMINAL_CB_POS_REPORT 50
|
||||
#define LIMINE_TERMINAL_CB_KBD_LEDS 60
|
||||
#define LIMINE_TERMINAL_CB_MODE 70
|
||||
#define LIMINE_TERMINAL_CB_LINUX 80
|
||||
|
||||
#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1))
|
||||
#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2))
|
||||
#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3))
|
||||
#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4))
|
||||
|
||||
/* Response revision 1 */
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10))
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11))
|
||||
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6)
|
||||
#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7)
|
||||
|
||||
LIMINE_DEPRECATED_IGNORE_START
|
||||
|
||||
struct LIMINE_DEPRECATED limine_terminal;
|
||||
|
||||
typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t);
|
||||
typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
|
||||
struct LIMINE_DEPRECATED limine_terminal {
|
||||
uint64_t columns;
|
||||
uint64_t rows;
|
||||
LIMINE_PTR(struct limine_framebuffer *) framebuffer;
|
||||
};
|
||||
|
||||
struct LIMINE_DEPRECATED limine_terminal_response {
|
||||
uint64_t revision;
|
||||
uint64_t terminal_count;
|
||||
LIMINE_PTR(struct limine_terminal **) terminals;
|
||||
LIMINE_PTR(limine_terminal_write) write;
|
||||
};
|
||||
|
||||
struct LIMINE_DEPRECATED limine_terminal_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_terminal_response *) response;
|
||||
LIMINE_PTR(limine_terminal_callback) callback;
|
||||
};
|
||||
|
||||
LIMINE_DEPRECATED_IGNORE_END
|
||||
|
||||
/* Paging mode */
|
||||
|
||||
#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a }
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
#define LIMINE_PAGING_MODE_X86_64_4LVL 0
|
||||
#define LIMINE_PAGING_MODE_X86_64_5LVL 1
|
||||
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL
|
||||
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL
|
||||
#elif defined (__aarch64__)
|
||||
#define LIMINE_PAGING_MODE_AARCH64_4LVL 0
|
||||
#define LIMINE_PAGING_MODE_AARCH64_5LVL 1
|
||||
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL
|
||||
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL
|
||||
#elif defined (__riscv) && (__riscv_xlen == 64)
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV39 0
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV48 1
|
||||
#define LIMINE_PAGING_MODE_RISCV_SV57 2
|
||||
#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57
|
||||
#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
struct limine_paging_mode_response {
|
||||
uint64_t revision;
|
||||
uint64_t mode;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
struct limine_paging_mode_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_paging_mode_response *) response;
|
||||
uint64_t mode;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/* 5-level paging */
|
||||
|
||||
#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 }
|
||||
|
||||
LIMINE_DEPRECATED_IGNORE_START
|
||||
|
||||
struct LIMINE_DEPRECATED limine_5_level_paging_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct LIMINE_DEPRECATED limine_5_level_paging_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_5_level_paging_response *) response;
|
||||
};
|
||||
|
||||
LIMINE_DEPRECATED_IGNORE_END
|
||||
|
||||
/* SMP */
|
||||
|
||||
#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
|
||||
|
||||
struct limine_smp_info;
|
||||
|
||||
typedef void (*limine_goto_address)(struct limine_smp_info *);
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
|
||||
#define LIMINE_SMP_X2APIC (1 << 0)
|
||||
|
||||
struct limine_smp_info {
|
||||
uint32_t processor_id;
|
||||
uint32_t lapic_id;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_smp_response {
|
||||
uint64_t revision;
|
||||
uint32_t flags;
|
||||
uint32_t bsp_lapic_id;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_smp_info **) cpus;
|
||||
};
|
||||
|
||||
#elif defined (__aarch64__)
|
||||
|
||||
struct limine_smp_info {
|
||||
uint32_t processor_id;
|
||||
uint32_t gic_iface_no;
|
||||
uint64_t mpidr;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_smp_response {
|
||||
uint64_t revision;
|
||||
uint64_t flags;
|
||||
uint64_t bsp_mpidr;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_smp_info **) cpus;
|
||||
};
|
||||
|
||||
#elif defined (__riscv) && (__riscv_xlen == 64)
|
||||
|
||||
struct limine_smp_info {
|
||||
uint64_t processor_id;
|
||||
uint64_t hartid;
|
||||
uint64_t reserved;
|
||||
LIMINE_PTR(limine_goto_address) goto_address;
|
||||
uint64_t extra_argument;
|
||||
};
|
||||
|
||||
struct limine_smp_response {
|
||||
uint64_t revision;
|
||||
uint64_t flags;
|
||||
uint64_t bsp_hartid;
|
||||
uint64_t cpu_count;
|
||||
LIMINE_PTR(struct limine_smp_info **) cpus;
|
||||
};
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
struct limine_smp_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_smp_response *) response;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/* Memory map */
|
||||
|
||||
#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
|
||||
|
||||
#define LIMINE_MEMMAP_USABLE 0
|
||||
#define LIMINE_MEMMAP_RESERVED 1
|
||||
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
|
||||
#define LIMINE_MEMMAP_ACPI_NVS 3
|
||||
#define LIMINE_MEMMAP_BAD_MEMORY 4
|
||||
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
|
||||
#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6
|
||||
#define LIMINE_MEMMAP_FRAMEBUFFER 7
|
||||
|
||||
struct limine_memmap_entry {
|
||||
uint64_t base;
|
||||
uint64_t length;
|
||||
uint64_t type;
|
||||
};
|
||||
|
||||
struct limine_memmap_response {
|
||||
uint64_t revision;
|
||||
uint64_t entry_count;
|
||||
LIMINE_PTR(struct limine_memmap_entry **) entries;
|
||||
};
|
||||
|
||||
struct limine_memmap_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_memmap_response *) response;
|
||||
};
|
||||
|
||||
/* Entry point */
|
||||
|
||||
#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
|
||||
|
||||
typedef void (*limine_entry_point)(void);
|
||||
|
||||
struct limine_entry_point_response {
|
||||
uint64_t revision;
|
||||
};
|
||||
|
||||
struct limine_entry_point_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_entry_point_response *) response;
|
||||
LIMINE_PTR(limine_entry_point) entry;
|
||||
};
|
||||
|
||||
/* Kernel File */
|
||||
|
||||
#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
|
||||
|
||||
struct limine_kernel_file_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_file *) kernel_file;
|
||||
};
|
||||
|
||||
struct limine_kernel_file_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_kernel_file_response *) response;
|
||||
};
|
||||
|
||||
/* Module */
|
||||
|
||||
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
|
||||
|
||||
#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0)
|
||||
#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1)
|
||||
|
||||
struct limine_internal_module {
|
||||
LIMINE_PTR(const char *) path;
|
||||
LIMINE_PTR(const char *) cmdline;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
struct limine_module_response {
|
||||
uint64_t revision;
|
||||
uint64_t module_count;
|
||||
LIMINE_PTR(struct limine_file **) modules;
|
||||
};
|
||||
|
||||
struct limine_module_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_module_response *) response;
|
||||
|
||||
/* Request revision 1 */
|
||||
uint64_t internal_module_count;
|
||||
LIMINE_PTR(struct limine_internal_module **) internal_modules;
|
||||
};
|
||||
|
||||
/* RSDP */
|
||||
|
||||
#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
|
||||
|
||||
struct limine_rsdp_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
};
|
||||
|
||||
struct limine_rsdp_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_rsdp_response *) response;
|
||||
};
|
||||
|
||||
/* SMBIOS */
|
||||
|
||||
#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
|
||||
|
||||
struct limine_smbios_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) entry_32;
|
||||
LIMINE_PTR(void *) entry_64;
|
||||
};
|
||||
|
||||
struct limine_smbios_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_smbios_response *) response;
|
||||
};
|
||||
|
||||
/* EFI system table */
|
||||
|
||||
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
|
||||
|
||||
struct limine_efi_system_table_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) address;
|
||||
};
|
||||
|
||||
struct limine_efi_system_table_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_efi_system_table_response *) response;
|
||||
};
|
||||
|
||||
/* EFI memory map */
|
||||
|
||||
#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
|
||||
|
||||
struct limine_efi_memmap_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) memmap;
|
||||
uint64_t memmap_size;
|
||||
uint64_t desc_size;
|
||||
uint64_t desc_version;
|
||||
};
|
||||
|
||||
struct limine_efi_memmap_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_efi_memmap_response *) response;
|
||||
};
|
||||
|
||||
/* Boot time */
|
||||
|
||||
#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
|
||||
|
||||
struct limine_boot_time_response {
|
||||
uint64_t revision;
|
||||
int64_t boot_time;
|
||||
};
|
||||
|
||||
struct limine_boot_time_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_boot_time_response *) response;
|
||||
};
|
||||
|
||||
/* Kernel address */
|
||||
|
||||
#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
|
||||
|
||||
struct limine_kernel_address_response {
|
||||
uint64_t revision;
|
||||
uint64_t physical_base;
|
||||
uint64_t virtual_base;
|
||||
};
|
||||
|
||||
struct limine_kernel_address_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_kernel_address_response *) response;
|
||||
};
|
||||
|
||||
/* Device Tree Blob */
|
||||
|
||||
#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
|
||||
|
||||
struct limine_dtb_response {
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(void *) dtb_ptr;
|
||||
};
|
||||
|
||||
struct limine_dtb_request {
|
||||
uint64_t id[4];
|
||||
uint64_t revision;
|
||||
LIMINE_PTR(struct limine_dtb_response *) response;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
207
src/core/main.c
Normal file
207
src/core/main.c
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "limine.h"
|
||||
#include "graphics.h"
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include "paging.h"
|
||||
#include "syscall.h"
|
||||
#include "process.h"
|
||||
#include "ps2.h"
|
||||
#include "wm.h"
|
||||
#include "io.h"
|
||||
#include "fat32.h"
|
||||
#include "memory_manager.h"
|
||||
#include "platform.h"
|
||||
#include "wallpaper.h"
|
||||
|
||||
// --- Limine Requests ---
|
||||
__attribute__((used, section(".requests")))
|
||||
static volatile LIMINE_BASE_REVISION(2);
|
||||
|
||||
__attribute__((used, section(".requests")))
|
||||
static volatile struct limine_framebuffer_request framebuffer_request = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
||||
.revision = 1
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests")))
|
||||
static volatile struct limine_memmap_request memmap_request = {
|
||||
.id = LIMINE_MEMMAP_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests")))
|
||||
static volatile struct limine_module_request module_request = {
|
||||
.id = LIMINE_MODULE_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests_start")))
|
||||
static volatile struct limine_request *const requests_start_marker[] = {
|
||||
(struct limine_request *)&framebuffer_request,
|
||||
(struct limine_request *)&memmap_request,
|
||||
(struct limine_request *)&module_request,
|
||||
NULL
|
||||
};
|
||||
|
||||
__attribute__((used, section(".requests_end")))
|
||||
static volatile struct limine_request *const requests_end_marker[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static void hcf(void) {
|
||||
asm("cli");
|
||||
for (;;) {
|
||||
asm("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
static void init_serial() {
|
||||
outb(0x3F8 + 1, 0x00);
|
||||
outb(0x3F8 + 3, 0x80);
|
||||
outb(0x3F8 + 0, 0x03);
|
||||
outb(0x3F8 + 1, 0x00);
|
||||
outb(0x3F8 + 3, 0x03);
|
||||
outb(0x3F8 + 2, 0xC7);
|
||||
outb(0x3F8 + 4, 0x0B);
|
||||
}
|
||||
|
||||
void serial_write(const char *str) {
|
||||
while (*str) {
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_write_num(uint32_t n) {
|
||||
if (n >= 10) serial_write_num(n / 10);
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, '0' + (n % 10));
|
||||
}
|
||||
|
||||
void serial_write_hex(uint64_t n) {
|
||||
char *hex = "0123456789ABCDEF";
|
||||
if (n >= 16) serial_write_hex(n / 16);
|
||||
while ((inb(0x3F8 + 5) & 0x20) == 0);
|
||||
outb(0x3F8, hex[n % 16]);
|
||||
}
|
||||
|
||||
// Kernel Entry Point
|
||||
void kmain(void) {
|
||||
init_serial();
|
||||
serial_write("\n[DEBUG] Entering kmain...\n");
|
||||
|
||||
platform_init();
|
||||
serial_write("[DEBUG] platform_init OK\n");
|
||||
|
||||
extern uint64_t hhdm_offset;
|
||||
extern uint64_t kernel_phys_base;
|
||||
extern uint64_t kernel_virt_base;
|
||||
|
||||
serial_write("[DEBUG] HHDM Offset: 0x");
|
||||
serial_write_hex(hhdm_offset);
|
||||
serial_write("\n");
|
||||
serial_write("[DEBUG] Kernel Phys: 0x");
|
||||
serial_write_hex(kernel_phys_base);
|
||||
serial_write("\n");
|
||||
serial_write("[DEBUG] Kernel Virt: 0x");
|
||||
serial_write_hex(kernel_virt_base);
|
||||
serial_write("\n");
|
||||
|
||||
if (memmap_request.response != NULL) {
|
||||
// The memory manager will now scan the memory map and manage all usable regions.
|
||||
memory_manager_init_from_memmap(memmap_request.response);
|
||||
serial_write("[DEBUG] memory_manager_init OK\n");
|
||||
} else {
|
||||
serial_write("[DEBUG] ERROR: No usable memory for heap! Check Limine memmap.\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
|
||||
serial_write("[DEBUG] No framebuffer! Halting.\n");
|
||||
hcf();
|
||||
}
|
||||
|
||||
struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0];
|
||||
graphics_init(fb);
|
||||
serial_write("[DEBUG] graphics_init OK\n");
|
||||
|
||||
gdt_init();
|
||||
serial_write("[DEBUG] gdt_init OK\n");
|
||||
|
||||
paging_init();
|
||||
serial_write("[DEBUG] paging_init OK\n");
|
||||
|
||||
syscall_init();
|
||||
serial_write("[DEBUG] syscall_init OK\n");
|
||||
|
||||
idt_init();
|
||||
idt_register_interrupts();
|
||||
idt_load();
|
||||
serial_write("[DEBUG] idt_init OK\n");
|
||||
|
||||
process_init();
|
||||
|
||||
|
||||
fat32_init();
|
||||
serial_write("[DEBUG] fat32_init OK\n");
|
||||
fat32_mkdir("/bin");
|
||||
fat32_mkdir("/Library");
|
||||
fat32_mkdir("/Library/images");
|
||||
fat32_mkdir("/Library/images/Wallpapers");
|
||||
fat32_mkdir("/Library/images/gif");
|
||||
fat32_mkdir("/Library/Fonts");
|
||||
fat32_mkdir("/Library/DOOM");
|
||||
|
||||
if (module_request.response == NULL) {
|
||||
serial_write("[DEBUG] ERROR: Limine Module Response is NULL!\n");
|
||||
} else {
|
||||
serial_write("[DEBUG] Limine Module Response found. Count: ");
|
||||
serial_write_num(module_request.response->module_count);
|
||||
serial_write("\n");
|
||||
for (uint64_t i = 0; i < module_request.response->module_count; i++) {
|
||||
struct limine_file *mod = module_request.response->modules[i];
|
||||
|
||||
const char *clean_path = mod->path;
|
||||
if (fs_starts_with(clean_path, "boot():")) clean_path += 7;
|
||||
else if (fs_starts_with(clean_path, "boot:///")) clean_path += 8;
|
||||
|
||||
FAT32_FileHandle *fh = fat32_open(clean_path, "w");
|
||||
if (fh && fh->valid) {
|
||||
fat32_write(fh, mod->address, mod->size);
|
||||
fat32_close(fh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize fonts now that FAT32 and modules are loaded
|
||||
uint64_t current_rsp;
|
||||
asm volatile("mov %%rsp, %0" : "=r"(current_rsp));
|
||||
serial_write("[DEBUG] Stack Alignment: 0x");
|
||||
serial_write_hex(current_rsp);
|
||||
serial_write("\n");
|
||||
|
||||
graphics_init_fonts();
|
||||
|
||||
asm("cli");
|
||||
ps2_init();
|
||||
asm("sti");
|
||||
|
||||
wm_init();
|
||||
|
||||
asm volatile("sti");
|
||||
|
||||
|
||||
while (1) {
|
||||
wm_process_input();
|
||||
wm_process_deferred_thumbs();
|
||||
wallpaper_process_pending();
|
||||
asm("hlt");
|
||||
}
|
||||
}
|
||||
74
src/core/man_entries.h
Normal file
74
src/core/man_entries.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef MAN_ENTRIES_H
|
||||
#define MAN_ENTRIES_H
|
||||
|
||||
#include "fat32.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static size_t man_strlen(const char *str) {
|
||||
size_t len = 0;
|
||||
while (str[len]) len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
static void write_man_file(const char *name, const char *content) {
|
||||
char path[128] = "A:/Library/man/";
|
||||
int i = 15;
|
||||
while (*name) path[i++] = *name++;
|
||||
path[i++] = '.';
|
||||
path[i++] = 't';
|
||||
path[i++] = 'x';
|
||||
path[i++] = 't';
|
||||
path[i] = 0;
|
||||
|
||||
FAT32_FileHandle *fh = fat32_open(path, "w");
|
||||
if (fh) {
|
||||
fat32_write(fh, (void *)content, man_strlen(content));
|
||||
fat32_close(fh);
|
||||
}
|
||||
}
|
||||
|
||||
void create_man_entries(void) {
|
||||
fat32_mkdir("A:/Library");
|
||||
fat32_mkdir("A:/Library/man");
|
||||
|
||||
write_man_file("ping", "PING - Send ICMP echo requests\n\nUsage: ping <ip>\n\nSends ICMP echo requests to the specified IP address and displays the response times.");
|
||||
write_man_file("net", "NET - Network utilities\n\nUsage: net init\nnet info\nnet ipset >ip<\nnet udpsend >ip< >port< >message< net ping >ip< net help\n\nA collection of network-related commands.");
|
||||
write_man_file("ls", "LS - List directory contents\n\nUsage: ls [path]\n\nLists files and directories in the current or specified directory.");
|
||||
write_man_file("cat", "CAT - Concatenate and display file contents\n\nUsage: cat <filename>\n\nDisplays the text content of the specified file.");
|
||||
write_man_file("man", "MAN - Display manual pages\n\nUsage: man <command>\n\nDisplays help information for the specified command.");
|
||||
write_man_file("beep", "BEEP - Play system beep\n\nUsage: beep\n\nPlays a short tone through the PC speaker.");
|
||||
write_man_file("sweden", "SWEDEN - Play Swedish melody\n\nUsage: sweden\n\nPlays the Swedish national anthem through the PC speaker.");
|
||||
write_man_file("clear", "CLEAR - Clear terminal screen\n\nUsage: clear\n\nClears all text from the current terminal window.");
|
||||
write_man_file("date", "DATE - Show current date and time\n\nUsage: date\n\nDisplays the current system date and time from the RTC.");
|
||||
write_man_file("echo", "ECHO - Print text\n\nUsage: echo [text]\n\nPrints the specified text to the terminal.");
|
||||
write_man_file("hello", "HELLO - Hello World demo\n\nUsage: hello\n\nA simple demonstration program that prints a greeting.");
|
||||
write_man_file("help", "HELP - List available commands\n\nUsage: help\n\nLists all internal and external commands available in the shell.");
|
||||
write_man_file("uptime", "UPTIME - Show system uptime\n\nUsage: uptime\n\nDisplays how long BoredOS has been running since boot.");
|
||||
write_man_file("pwd", "PWD - Print working directory\n\nUsage: pwd\n\nDisplays the absolute path of the current working directory.");
|
||||
write_man_file("mkdir", "MKDIR - Create directory\n\nUsage: mkdir <dirname>\n\nCreates a new directory with the specified name.");
|
||||
write_man_file("rm", "RM - Remove file\n\nUsage: rm <filename>\n\nDeletes the specified file from the filesystem.");
|
||||
write_man_file("mv", "MV - Move or rename file\n\nUsage: mv <source> <dest>\n\nMoves or renames a file or directory.");
|
||||
write_man_file("cp", "CP - Copy file\n\nUsage: cp <source> <dest>\n\nCopies a file from the source path to the destination path.");
|
||||
write_man_file("touch", "TOUCH - Create empty file\n\nUsage: touch <filename>\n\nCreates a new empty file if it doesn't exist.");
|
||||
write_man_file("cc", "CC - C Compiler\n\nUsage: cc <file.c>\n\nThe BoredOS C Compiler. Compiles C source files into executables. (execute these with ./>file<)");
|
||||
write_man_file("crash", "CRASH - Trigger kernel exception\n\nUsage: crash\n\nIntentionally triggers a null pointer dereference to test handlers.");
|
||||
write_man_file("sysfetch", "SYSFETCH - Show OS information\n\nUsage: sysfetch\n\nDisplays system information in a neofetch-like layout. Configurable via A:/Library/conf/sysfetch.cfg.");
|
||||
write_man_file("meminfo", "MEMINFO - Memory usage stats\n\nUsage: meminfo\n\nDisplays current physical and virtual memory allocation statistics.");
|
||||
write_man_file("pci_list", "PCI_LIST - Scan PCI bus\n\nUsage: pci_list\n\nScans the PCI bus and lists all detected hardware devices.");
|
||||
write_man_file("reboot", "REBOOT - Restart system\n\nUsage: reboot\n\nRestarts the computer immediately.");
|
||||
write_man_file("shutdown", "SHUTDOWN - Power off\n\nUsage: shutdown\n\nPowers off the machine (requires ACPI support).");
|
||||
write_man_file("calculator", "CALCULATOR - Graphical calculator\n\nUsage: calculator\n\nOpens a simple calculator with a mouse interface.");
|
||||
write_man_file("notepad", "NOTEPAD - Desktop text editor\n\nUsage: notepad\n\nOpens a graphical text editor for the BoredOS desktop.");
|
||||
write_man_file("paint", "PAINT - Drawing application\n\nUsage: paint\n\nOpens a simple drawing program with various colors.");
|
||||
write_man_file("minesweeper", "MINESWEEPER - Classic game\n\nUsage: minesweeper\n\nPlays the classic minesweeper puzzle game.");
|
||||
write_man_file("markdown", "MARKDOWN - MD file viewer\n\nUsage: markdown <file.md>\n\nOpens a graphical viewer for formatted markdown files.");
|
||||
write_man_file("txtedit", "TXTEDIT - Terminal text editor\n\nUsage: txtedit <filename>\n\nOpens a CLI-based text editor within the terminal.");
|
||||
write_man_file("math", "MATH - Expression evaluator\n\nUsage: math <expression>\n\nEvaluates simple arithmetic expressions from the command line.");
|
||||
write_man_file("viewer", "VIEWER - Image viewer\n\nUsage: viewer <file.ppm>\n\nA graphical application for viewing image files.");
|
||||
write_man_file("settings", "SETTINGS - System settings\n\nUsage: settings\n\nOpens the graphical system configuration tool.");
|
||||
}
|
||||
|
||||
#endif
|
||||
145
src/core/panic.c
Normal file
145
src/core/panic.c
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include "process.h"
|
||||
#include "graphics.h"
|
||||
#include "io.h"
|
||||
#include "kutils.h"
|
||||
|
||||
extern void serial_write(const char *str);
|
||||
|
||||
static void draw_string_centered(int y, const char *s, uint32_t color) {
|
||||
if (!s) return;
|
||||
int len = 0;
|
||||
while (s[len]) len++;
|
||||
int x = (get_screen_width() - (len * 8)) / 2;
|
||||
draw_string(x, y, s, color);
|
||||
}
|
||||
|
||||
void kernel_panic(registers_t *regs, const char *error_name) {
|
||||
// Disable interrupts to prevent nested panics
|
||||
asm volatile("cli");
|
||||
|
||||
// Clear back buffer to black
|
||||
graphics_clear_back_buffer(0x00000000);
|
||||
|
||||
int sh = get_screen_height();
|
||||
int cy = sh / 2;
|
||||
|
||||
// Draw header
|
||||
draw_string_centered(cy - 150, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0xFFFF0000);
|
||||
draw_string_centered(cy - 130, "KERNEL EXCEPTION OCCURRED", 0xFFFFFFFF);
|
||||
draw_string_centered(cy - 110, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0xFFFF0000);
|
||||
|
||||
// Error name
|
||||
char err_buf[256];
|
||||
int pos = 0;
|
||||
const char *prefix = "Exception: ";
|
||||
while(prefix[pos]) { err_buf[pos] = prefix[pos]; pos++; }
|
||||
int i = 0;
|
||||
while(error_name[i]) { err_buf[pos++] = error_name[i++]; }
|
||||
err_buf[pos] = 0;
|
||||
draw_string_centered(cy - 70, err_buf, 0xFFFFCC00);
|
||||
|
||||
// Details - simplified centering by drawing them as a block or individually centered
|
||||
char info_buf[64];
|
||||
|
||||
// Vector
|
||||
pos = 0;
|
||||
prefix = "Vector: ";
|
||||
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
|
||||
uint64_t v = regs->int_no;
|
||||
const char* digits = "0123456789ABCDEF";
|
||||
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
info_buf[pos + i] = digits[v & 0xF];
|
||||
v >>= 4;
|
||||
}
|
||||
info_buf[pos + 16] = 0;
|
||||
draw_string_centered(cy - 40, info_buf, 0xFFFFFFFF);
|
||||
|
||||
// Error Code
|
||||
pos = 0;
|
||||
prefix = "Error Code: ";
|
||||
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
|
||||
v = regs->err_code;
|
||||
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
info_buf[pos + i] = digits[v & 0xF];
|
||||
v >>= 4;
|
||||
}
|
||||
info_buf[pos + 16] = 0;
|
||||
draw_string_centered(cy - 20, info_buf, 0xFFFFFFFF);
|
||||
|
||||
// RIP
|
||||
pos = 0;
|
||||
prefix = "RIP: ";
|
||||
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
|
||||
v = regs->rip;
|
||||
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
info_buf[pos + i] = digits[v & 0xF];
|
||||
v >>= 4;
|
||||
}
|
||||
info_buf[pos + 16] = 0;
|
||||
draw_string_centered(cy, info_buf, 0xFFFFFFFF);
|
||||
|
||||
// CR2 for page faults
|
||||
if (regs->int_no == 14) {
|
||||
uint64_t cr2;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
pos = 0;
|
||||
prefix = "CR2: ";
|
||||
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
|
||||
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
info_buf[pos + i] = digits[cr2 & 0xF];
|
||||
cr2 >>= 4;
|
||||
}
|
||||
info_buf[pos + 16] = 0;
|
||||
draw_string_centered(cy + 20, info_buf, 0xFFFF5555);
|
||||
}
|
||||
|
||||
// Message
|
||||
draw_string_centered(cy + 100, "The system has been halted to prevent damage.", 0xFFFFFFFF);
|
||||
draw_string_centered(cy + 120, "Please restart your computer.", 0xFFAAAAAA);
|
||||
|
||||
|
||||
// Flip buffer to screen
|
||||
graphics_mark_screen_dirty();
|
||||
graphics_flip_buffer();
|
||||
|
||||
char hex_buf[17];
|
||||
serial_write("\n*** KERNEL PANIC ***\n");
|
||||
serial_write(error_name);
|
||||
serial_write("\n");
|
||||
|
||||
serial_write("Vector: 0x");
|
||||
k_itoa_hex(regs->int_no, hex_buf);
|
||||
serial_write(hex_buf);
|
||||
serial_write("\n");
|
||||
|
||||
serial_write("Error Code: 0x");
|
||||
k_itoa_hex(regs->err_code, hex_buf);
|
||||
serial_write(hex_buf);
|
||||
serial_write("\n");
|
||||
|
||||
serial_write("RIP: 0x");
|
||||
k_itoa_hex(regs->rip, hex_buf);
|
||||
serial_write(hex_buf);
|
||||
serial_write("\n");
|
||||
|
||||
if (regs->int_no == 14) {
|
||||
uint64_t cr2;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
serial_write("CR2: 0x");
|
||||
k_itoa_hex(cr2, hex_buf);
|
||||
serial_write(hex_buf);
|
||||
serial_write("\n");
|
||||
}
|
||||
|
||||
// Halt
|
||||
while(1) {
|
||||
asm volatile("cli; hlt");
|
||||
}
|
||||
}
|
||||
71
src/core/platform.c
Normal file
71
src/core/platform.c
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include <stdint.h>
|
||||
#include "limine.h"
|
||||
#include <stddef.h>
|
||||
static volatile struct limine_hhdm_request hhdm_request __attribute__((used, section(".requests"))) = {
|
||||
.id = LIMINE_HHDM_REQUEST,
|
||||
.revision = 0,
|
||||
.response = NULL
|
||||
};
|
||||
static volatile struct limine_kernel_address_request kernel_addr_request __attribute__((used, section(".requests"))) = {
|
||||
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
|
||||
.revision = 0,
|
||||
.response = NULL
|
||||
};
|
||||
uint64_t hhdm_offset = 0;
|
||||
uint64_t kernel_phys_base = 0;
|
||||
uint64_t kernel_virt_base = 0;
|
||||
void platform_init(void) {
|
||||
if (hhdm_request.response) { hhdm_offset = hhdm_request.response->offset; }
|
||||
if (kernel_addr_request.response) {
|
||||
kernel_phys_base = kernel_addr_request.response->physical_base;
|
||||
kernel_virt_base = kernel_addr_request.response->virtual_base;
|
||||
}
|
||||
|
||||
// Enable FPU and SSE
|
||||
uint64_t cr0;
|
||||
asm volatile("mov %%cr0, %0" : "=r"(cr0));
|
||||
cr0 &= ~(1ULL << 2); // Clear EM (Emulation)
|
||||
cr0 |= (1ULL << 1); // Set MP (Monitor Coprocessor)
|
||||
cr0 |= (1ULL << 5); // Set NE (Numeric Error)
|
||||
asm volatile("mov %0, %%cr0" : : "r"(cr0));
|
||||
|
||||
uint64_t cr4;
|
||||
asm volatile("mov %%cr4, %0" : "=r"(cr4));
|
||||
cr4 |= (1ULL << 9); // Set OSFXSR (FXSAVE/FXRSTOR support)
|
||||
cr4 |= (1ULL << 10); // Set OSXMMEXCPT (SIMD exception support)
|
||||
asm volatile("mov %0, %%cr4" : : "r"(cr4));
|
||||
|
||||
// Initialize FPU
|
||||
asm volatile("fninit");
|
||||
}
|
||||
uint64_t p2v(uint64_t phys) { return phys + hhdm_offset; }
|
||||
uint64_t v2p(uint64_t virt) {
|
||||
if (kernel_virt_base && virt >= kernel_virt_base) {
|
||||
return virt - kernel_virt_base + kernel_phys_base;
|
||||
}
|
||||
if (hhdm_offset && virt >= hhdm_offset) {
|
||||
return virt - hhdm_offset;
|
||||
}
|
||||
return virt;
|
||||
}
|
||||
void platform_get_cpu_model(char *model) {
|
||||
uint32_t brand[12];
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(0x80000002 + i));
|
||||
brand[i * 4 + 0] = eax;
|
||||
brand[i * 4 + 1] = ebx;
|
||||
brand[i * 4 + 2] = ecx;
|
||||
brand[i * 4 + 3] = edx;
|
||||
}
|
||||
|
||||
char *p = (char *)brand;
|
||||
for (int i = 0; i < 48; i++) {
|
||||
model[i] = p[i];
|
||||
}
|
||||
model[48] = '\0';
|
||||
}
|
||||
14
src/core/platform.h
Normal file
14
src/core/platform.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void platform_init(void);
|
||||
uint64_t p2v(uint64_t phys);
|
||||
uint64_t v2p(uint64_t virt);
|
||||
void platform_get_cpu_model(char *model);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user