mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
初始化
This commit is contained in:
7
clks/arch/aarch64/boot.c
Normal file
7
clks/arch/aarch64/boot.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/kernel.h>
|
||||
|
||||
void _start(void) {
|
||||
clks_kernel_main();
|
||||
clks_cpu_halt_forever();
|
||||
}
|
||||
38
clks/arch/aarch64/linker.ld
Normal file
38
clks/arch/aarch64/linker.ld
Normal file
@@ -0,0 +1,38 @@
|
||||
OUTPUT_FORMAT(elf64-littleaarch64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS(5);
|
||||
rodata PT_LOAD FLAGS(4);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
. = 0x100000;
|
||||
|
||||
.text : {
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
.rodata : {
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
} :data
|
||||
|
||||
.bss : {
|
||||
*(COMMON)
|
||||
*(.bss .bss.*)
|
||||
} :data
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.eh_frame)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
||||
7
clks/arch/x86_64/boot.c
Normal file
7
clks/arch/x86_64/boot.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <clks/cpu.h>
|
||||
#include <clks/kernel.h>
|
||||
|
||||
void _start(void) {
|
||||
clks_kernel_main();
|
||||
clks_cpu_halt_forever();
|
||||
}
|
||||
42
clks/arch/x86_64/linker.ld
Normal file
42
clks/arch/x86_64/linker.ld
Normal file
@@ -0,0 +1,42 @@
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS(5);
|
||||
rodata PT_LOAD FLAGS(4);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
. = 0xffffffff80000000;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
.text : ALIGN(0x1000) {
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
.rodata : ALIGN(0x1000) {
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
.data : ALIGN(0x1000) {
|
||||
*(.data .data.*)
|
||||
} :data
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
.bss : ALIGN(0x1000) {
|
||||
*(COMMON)
|
||||
*(.bss .bss.*)
|
||||
} :data
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.eh_frame)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
||||
68
clks/drivers/serial/serial.c
Normal file
68
clks/drivers/serial/serial.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <clks/compiler.h>
|
||||
#include <clks/serial.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
|
||||
#define CLKS_COM1_PORT 0x3F8
|
||||
|
||||
static inline void clks_x86_outb(u16 port, u8 value) {
|
||||
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||
}
|
||||
|
||||
static inline u8 clks_x86_inb(u16 port) {
|
||||
u8 value;
|
||||
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||
return value;
|
||||
}
|
||||
|
||||
void clks_serial_init(void) {
|
||||
clks_x86_outb(CLKS_COM1_PORT + 1, 0x00);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 3, 0x80);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 0, 0x03);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 1, 0x00);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 3, 0x03);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 2, 0xC7);
|
||||
clks_x86_outb(CLKS_COM1_PORT + 4, 0x0B);
|
||||
}
|
||||
|
||||
void clks_serial_write_char(char ch) {
|
||||
while ((clks_x86_inb(CLKS_COM1_PORT + 5) & 0x20) == 0) {
|
||||
}
|
||||
|
||||
clks_x86_outb(CLKS_COM1_PORT, (u8)ch);
|
||||
}
|
||||
|
||||
#elif defined(CLKS_ARCH_AARCH64)
|
||||
|
||||
#define CLKS_PL011_BASE 0x09000000ULL
|
||||
#define CLKS_PL011_DR (*(volatile u32 *)(CLKS_PL011_BASE + 0x00))
|
||||
#define CLKS_PL011_FR (*(volatile u32 *)(CLKS_PL011_BASE + 0x18))
|
||||
#define CLKS_PL011_TXFF (1U << 5)
|
||||
|
||||
void clks_serial_init(void) {
|
||||
}
|
||||
|
||||
void clks_serial_write_char(char ch) {
|
||||
while ((CLKS_PL011_FR & CLKS_PL011_TXFF) != 0) {
|
||||
}
|
||||
|
||||
CLKS_PL011_DR = (u32)(u8)ch;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
void clks_serial_write(const char *text) {
|
||||
usize i = 0;
|
||||
|
||||
while (text[i] != '\0') {
|
||||
if (text[i] == '\n') {
|
||||
clks_serial_write_char('\r');
|
||||
}
|
||||
|
||||
clks_serial_write_char(text[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
75
clks/drivers/video/font8x8.c
Normal file
75
clks/drivers/video/font8x8.c
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "font8x8.h"
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
struct clks_glyph8x8 {
|
||||
char ch;
|
||||
u8 rows[8];
|
||||
};
|
||||
|
||||
static const struct clks_glyph8x8 clks_font_table[] = {
|
||||
{' ', {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{'[', {0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00}},
|
||||
{']', {0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00}},
|
||||
{':', {0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00}},
|
||||
{'.', {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00}},
|
||||
{'-', {0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00}},
|
||||
{'/', {0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00}},
|
||||
{'_', {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00}},
|
||||
{'?', {0x3C, 0x42, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00}},
|
||||
{'0', {0x3C, 0x42, 0x46, 0x4A, 0x52, 0x62, 0x3C, 0x00}},
|
||||
{'1', {0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00}},
|
||||
{'2', {0x3C, 0x42, 0x02, 0x0C, 0x30, 0x40, 0x7E, 0x00}},
|
||||
{'3', {0x3C, 0x42, 0x02, 0x1C, 0x02, 0x42, 0x3C, 0x00}},
|
||||
{'4', {0x0C, 0x14, 0x24, 0x44, 0x7E, 0x04, 0x04, 0x00}},
|
||||
{'5', {0x7E, 0x40, 0x7C, 0x02, 0x02, 0x42, 0x3C, 0x00}},
|
||||
{'6', {0x1C, 0x20, 0x40, 0x7C, 0x42, 0x42, 0x3C, 0x00}},
|
||||
{'7', {0x7E, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x00}},
|
||||
{'8', {0x3C, 0x42, 0x42, 0x3C, 0x42, 0x42, 0x3C, 0x00}},
|
||||
{'9', {0x3C, 0x42, 0x42, 0x3E, 0x02, 0x04, 0x38, 0x00}},
|
||||
{'A', {0x18, 0x24, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00}},
|
||||
{'B', {0x7C, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x7C, 0x00}},
|
||||
{'C', {0x3C, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3C, 0x00}},
|
||||
{'D', {0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00}},
|
||||
{'E', {0x7E, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x7E, 0x00}},
|
||||
{'F', {0x7E, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x40, 0x00}},
|
||||
{'G', {0x3C, 0x42, 0x40, 0x4E, 0x42, 0x42, 0x3C, 0x00}},
|
||||
{'H', {0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x00}},
|
||||
{'I', {0x3E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3E, 0x00}},
|
||||
{'J', {0x1E, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00}},
|
||||
{'K', {0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x00}},
|
||||
{'L', {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00}},
|
||||
{'M', {0x42, 0x66, 0x5A, 0x5A, 0x42, 0x42, 0x42, 0x00}},
|
||||
{'N', {0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x42, 0x00}},
|
||||
{'O', {0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00}},
|
||||
{'P', {0x7C, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00}},
|
||||
{'Q', {0x3C, 0x42, 0x42, 0x42, 0x4A, 0x44, 0x3A, 0x00}},
|
||||
{'R', {0x7C, 0x42, 0x42, 0x7C, 0x48, 0x44, 0x42, 0x00}},
|
||||
{'S', {0x3C, 0x42, 0x40, 0x3C, 0x02, 0x42, 0x3C, 0x00}},
|
||||
{'T', {0x7F, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00}},
|
||||
{'U', {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00}},
|
||||
{'V', {0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00}},
|
||||
{'W', {0x42, 0x42, 0x42, 0x5A, 0x5A, 0x66, 0x42, 0x00}},
|
||||
{'X', {0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x00}},
|
||||
{'Y', {0x42, 0x42, 0x24, 0x18, 0x08, 0x08, 0x08, 0x00}},
|
||||
{'Z', {0x7E, 0x02, 0x04, 0x18, 0x20, 0x40, 0x7E, 0x00}},
|
||||
};
|
||||
|
||||
static const u8 clks_unknown[8] = {0x3C, 0x42, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00};
|
||||
|
||||
const u8 *clks_font8x8_get(char ch) {
|
||||
usize i;
|
||||
char upper = ch;
|
||||
|
||||
if (upper >= 'a' && upper <= 'z') {
|
||||
upper = (char)(upper - ('a' - 'A'));
|
||||
}
|
||||
|
||||
for (i = 0; i < (sizeof(clks_font_table) / sizeof(clks_font_table[0])); i++) {
|
||||
if (clks_font_table[i].ch == upper) {
|
||||
return clks_font_table[i].rows;
|
||||
}
|
||||
}
|
||||
|
||||
return clks_unknown;
|
||||
}
|
||||
8
clks/drivers/video/font8x8.h
Normal file
8
clks/drivers/video/font8x8.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef CLKS_FONT8X8_H
|
||||
#define CLKS_FONT8X8_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
const u8 *clks_font8x8_get(char ch);
|
||||
|
||||
#endif
|
||||
95
clks/drivers/video/framebuffer.c
Normal file
95
clks/drivers/video/framebuffer.c
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <clks/framebuffer.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#include "font8x8.h"
|
||||
|
||||
struct clks_fb_state {
|
||||
volatile u8 *address;
|
||||
struct clks_framebuffer_info info;
|
||||
clks_bool ready;
|
||||
};
|
||||
|
||||
static struct clks_fb_state clks_fb = {
|
||||
.address = CLKS_NULL,
|
||||
.info = {0, 0, 0, 0},
|
||||
.ready = CLKS_FALSE,
|
||||
};
|
||||
|
||||
static void clks_fb_put_pixel(u32 x, u32 y, u32 rgb) {
|
||||
volatile u8 *row;
|
||||
volatile u32 *pixel;
|
||||
|
||||
if (clks_fb.ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x >= clks_fb.info.width || y >= clks_fb.info.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clks_fb.info.bpp != 32) {
|
||||
return;
|
||||
}
|
||||
|
||||
row = clks_fb.address + ((usize)y * (usize)clks_fb.info.pitch);
|
||||
pixel = (volatile u32 *)(row + ((usize)x * 4));
|
||||
*pixel = rgb;
|
||||
}
|
||||
|
||||
void clks_fb_init(const struct limine_framebuffer *fb) {
|
||||
if (fb == CLKS_NULL) {
|
||||
clks_fb.ready = CLKS_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
clks_fb.address = (volatile u8 *)fb->address;
|
||||
clks_fb.info.width = (u32)fb->width;
|
||||
clks_fb.info.height = (u32)fb->height;
|
||||
clks_fb.info.pitch = (u32)fb->pitch;
|
||||
clks_fb.info.bpp = fb->bpp;
|
||||
clks_fb.ready = CLKS_TRUE;
|
||||
}
|
||||
|
||||
clks_bool clks_fb_ready(void) {
|
||||
return clks_fb.ready;
|
||||
}
|
||||
|
||||
struct clks_framebuffer_info clks_fb_info(void) {
|
||||
return clks_fb.info;
|
||||
}
|
||||
|
||||
void clks_fb_clear(u32 rgb) {
|
||||
u32 x;
|
||||
u32 y;
|
||||
|
||||
if (clks_fb.ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (y = 0; y < clks_fb.info.height; y++) {
|
||||
for (x = 0; x < clks_fb.info.width; x++) {
|
||||
clks_fb_put_pixel(x, y, rgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clks_fb_draw_char(u32 x, u32 y, char ch, u32 fg_rgb, u32 bg_rgb) {
|
||||
const u8 *glyph;
|
||||
u32 row;
|
||||
u32 col;
|
||||
|
||||
if (clks_fb.ready == CLKS_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
glyph = clks_font8x8_get(ch);
|
||||
|
||||
for (row = 0; row < 8; row++) {
|
||||
for (col = 0; col < 8; col++) {
|
||||
u8 mask = (u8)(1U << (7U - col));
|
||||
u32 color = (glyph[row] & mask) != 0 ? fg_rgb : bg_rgb;
|
||||
clks_fb_put_pixel(x + col, y + row, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
clks/include/clks/boot.h
Normal file
10
clks/include/clks/boot.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef CLKS_BOOT_H
|
||||
#define CLKS_BOOT_H
|
||||
|
||||
#include <clks/limine.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
clks_bool clks_boot_base_revision_supported(void);
|
||||
const struct limine_framebuffer *clks_boot_get_framebuffer(void);
|
||||
|
||||
#endif
|
||||
17
clks/include/clks/compiler.h
Normal file
17
clks/include/clks/compiler.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef CLKS_COMPILER_H
|
||||
#define CLKS_COMPILER_H
|
||||
|
||||
#define CLKS_USED __attribute__((used))
|
||||
#define CLKS_NORETURN __attribute__((noreturn))
|
||||
#define CLKS_PACKED __attribute__((packed))
|
||||
#define CLKS_ALIGN(N) __attribute__((aligned(N)))
|
||||
|
||||
#if defined(CLKS_ARCH_X86_64) && defined(CLKS_ARCH_AARCH64)
|
||||
#error "Only one architecture can be selected"
|
||||
#endif
|
||||
|
||||
#if !defined(CLKS_ARCH_X86_64) && !defined(CLKS_ARCH_AARCH64)
|
||||
#error "Missing architecture define: CLKS_ARCH_X86_64 or CLKS_ARCH_AARCH64"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
24
clks/include/clks/cpu.h
Normal file
24
clks/include/clks/cpu.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef CLKS_CPU_H
|
||||
#define CLKS_CPU_H
|
||||
|
||||
#include <clks/compiler.h>
|
||||
|
||||
static inline void clks_cpu_pause(void) {
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
__asm__ volatile("pause");
|
||||
#elif defined(CLKS_ARCH_AARCH64)
|
||||
__asm__ volatile("yield");
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline CLKS_NORETURN void clks_cpu_halt_forever(void) {
|
||||
for (;;) {
|
||||
#if defined(CLKS_ARCH_X86_64)
|
||||
__asm__ volatile("hlt");
|
||||
#elif defined(CLKS_ARCH_AARCH64)
|
||||
__asm__ volatile("wfe");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
20
clks/include/clks/framebuffer.h
Normal file
20
clks/include/clks/framebuffer.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef CLKS_FRAMEBUFFER_H
|
||||
#define CLKS_FRAMEBUFFER_H
|
||||
|
||||
#include <clks/limine.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
struct clks_framebuffer_info {
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 pitch;
|
||||
u16 bpp;
|
||||
};
|
||||
|
||||
void clks_fb_init(const struct limine_framebuffer *fb);
|
||||
clks_bool clks_fb_ready(void);
|
||||
struct clks_framebuffer_info clks_fb_info(void);
|
||||
void clks_fb_clear(u32 rgb);
|
||||
void clks_fb_draw_char(u32 x, u32 y, char ch, u32 fg_rgb, u32 bg_rgb);
|
||||
|
||||
#endif
|
||||
6
clks/include/clks/kernel.h
Normal file
6
clks/include/clks/kernel.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef CLKS_KERNEL_H
|
||||
#define CLKS_KERNEL_H
|
||||
|
||||
void clks_kernel_main(void);
|
||||
|
||||
#endif
|
||||
56
clks/include/clks/limine.h
Normal file
56
clks/include/clks/limine.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef CLKS_LIMINE_H
|
||||
#define CLKS_LIMINE_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88ULL
|
||||
#define LIMINE_REQUEST_MAGIC 0x0a82e883a194f07bULL
|
||||
|
||||
#define LIMINE_REQUESTS_START_MARKER \
|
||||
{ 0xf6b8f4b39de7d1aeULL, 0xfab91a6940fcb9cfULL }
|
||||
|
||||
#define LIMINE_REQUESTS_END_MARKER \
|
||||
{ 0xadc0e0531bb10d03ULL, 0x9572709f31764c62ULL }
|
||||
|
||||
#define LIMINE_BASE_REVISION(N) \
|
||||
{ 0xf9562b2d5c95a6c8ULL, 0x6a7b384944536bdcULL, (N) }
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_REQUEST \
|
||||
{ \
|
||||
LIMINE_COMMON_MAGIC, \
|
||||
LIMINE_REQUEST_MAGIC, \
|
||||
0x9d5827dcd881dd75ULL, \
|
||||
0xa3148604f6fab11bULL \
|
||||
}
|
||||
|
||||
struct limine_framebuffer {
|
||||
void *address;
|
||||
u64 width;
|
||||
u64 height;
|
||||
u64 pitch;
|
||||
u16 bpp;
|
||||
u8 memory_model;
|
||||
u8 red_mask_size;
|
||||
u8 red_mask_shift;
|
||||
u8 green_mask_size;
|
||||
u8 green_mask_shift;
|
||||
u8 blue_mask_size;
|
||||
u8 blue_mask_shift;
|
||||
u8 unused[7];
|
||||
u64 edid_size;
|
||||
void *edid;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_response {
|
||||
u64 revision;
|
||||
u64 framebuffer_count;
|
||||
struct limine_framebuffer **framebuffers;
|
||||
};
|
||||
|
||||
struct limine_framebuffer_request {
|
||||
u64 id[4];
|
||||
u64 revision;
|
||||
struct limine_framebuffer_response *response;
|
||||
};
|
||||
|
||||
#endif
|
||||
16
clks/include/clks/log.h
Normal file
16
clks/include/clks/log.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef CLKS_LOG_H
|
||||
#define CLKS_LOG_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
enum clks_log_level {
|
||||
CLKS_LOG_DEBUG = 0,
|
||||
CLKS_LOG_INFO = 1,
|
||||
CLKS_LOG_WARN = 2,
|
||||
CLKS_LOG_ERROR = 3,
|
||||
};
|
||||
|
||||
void clks_log(enum clks_log_level level, const char *tag, const char *message);
|
||||
void clks_log_hex(enum clks_log_level level, const char *tag, const char *label, u64 value);
|
||||
|
||||
#endif
|
||||
8
clks/include/clks/serial.h
Normal file
8
clks/include/clks/serial.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef CLKS_SERIAL_H
|
||||
#define CLKS_SERIAL_H
|
||||
|
||||
void clks_serial_init(void);
|
||||
void clks_serial_write_char(char ch);
|
||||
void clks_serial_write(const char *text);
|
||||
|
||||
#endif
|
||||
12
clks/include/clks/string.h
Normal file
12
clks/include/clks/string.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef CLKS_STRING_H
|
||||
#define CLKS_STRING_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
usize clks_strlen(const char *str);
|
||||
void *clks_memset(void *dst, int value, usize count);
|
||||
void *clks_memcpy(void *dst, const void *src, usize count);
|
||||
void *clks_memmove(void *dst, const void *src, usize count);
|
||||
int clks_strcmp(const char *left, const char *right);
|
||||
|
||||
#endif
|
||||
12
clks/include/clks/tty.h
Normal file
12
clks/include/clks/tty.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef CLKS_TTY_H
|
||||
#define CLKS_TTY_H
|
||||
|
||||
#include <clks/types.h>
|
||||
|
||||
void clks_tty_init(void);
|
||||
void clks_tty_write(const char *text);
|
||||
void clks_tty_write_char(char ch);
|
||||
void clks_tty_switch(u32 tty_index);
|
||||
u32 clks_tty_active(void);
|
||||
|
||||
#endif
|
||||
23
clks/include/clks/types.h
Normal file
23
clks/include/clks/types.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef CLKS_TYPES_H
|
||||
#define CLKS_TYPES_H
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef signed char i8;
|
||||
typedef signed short i16;
|
||||
typedef signed int i32;
|
||||
typedef signed long long i64;
|
||||
|
||||
typedef u64 usize;
|
||||
|
||||
typedef enum clks_bool {
|
||||
CLKS_FALSE = 0,
|
||||
CLKS_TRUE = 1
|
||||
} clks_bool;
|
||||
|
||||
#define CLKS_NULL ((void *)0)
|
||||
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
70
clks/lib/string.c
Normal file
70
clks/lib/string.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <clks/string.h>
|
||||
|
||||
usize clks_strlen(const char *str) {
|
||||
usize len = 0;
|
||||
|
||||
while (str[len] != '\0') {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void *clks_memset(void *dst, int value, usize count) {
|
||||
u8 *d = (u8 *)dst;
|
||||
u8 v = (u8)value;
|
||||
usize i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
d[i] = v;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *clks_memcpy(void *dst, const void *src, usize count) {
|
||||
u8 *d = (u8 *)dst;
|
||||
const u8 *s = (const u8 *)src;
|
||||
usize i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *clks_memmove(void *dst, const void *src, usize count) {
|
||||
u8 *d = (u8 *)dst;
|
||||
const u8 *s = (const u8 *)src;
|
||||
usize i;
|
||||
|
||||
if (d == s || count == 0) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
if (d < s) {
|
||||
for (i = 0; i < count; i++) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
} else {
|
||||
for (i = count; i != 0; i--) {
|
||||
d[i - 1] = s[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int clks_strcmp(const char *left, const char *right) {
|
||||
usize i = 0;
|
||||
|
||||
while (left[i] != '\0' && right[i] != '\0') {
|
||||
if (left[i] != right[i]) {
|
||||
return (int)((u8)left[i] - (u8)right[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return (int)((u8)left[i] - (u8)right[i]);
|
||||
}
|
||||
Reference in New Issue
Block a user