mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
初始化
This commit is contained in:
48
clks/kernel/kmain.c
Normal file
48
clks/kernel/kmain.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <clks/boot.h>
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/framebuffer.h>
|
||||
#include <clks/kernel.h>
|
||||
#include <clks/log.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/tty.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
void clks_kernel_main(void) {
|
||||
const struct limine_framebuffer *boot_fb;
|
||||
|
||||
clks_serial_init();
|
||||
|
||||
if (clks_boot_base_revision_supported() == CLKS_FALSE) {
|
||||
clks_serial_write("[ERROR][BOOT] LIMINE BASE REVISION NOT SUPPORTED\n");
|
||||
clks_cpu_halt_forever();
|
||||
}
|
||||
|
||||
boot_fb = clks_boot_get_framebuffer();
|
||||
|
||||
if (boot_fb != CLKS_NULL) {
|
||||
clks_fb_init(boot_fb);
|
||||
clks_tty_init();
|
||||
}
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE1 START");
|
||||
|
||||
if (boot_fb == CLKS_NULL) {
|
||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||
} else {
|
||||
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "WIDTH", boot_fb->width);
|
||||
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "HEIGHT", boot_fb->height);
|
||||
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "PITCH", boot_fb->pitch);
|
||||
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "BPP", boot_fb->bpp);
|
||||
}
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
clks_log(CLKS_LOG_INFO, "ARCH", "X86_64 ONLINE");
|
||||
#elif defined(CLKS_ARCH_AARCH64)
|
||||
clks_log(CLKS_LOG_INFO, "ARCH", "AARCH64 ONLINE");
|
||||
#endif
|
||||
|
||||
clks_log(CLKS_LOG_INFO, "TTY", "VIRTUAL TTY0 READY");
|
||||
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
|
||||
|
||||
clks_cpu_halt_forever();
|
||||
}
|
||||
36
clks/kernel/limine_requests.c
Normal file
36
clks/kernel/limine_requests.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <clks/boot.h>
|
||||
#include <clks/compiler.h>
|
||||
|
||||
CLKS_USED static volatile u64 limine_requests_start[]
|
||||
__attribute__((section(".limine_requests_start"))) = LIMINE_REQUESTS_START_MARKER;
|
||||
|
||||
CLKS_USED static volatile u64 limine_base_revision[]
|
||||
__attribute__((section(".limine_requests"))) = LIMINE_BASE_REVISION(3);
|
||||
|
||||
CLKS_USED static volatile struct limine_framebuffer_request limine_framebuffer_request
|
||||
__attribute__((section(".limine_requests"))) = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
||||
.revision = 0,
|
||||
.response = CLKS_NULL,
|
||||
};
|
||||
|
||||
CLKS_USED static volatile u64 limine_requests_end[]
|
||||
__attribute__((section(".limine_requests_end"))) = LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
clks_bool clks_boot_base_revision_supported(void) {
|
||||
return (limine_base_revision[2] == 0) ? CLKS_TRUE : CLKS_FALSE;
|
||||
}
|
||||
|
||||
const struct limine_framebuffer *clks_boot_get_framebuffer(void) {
|
||||
volatile struct limine_framebuffer_request *request = &limine_framebuffer_request;
|
||||
|
||||
if (request->response == CLKS_NULL) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
if (request->response->framebuffer_count < 1) {
|
||||
return CLKS_NULL;
|
||||
}
|
||||
|
||||
return request->response->framebuffers[0];
|
||||
}
|
||||
96
clks/kernel/log.c
Normal file
96
clks/kernel/log.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include <clks/log.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/tty.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_LOG_LINE_MAX 256
|
||||
|
||||
static const char *clks_log_level_name(enum clks_log_level level) {
|
||||
switch (level) {
|
||||
case CLKS_LOG_DEBUG:
|
||||
return "DEBUG";
|
||||
case CLKS_LOG_INFO:
|
||||
return "INFO";
|
||||
case CLKS_LOG_WARN:
|
||||
return "WARN";
|
||||
case CLKS_LOG_ERROR:
|
||||
return "ERROR";
|
||||
default:
|
||||
return "UNK";
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_log_append_char(char *buffer, usize *cursor, char ch) {
|
||||
if (*cursor >= (CLKS_LOG_LINE_MAX - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[*cursor] = ch;
|
||||
(*cursor)++;
|
||||
}
|
||||
|
||||
static void clks_log_append_text(char *buffer, usize *cursor, const char *text) {
|
||||
usize i = 0;
|
||||
|
||||
while (text[i] != '\0') {
|
||||
clks_log_append_char(buffer, cursor, text[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_log_append_hex_u64(char *buffer, usize *cursor, u64 value) {
|
||||
int nibble;
|
||||
|
||||
clks_log_append_text(buffer, cursor, "0X");
|
||||
|
||||
for (nibble = 15; nibble >= 0; nibble--) {
|
||||
u8 current = (u8)((value >> (nibble * 4)) & 0x0FULL);
|
||||
char out = (current < 10) ? (char)('0' + current) : (char)('A' + (current - 10));
|
||||
clks_log_append_char(buffer, cursor, out);
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_log_emit_line(const char *line) {
|
||||
clks_serial_write(line);
|
||||
clks_serial_write("\n");
|
||||
|
||||
clks_tty_write(line);
|
||||
clks_tty_write("\n");
|
||||
}
|
||||
|
||||
void clks_log(enum clks_log_level level, const char *tag, const char *message) {
|
||||
char line[CLKS_LOG_LINE_MAX];
|
||||
usize cursor = 0;
|
||||
|
||||
clks_log_append_char(line, &cursor, '[');
|
||||
clks_log_append_text(line, &cursor, clks_log_level_name(level));
|
||||
clks_log_append_char(line, &cursor, ']');
|
||||
clks_log_append_char(line, &cursor, '[');
|
||||
clks_log_append_text(line, &cursor, tag);
|
||||
clks_log_append_char(line, &cursor, ']');
|
||||
clks_log_append_char(line, &cursor, ' ');
|
||||
clks_log_append_text(line, &cursor, message);
|
||||
line[cursor] = '\0';
|
||||
|
||||
clks_log_emit_line(line);
|
||||
}
|
||||
|
||||
void clks_log_hex(enum clks_log_level level, const char *tag, const char *label, u64 value) {
|
||||
char line[CLKS_LOG_LINE_MAX];
|
||||
usize cursor = 0;
|
||||
|
||||
clks_log_append_char(line, &cursor, '[');
|
||||
clks_log_append_text(line, &cursor, clks_log_level_name(level));
|
||||
clks_log_append_char(line, &cursor, ']');
|
||||
clks_log_append_char(line, &cursor, '[');
|
||||
clks_log_append_text(line, &cursor, tag);
|
||||
clks_log_append_char(line, &cursor, ']');
|
||||
clks_log_append_char(line, &cursor, ' ');
|
||||
clks_log_append_text(line, &cursor, label);
|
||||
clks_log_append_char(line, &cursor, ':');
|
||||
clks_log_append_char(line, &cursor, ' ');
|
||||
clks_log_append_hex_u64(line, &cursor, value);
|
||||
line[cursor] = '\0';
|
||||
|
||||
clks_log_emit_line(line);
|
||||
}
|
||||
194
clks/kernel/tty.c
Normal file
194
clks/kernel/tty.c
Normal file
@@ -0,0 +1,194 @@
|
||||
#include <clks/framebuffer.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/tty.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_TTY_COUNT 4
|
||||
#define CLKS_TTY_MAX_ROWS 128
|
||||
#define CLKS_TTY_MAX_COLS 256
|
||||
|
||||
#define CLKS_TTY_FG 0x00E6E6E6U
|
||||
#define CLKS_TTY_BG 0x00101010U
|
||||
|
||||
static char clks_tty_cells[CLKS_TTY_COUNT][CLKS_TTY_MAX_ROWS][CLKS_TTY_MAX_COLS];
|
||||
static u32 clks_tty_cursor_row[CLKS_TTY_COUNT];
|
||||
static u32 clks_tty_cursor_col[CLKS_TTY_COUNT];
|
||||
|
||||
static u32 clks_tty_rows = 0;
|
||||
static u32 clks_tty_cols = 0;
|
||||
static u32 clks_tty_active_index = 0;
|
||||
static clks_bool clks_tty_is_ready = CLKS_FALSE;
|
||||
|
||||
static void clks_tty_fill_row(u32 tty_index, u32 row, char ch) {
|
||||
u32 col;
|
||||
|
||||
for (col = 0; col < clks_tty_cols; col++) {
|
||||
clks_tty_cells[tty_index][row][col] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_tty_draw_cell(u32 row, u32 col, char ch) {
|
||||
clks_fb_draw_char(col * 8U, row * 8U, ch, CLKS_TTY_FG, CLKS_TTY_BG);
|
||||
}
|
||||
|
||||
static void clks_tty_redraw_active(void) {
|
||||
u32 row;
|
||||
u32 col;
|
||||
|
||||
clks_fb_clear(CLKS_TTY_BG);
|
||||
|
||||
for (row = 0; row < clks_tty_rows; row++) {
|
||||
for (col = 0; col < clks_tty_cols; col++) {
|
||||
clks_tty_draw_cell(row, col, clks_tty_cells[clks_tty_active_index][row][col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_tty_scroll_up(u32 tty_index) {
|
||||
u32 row;
|
||||
|
||||
for (row = 1; row < clks_tty_rows; row++) {
|
||||
clks_memcpy(
|
||||
clks_tty_cells[tty_index][row - 1],
|
||||
clks_tty_cells[tty_index][row],
|
||||
clks_tty_cols
|
||||
);
|
||||
}
|
||||
|
||||
clks_tty_fill_row(tty_index, clks_tty_rows - 1, ' ');
|
||||
|
||||
if (tty_index == clks_tty_active_index) {
|
||||
clks_tty_redraw_active();
|
||||
}
|
||||
}
|
||||
|
||||
static void clks_tty_put_visible(u32 tty_index, u32 row, u32 col, char ch) {
|
||||
clks_tty_cells[tty_index][row][col] = ch;
|
||||
|
||||
if (tty_index == clks_tty_active_index) {
|
||||
clks_tty_draw_cell(row, col, ch);
|
||||
}
|
||||
}
|
||||
|
||||
void clks_tty_init(void) {
|
||||
struct clks_framebuffer_info info;
|
||||
u32 tty;
|
||||
u32 row;
|
||||
|
||||
if (clks_fb_ready() == CLKS_FALSE) {
|
||||
clks_tty_is_ready = CLKS_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
info = clks_fb_info();
|
||||
clks_tty_rows = info.height / 8U;
|
||||
clks_tty_cols = info.width / 8U;
|
||||
|
||||
if (clks_tty_rows > CLKS_TTY_MAX_ROWS) {
|
||||
clks_tty_rows = CLKS_TTY_MAX_ROWS;
|
||||
}
|
||||
|
||||
if (clks_tty_cols > CLKS_TTY_MAX_COLS) {
|
||||
clks_tty_cols = CLKS_TTY_MAX_COLS;
|
||||
}
|
||||
|
||||
if (clks_tty_rows == 0 || clks_tty_cols == 0) {
|
||||
clks_tty_is_ready = CLKS_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
for (tty = 0; tty < CLKS_TTY_COUNT; tty++) {
|
||||
clks_tty_cursor_row[tty] = 0;
|
||||
clks_tty_cursor_col[tty] = 0;
|
||||
|
||||
for (row = 0; row < clks_tty_rows; row++) {
|
||||
clks_tty_fill_row(tty, row, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
clks_tty_active_index = 0;
|
||||
clks_tty_is_ready = CLKS_TRUE;
|
||||
clks_tty_redraw_active();
|
||||
}
|
||||
|
||||
void clks_tty_write_char(char ch) {
|
||||
u32 tty_index;
|
||||
u32 row;
|
||||
u32 col;
|
||||
|
||||
if (clks_tty_is_ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
tty_index = clks_tty_active_index;
|
||||
row = clks_tty_cursor_row[tty_index];
|
||||
col = clks_tty_cursor_col[tty_index];
|
||||
|
||||
if (ch == '\r') {
|
||||
clks_tty_cursor_col[tty_index] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == '\n') {
|
||||
clks_tty_cursor_col[tty_index] = 0;
|
||||
clks_tty_cursor_row[tty_index]++;
|
||||
|
||||
if (clks_tty_cursor_row[tty_index] >= clks_tty_rows) {
|
||||
clks_tty_scroll_up(tty_index);
|
||||
clks_tty_cursor_row[tty_index] = clks_tty_rows - 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch == '\t') {
|
||||
clks_tty_write_char(' ');
|
||||
clks_tty_write_char(' ');
|
||||
clks_tty_write_char(' ');
|
||||
clks_tty_write_char(' ');
|
||||
return;
|
||||
}
|
||||
|
||||
clks_tty_put_visible(tty_index, row, col, ch);
|
||||
clks_tty_cursor_col[tty_index]++;
|
||||
|
||||
if (clks_tty_cursor_col[tty_index] >= clks_tty_cols) {
|
||||
clks_tty_cursor_col[tty_index] = 0;
|
||||
clks_tty_cursor_row[tty_index]++;
|
||||
|
||||
if (clks_tty_cursor_row[tty_index] >= clks_tty_rows) {
|
||||
clks_tty_scroll_up(tty_index);
|
||||
clks_tty_cursor_row[tty_index] = clks_tty_rows - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clks_tty_write(const char *text) {
|
||||
usize i = 0;
|
||||
|
||||
if (clks_tty_is_ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (text[i] != '\0') {
|
||||
clks_tty_write_char(text[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void clks_tty_switch(u32 tty_index) {
|
||||
if (clks_tty_is_ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tty_index >= CLKS_TTY_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
clks_tty_active_index = tty_index;
|
||||
clks_tty_redraw_active();
|
||||
}
|
||||
|
||||
u32 clks_tty_active(void) {
|
||||
return clks_tty_active_index;
|
||||
}
|
||||
Reference in New Issue
Block a user