Merge pull request 'Issue 2' (#3) from issue-2 into main
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -20,6 +20,7 @@ KERNEL_CPP = kernel/entry.cpp kernel/main.cpp kernel/serial.cpp kernel/fs.cpp \
|
||||
kernel/scheduler/scheduler.cpp \
|
||||
kernel/interrupt/gdt.cpp kernel/interrupt/idt.cpp \
|
||||
kernel/interrupt/pic.cpp kernel/interrupt/pit.cpp \
|
||||
kernel/graphics/layer.cpp \
|
||||
graphics/context.cpp graphics/draw.cpp \
|
||||
fonts/pixel_font.cpp
|
||||
KERNEL_ASM = kernel/scheduler/context_switch.S kernel/interrupt/isr.S kernel/interrupt/idt_helpers.S
|
||||
@@ -48,7 +49,7 @@ all: _bd $(EFI_OBJ) $(BOOT_OBJ) $(KERNEL_OBJ)
|
||||
|
||||
_bd:
|
||||
@mkdir -p build/graphics build/kernel build/fonts build/kernel/memory \
|
||||
build/kernel/scheduler build/kernel/interrupt \
|
||||
build/kernel/scheduler build/kernel/interrupt build/kernel/graphics \
|
||||
build/efi/lib build/efi/lib/x86_64 build/efi/lib/runtime build/efi/gnuefi
|
||||
|
||||
$(EFI_CRT0_OBJ): efi/gnuefi/crt0-efi-x86_64.S | _bd
|
||||
|
||||
+9
-35
@@ -2,20 +2,12 @@
|
||||
#include <fonts/pixel_font.h>
|
||||
#include <graphics/draw.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
static unsigned int pf_x = 0;
|
||||
static unsigned int pf_y = 1;
|
||||
|
||||
void pf_reset_position(void) {
|
||||
// 其实应该还要清一下屏,后面思考一个安全的做法
|
||||
pf_x = 0;
|
||||
pf_y = 1;
|
||||
}
|
||||
|
||||
void pf_print_char(char c, unsigned int basex, unsigned int basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (unsigned int y = 0; y < 16; y++) {
|
||||
unsigned char data = hankaku_pixels[c][y];
|
||||
for (int x = 7; x >= 0; x--) {
|
||||
void pf_print_char(char c, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (SUINT32 y = 0; y < 16; y++) {
|
||||
SUINT8 data = hankaku_pixels[c][y];
|
||||
for (SSINT32 x = 7; x >= 0; x--) {
|
||||
// 解码Hankaku字体
|
||||
/*
|
||||
既然都在这了,就讲一下Hankaku字体是如何解码的
|
||||
@@ -23,7 +15,7 @@ void pf_print_char(char c, unsigned int basex, unsigned int basey, EFI_GRAPHICS_
|
||||
{0x00, 0x82, 0x82, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00}
|
||||
每一个Hex代表一行,比如0x82就是一行,转换成Bin得到10000010,1代表有像素,0代表没像素
|
||||
*/
|
||||
unsigned int current = data & 1;
|
||||
SUINT32 current = data & 1;
|
||||
data >>= 1;
|
||||
if (current)
|
||||
draw_pixel(basex + x, basey + y, color);
|
||||
@@ -31,27 +23,9 @@ void pf_print_char(char c, unsigned int basex, unsigned int basey, EFI_GRAPHICS_
|
||||
}
|
||||
}
|
||||
|
||||
void pf_print(const char* text, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (unsigned int i = 0; i < strlen(text); i++) {
|
||||
void pf_print(const char* text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (SUINT32 i = 0; i < str_len(text); i++) {
|
||||
char c = text[i];
|
||||
if (c == '\n') {
|
||||
pf_x = 0;
|
||||
pf_y++;
|
||||
if ((pf_y - 1) * 16 >= g_gfx.vr) {
|
||||
gfx_clear();
|
||||
pf_y = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (pf_x * 9 + 9 > g_gfx.hr) {
|
||||
pf_x = 0;
|
||||
pf_y++;
|
||||
if ((pf_y - 1) * 16 >= g_gfx.vr) {
|
||||
gfx_clear();
|
||||
pf_y = 1;
|
||||
}
|
||||
}
|
||||
pf_print_char(c, pf_x * 9, (pf_y - 1) * 16, color);
|
||||
pf_x++;
|
||||
pf_print_char(c, basex + i * 8, basey, color); // 只要 字数 * 8 + basex 不爆hr就没事
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,37 @@
|
||||
// GFX 存在的意义是什么?
|
||||
// 每一次想要draw pixel,都需要传入GOP的各种参数,
|
||||
// 加入 GFX 后,GOP 的context就是全局的,可以直接用
|
||||
// 而不用显示传递参数到draw的函数里
|
||||
|
||||
#include <graphics/context.h>
|
||||
|
||||
gfx_context g_gfx;
|
||||
draw_target g_draw_target;
|
||||
|
||||
void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP) {
|
||||
g_gfx.GOP = GOP;
|
||||
g_gfx.hr = GOP->Mode->Info->HorizontalResolution;
|
||||
g_gfx.vr = GOP->Mode->Info->VerticalResolution;
|
||||
g_gfx.base = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) GOP->Mode->FrameBufferBase;
|
||||
|
||||
g_draw_target.buf = g_gfx.base;
|
||||
g_draw_target.w = g_gfx.hr;
|
||||
g_draw_target.h = g_gfx.vr;
|
||||
}
|
||||
|
||||
void gfx_clear(void) {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0};
|
||||
g_gfx.GOP->Blt(g_gfx.GOP, &black, EfiBltVideoFill, 0, 0, 0, 0, g_gfx.hr, g_gfx.vr, 0);
|
||||
}
|
||||
|
||||
void draw_set_target(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, SUINT32 w, SUINT32 h) {
|
||||
g_draw_target.buf = buf;
|
||||
g_draw_target.w = w;
|
||||
g_draw_target.h = h;
|
||||
}
|
||||
|
||||
void draw_set_default_target(void) {
|
||||
g_draw_target.buf = g_gfx.base;
|
||||
g_draw_target.w = g_gfx.hr;
|
||||
g_draw_target.h = g_gfx.vr;
|
||||
}
|
||||
+29
-3
@@ -1,10 +1,36 @@
|
||||
#include <graphics/draw.h>
|
||||
|
||||
void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_gfx.base + (g_gfx.hr * y) + x;
|
||||
// --- Global (framebuffer) ---
|
||||
|
||||
void global_draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_gfx.base + (g_gfx.hr * y) + x;
|
||||
p->Blue = color.Blue;
|
||||
p->Green = color.Green;
|
||||
p->Red = color.Red;
|
||||
p->Reserved = color.Reserved;
|
||||
}
|
||||
}
|
||||
|
||||
void global_draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (SUINT32 x = bx; x <= ex; x++)
|
||||
for (SUINT32 y = by; y <= ey; y++)
|
||||
global_draw_pixel(x, y, color);
|
||||
}
|
||||
|
||||
// --- Current target buffer ---
|
||||
|
||||
void draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
if (x >= g_draw_target.w || y >= g_draw_target.h) return;
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_draw_target.buf + (g_draw_target.w * y) + x;
|
||||
p->Blue = color.Blue;
|
||||
p->Green = color.Green;
|
||||
p->Red = color.Red;
|
||||
p->Reserved = color.Reserved;
|
||||
}
|
||||
|
||||
void draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
|
||||
for (SUINT32 x = bx; x <= ex; x++)
|
||||
for (SUINT32 y = by; y <= ey; y++)
|
||||
draw_pixel(x, y, color);
|
||||
}
|
||||
|
||||
+3
-7
@@ -1,9 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define ASM asm volatile
|
||||
|
||||
static unsigned int strlen(const char* arr) { // 获取string长度
|
||||
int i = 0;
|
||||
while (arr[i++] != '\0');
|
||||
return i - 1;
|
||||
}
|
||||
#include <types.h>
|
||||
#include <string_utils.h>
|
||||
#define ASM asm volatile
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include <common.h>
|
||||
|
||||
// Hankaku 字体,不动
|
||||
static unsigned char hankaku_pixels[256][16] = {
|
||||
static SUINT8 hankaku_pixels[256][16] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00},
|
||||
{0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x00, 0x00},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <graphics/context.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
void pf_print_char(char c, unsigned int basex, unsigned int basey,
|
||||
void pf_print_char(char c, SUINT32 basex, SUINT32 basey,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); // Pixel Font 打印字符
|
||||
void pf_print(const char* text, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); // Pixel Font 打印string
|
||||
void pf_reset_position(void); // 重设Pixel Font Cursor位置
|
||||
void pf_print(String text, SUINT32 basex, SUINT32 basey, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color = {255, 255, 255, 255}); // Pixel Font 打印string
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <efi.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
EFI_STATUS fs_init();
|
||||
void fs_list();
|
||||
EFI_STATUS fs_read(const CHAR16 *Path, void **Buffer, UINTN *Size);
|
||||
EFI_STATUS fs_read(WString Path, void **Buffer, UINTN *Size);
|
||||
|
||||
@@ -3,15 +3,26 @@
|
||||
// 这个文件存在的目的是让graphics的draw功能不用每次传 GOP hr vr base
|
||||
|
||||
#include <efi.h>
|
||||
#include <common.h>
|
||||
|
||||
struct gfx_context {
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP;
|
||||
unsigned int hr;
|
||||
unsigned int vr;
|
||||
SUINT32 hr;
|
||||
SUINT32 vr;
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *base;
|
||||
};
|
||||
|
||||
extern gfx_context g_gfx;
|
||||
|
||||
void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP); // 初始化 GFX
|
||||
void gfx_clear(void); // 清空 GFX(相当于重置)
|
||||
struct draw_target {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf;
|
||||
SUINT32 w;
|
||||
SUINT32 h;
|
||||
};
|
||||
|
||||
extern draw_target g_draw_target;
|
||||
|
||||
void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP);
|
||||
void gfx_clear(void);
|
||||
void draw_set_target(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, SUINT32 w, SUINT32 h);
|
||||
void draw_set_default_target(void);
|
||||
@@ -3,4 +3,10 @@
|
||||
#include <efi.h>
|
||||
#include <graphics/context.h>
|
||||
|
||||
void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); // 画像素
|
||||
void global_draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
||||
void global_draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
||||
|
||||
void draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
||||
void draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#define LAYER_MAX 32
|
||||
#define LAYER_NAME_LEN 32
|
||||
|
||||
typedef enum {
|
||||
LAYER_TYPE_DESKTOP,
|
||||
LAYER_TYPE_WINDOW,
|
||||
LAYER_TYPE_MOUSE,
|
||||
LAYER_TYPE_OVERLAY,
|
||||
} layer_type_t;
|
||||
|
||||
typedef struct layer {
|
||||
UINT32 id;
|
||||
char name[LAYER_NAME_LEN];
|
||||
layer_type_t type;
|
||||
SSINT32 x, y;
|
||||
UINT32 w, h;
|
||||
SSINT32 z;
|
||||
bool visible;
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buffer;
|
||||
struct layer* next;
|
||||
} layer_t;
|
||||
|
||||
// Initialization — allocates back buffer, registers keyboard handler
|
||||
void layer_init(void);
|
||||
|
||||
// Layer management
|
||||
layer_t* layer_create(String name, layer_type_t type, UINT32 w, UINT32 h);
|
||||
void layer_destroy(layer_t* layer);
|
||||
void layer_set_z(layer_t* layer, SSINT32 z);
|
||||
void layer_set_pos(layer_t* layer, SSINT32 x, SSINT32 y);
|
||||
void layer_set_visible(layer_t* layer, bool visible);
|
||||
layer_t* layer_get_by_id(UINT32 id);
|
||||
layer_t* layer_get_focused(void);
|
||||
|
||||
// Compositor task entry
|
||||
void layer_compositor_task(void);
|
||||
+2
-1
@@ -3,6 +3,7 @@
|
||||
#include <efi.h>
|
||||
#include <memory/pmm.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#define TASK_STACK_SIZE (PAGE_SIZE * 4) // 16 KB kernel stack per task
|
||||
#define TASK_MAX 32
|
||||
@@ -26,7 +27,7 @@ typedef struct task {
|
||||
} task_t;
|
||||
|
||||
// Create a new task. Returns task pointer or NULL on failure.
|
||||
task_t* task_create(const char* name, void (*entry)(void));
|
||||
task_t* task_create(String name, void (*entry)(void));
|
||||
|
||||
// Yield CPU to next ready task (cooperative)
|
||||
void yield(void);
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efiser.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
struct serial_context { // 串行内容结构体
|
||||
EFI_SERIAL_IO_PROTOCOL *SerialIo;
|
||||
@@ -10,7 +11,7 @@ struct serial_context { // 串行内容结构体
|
||||
extern serial_context g_serial;
|
||||
|
||||
void serial_init(EFI_SERIAL_IO_PROTOCOL *SerialIo); // 初始化串行驱动
|
||||
void serial_write(const char *str); // 往串行写string
|
||||
void serial_write(String str); // 往串行写string
|
||||
void serial_write_char(char c); // 往串行写char(不推荐使用)
|
||||
void serial_write_hex(UINTN val); // 往串行写十六进制数字
|
||||
char serial_read_char(); // 读串行
|
||||
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// === Unified string types ===
|
||||
// Use these throughout the kernel instead of raw char*/const char*.
|
||||
|
||||
typedef const char* String; // 8-bit narrow string
|
||||
typedef const uint16_t* WString; // 16-bit wide string (CHAR16)
|
||||
|
||||
// === Narrow string utilities (String) ===
|
||||
|
||||
static inline SUINT32 str_len(String s) {
|
||||
SUINT32 i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline SSINT32 str_cmp(String a, String b) {
|
||||
while (*a && *a == *b) { a++; b++; }
|
||||
return (SUINT8)*a - (SUINT8)*b;
|
||||
}
|
||||
|
||||
static inline bool str_eq(String a, String b) {
|
||||
return str_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
// Copy up to max-1 chars, always null-terminates.
|
||||
static inline void str_copy(char* dst, String src, SUINT32 max) {
|
||||
if (max == 0) return;
|
||||
SUINT32 i = 0;
|
||||
while (src[i] && i < max - 1) {
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
// === Wide string utilities (WString) ===
|
||||
|
||||
static inline SUINT32 wstr_len(WString s) {
|
||||
SUINT32 i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline SSINT32 wstr_cmp(WString a, WString b) {
|
||||
while (*a && *a == *b) { a++; b++; }
|
||||
return (SUINT16)*a - (SUINT16)*b;
|
||||
}
|
||||
|
||||
static inline bool wstr_eq(WString a, WString b) {
|
||||
return wstr_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
static inline void wstr_copy(uint16_t* dst, WString src, SUINT32 max) {
|
||||
if (max == 0) return;
|
||||
SUINT32 i = 0;
|
||||
while (src[i] && i < max - 1) {
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
// Convert wide string to ASCII (non-printable -> '?')
|
||||
static inline void wstr_to_ascii(char* dst, WString src, SUINT32 max) {
|
||||
if (max == 0) return;
|
||||
SUINT32 i = 0;
|
||||
while (src[i] && i < max - 1) {
|
||||
if (src[i] >= 0x20 && src[i] <= 0x7E)
|
||||
dst[i] = (char)src[i];
|
||||
else
|
||||
dst[i] = '?';
|
||||
i++;
|
||||
}
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
// === Memory utilities ===
|
||||
|
||||
static inline void mem_set(void* dst, SUINT8 val, SUINT32 size) {
|
||||
SUINT8* d = (SUINT8*)dst;
|
||||
for (SUINT32 i = 0; i < size; i++) d[i] = val;
|
||||
}
|
||||
|
||||
static inline void mem_copy(void* dst, const void* src, SUINT32 size) {
|
||||
SUINT8* d = (SUINT8*)dst;
|
||||
const SUINT8* s = (const SUINT8*)src;
|
||||
for (SUINT32 i = 0; i < size; i++) d[i] = s[i];
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Signed integers
|
||||
#define SSINT8 int8_t
|
||||
#define SSINT16 int16_t
|
||||
#define SSINT32 int32_t
|
||||
#define SSINT64 int64_t
|
||||
|
||||
// Unsigned integers
|
||||
#define SUINT8 uint8_t
|
||||
#define SUINT16 uint16_t
|
||||
#define SUINT32 uint32_t
|
||||
#define SUINT64 uint64_t
|
||||
+15
-25
@@ -1,7 +1,7 @@
|
||||
#include <fs.h>
|
||||
#include <serial.h>
|
||||
#include <memory/heap.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
extern EFI_SYSTEM_TABLE *ST;
|
||||
|
||||
@@ -216,7 +216,7 @@ static EFI_STATUS find_mbr_partition(struct block_dev *dev, UINT64 *StartLBA) {
|
||||
struct MBRPart *Parts = (struct MBRPart*)(Buf + 446);
|
||||
// Verify at least one non-zero partition entry exists
|
||||
BOOLEAN has_part = FALSE;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (SSINT32 i = 0; i < 4; i++) {
|
||||
if (Parts[i].Type != 0x00 && Parts[i].Type != 0xEE) {
|
||||
has_part = TRUE;
|
||||
break;
|
||||
@@ -224,7 +224,7 @@ static EFI_STATUS find_mbr_partition(struct block_dev *dev, UINT64 *StartLBA) {
|
||||
}
|
||||
if (!has_part) { kfree(Buf); return EFI_NOT_FOUND; }
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (SSINT32 i = 0; i < 4; i++) {
|
||||
UINT8 t = Parts[i].Type;
|
||||
if (t == 0x00 || t == 0xEE) continue;
|
||||
if (t == MBR_TYPE_FAT12 || t == MBR_TYPE_FAT16 ||
|
||||
@@ -238,7 +238,7 @@ static EFI_STATUS find_mbr_partition(struct block_dev *dev, UINT64 *StartLBA) {
|
||||
}
|
||||
|
||||
// Fallback: first non-empty partition
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (SSINT32 i = 0; i < 4; i++) {
|
||||
if (Parts[i].Type != 0x00) {
|
||||
*StartLBA = Parts[i].LBABegin;
|
||||
kfree(Buf);
|
||||
@@ -361,7 +361,7 @@ static EFI_STATUS fat_init(struct fat_fs *fs, struct block_dev *dev, UINT64 Part
|
||||
|
||||
static UINT8 lfn_checksum(const UINT8 *SFN) {
|
||||
UINT8 sum = 0;
|
||||
for (int i = 0; i < 11; i++)
|
||||
for (SSINT32 i = 0; i < 11; i++)
|
||||
sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + SFN[i];
|
||||
return sum;
|
||||
}
|
||||
@@ -381,17 +381,17 @@ static void lfn_reset(struct lfn_state *lfn) {
|
||||
static void lfn_add(struct lfn_state *lfn, const UINT8 *E) {
|
||||
if (lfn->count >= LFN_MAX_FRAGS) return;
|
||||
UINTN pos = 0;
|
||||
for (int i = 0; i < 5 && pos < LFN_FRAG_SIZE; i++) {
|
||||
for (SSINT32 i = 0; i < 5 && pos < LFN_FRAG_SIZE; i++) {
|
||||
CHAR16 c = *(const UINT16*)(E + 1 + i * 2);
|
||||
if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; }
|
||||
lfn->frags[lfn->count][pos++] = c;
|
||||
}
|
||||
for (int i = 0; i < 6 && pos < LFN_FRAG_SIZE; i++) {
|
||||
for (SSINT32 i = 0; i < 6 && pos < LFN_FRAG_SIZE; i++) {
|
||||
CHAR16 c = *(const UINT16*)(E + 14 + i * 2);
|
||||
if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; }
|
||||
lfn->frags[lfn->count][pos++] = c;
|
||||
}
|
||||
for (int i = 0; i < 2 && pos < LFN_FRAG_SIZE; i++) {
|
||||
for (SSINT32 i = 0; i < 2 && pos < LFN_FRAG_SIZE; i++) {
|
||||
CHAR16 c = *(const UINT16*)(E + 28 + i * 2);
|
||||
if (c == 0x0000 || c == 0xFFFF) { lfn->frags[lfn->count][pos] = 0; return; }
|
||||
lfn->frags[lfn->count][pos++] = c;
|
||||
@@ -413,11 +413,11 @@ static void lfn_build(struct lfn_state *lfn, CHAR16 *out, UINTN out_size) {
|
||||
|
||||
static void sfn_to_name(const UINT8 *E, CHAR16 *out, UINTN out_size) {
|
||||
UINTN pos = 0;
|
||||
for (int i = 0; i < 8 && pos < out_size - 1; i++)
|
||||
for (SSINT32 i = 0; i < 8 && pos < out_size - 1; i++)
|
||||
if (E[i] != ' ') out[pos++] = E[i];
|
||||
UINTN ext_start = pos;
|
||||
BOOLEAN has_ext = FALSE;
|
||||
for (int i = 8; i < 11 && pos < out_size - 1; i++) {
|
||||
for (SSINT32 i = 8; i < 11 && pos < out_size - 1; i++) {
|
||||
if (E[i] != ' ') {
|
||||
if (!has_ext) { out[pos++] = '.'; has_ext = TRUE; ext_start = pos; }
|
||||
out[pos++] = E[i];
|
||||
@@ -533,24 +533,17 @@ static BOOLEAN g_fs_inited = FALSE;
|
||||
|
||||
struct list_ctx {
|
||||
struct fat_fs *fs;
|
||||
int depth;
|
||||
SSINT32 depth;
|
||||
};
|
||||
|
||||
static void name_to_ascii(const CHAR16 *Name, char *Ascii, UINTN ascii_sz) {
|
||||
UINTN i = 0;
|
||||
for (; Name[i] && i < ascii_sz - 1; i++) {
|
||||
if (Name[i] >= 0x20 && Name[i] <= 0x7E)
|
||||
Ascii[i] = (char)Name[i];
|
||||
else
|
||||
Ascii[i] = '?';
|
||||
}
|
||||
Ascii[i] = 0;
|
||||
wstr_to_ascii(Ascii, (WString)Name, ascii_sz);
|
||||
}
|
||||
|
||||
static void list_callback(void *ctx, const CHAR16 *Name, UINT8 Attr,
|
||||
UINT32 Size, UINT32 FirstClus) {
|
||||
struct list_ctx *lc = (struct list_ctx*)ctx;
|
||||
for (int i = 0; i < lc->depth; i++) serial_write(" ");
|
||||
for (SSINT32 i = 0; i < lc->depth; i++) serial_write(" ");
|
||||
|
||||
serial_write(Attr & 0x10 ? "[DIR] " : "[FILE] ");
|
||||
|
||||
@@ -633,10 +626,7 @@ struct find_ctx {
|
||||
};
|
||||
|
||||
static BOOLEAN name_match(const CHAR16 *a, const CHAR16 *b) {
|
||||
UINTN i = 0;
|
||||
for (; a[i] && b[i]; i++)
|
||||
if (a[i] != b[i]) return FALSE;
|
||||
return a[i] == 0 && b[i] == 0;
|
||||
return wstr_eq((WString)a, (WString)b);
|
||||
}
|
||||
|
||||
static void find_callback(void *ctx, const CHAR16 *Name, UINT8 Attr,
|
||||
@@ -651,7 +641,7 @@ static void find_callback(void *ctx, const CHAR16 *Name, UINT8 Attr,
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS fs_read(const CHAR16 *Path, void **Buffer, UINTN *Size) {
|
||||
EFI_STATUS fs_read(WString Path, void **Buffer, UINTN *Size) {
|
||||
if (!g_fs_inited) return EFI_NOT_READY;
|
||||
|
||||
const CHAR16 *p = Path;
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
#include <graphics/layer.h>
|
||||
#include <graphics/draw.h>
|
||||
#include <graphics/context.h>
|
||||
#include <memory/heap.h>
|
||||
#include <memory/pmm.h>
|
||||
#include <scheduler.h>
|
||||
#include <serial.h>
|
||||
#include <idt.h>
|
||||
#include <pic.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
// --- Layer list (sorted by z, lowest first) ---
|
||||
|
||||
static layer_t g_layers[LAYER_MAX];
|
||||
static UINT32 g_layer_count = 0;
|
||||
static layer_t* g_layer_list = NULL;
|
||||
|
||||
// Compositor back buffer
|
||||
static EFI_GRAPHICS_OUTPUT_BLT_PIXEL* g_back_buffer = NULL;
|
||||
|
||||
// Focus tracking
|
||||
static layer_t* g_focused = NULL;
|
||||
|
||||
// Shift+F10 state (set by IRQ handler, consumed by compositor)
|
||||
static volatile bool g_shift_held = false;
|
||||
static volatile bool g_switch_pending = false;
|
||||
static volatile layer_t* g_switch_target = NULL;
|
||||
|
||||
// PS/2 scan code set 1
|
||||
#define PS2_F10 0x44
|
||||
#define PS2_LSHIFT 0x2A
|
||||
#define PS2_RSHIFT 0x36
|
||||
#define PS2_BREAK_BIT 0x80
|
||||
|
||||
// Forward declare
|
||||
static void layer_insert_sorted(layer_t* layer);
|
||||
static void layer_remove(layer_t* layer);
|
||||
static layer_t* find_next_window(layer_t* from);
|
||||
|
||||
// --- PS/2 keyboard IRQ handler ---
|
||||
|
||||
static void ps2_irq_handler(trap_frame* frame) {
|
||||
(void)frame;
|
||||
pic_send_eoi(1);
|
||||
|
||||
UINT8 sc;
|
||||
ASM("inb %1, %0" : "=a"(sc) : "Nd"((UINT16)0x60));
|
||||
|
||||
bool is_break = (sc & PS2_BREAK_BIT) != 0;
|
||||
UINT8 code = sc & 0x7F;
|
||||
|
||||
if (code == PS2_LSHIFT || code == PS2_RSHIFT) {
|
||||
g_shift_held = !is_break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_break && g_shift_held && code == PS2_F10) {
|
||||
layer_t* next = find_next_window((layer_t*)g_focused);
|
||||
if (next) {
|
||||
g_switch_target = next;
|
||||
g_switch_pending = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Layer management ---
|
||||
|
||||
layer_t* layer_create(const char* name, layer_type_t type, UINT32 w, UINT32 h) {
|
||||
if (g_layer_count >= LAYER_MAX) {
|
||||
serial_write("LAYER: limit reached\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT32 id = g_layer_count++;
|
||||
layer_t* layer = &g_layers[id];
|
||||
|
||||
layer->id = id;
|
||||
layer->type = type;
|
||||
layer->x = 0;
|
||||
layer->y = 0;
|
||||
layer->w = w;
|
||||
layer->h = h;
|
||||
layer->z = 0;
|
||||
layer->visible = true;
|
||||
layer->next = NULL;
|
||||
|
||||
str_copy(layer->name, name, LAYER_NAME_LEN);
|
||||
|
||||
UINTN buf_size = (UINTN)w * h * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
|
||||
layer->buffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)kmalloc(buf_size);
|
||||
if (!layer->buffer) {
|
||||
serial_write("LAYER: buffer alloc failed for ");
|
||||
serial_write(name);
|
||||
serial_write("\n");
|
||||
g_layer_count--;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = layer->buffer;
|
||||
for (UINTN i = 0; i < (UINTN)w * h; i++) {
|
||||
p->Blue = 0; p->Green = 0; p->Red = 0; p->Reserved = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
layer_insert_sorted(layer);
|
||||
|
||||
serial_write("LAYER: created '");
|
||||
serial_write(name);
|
||||
serial_write("' id=");
|
||||
serial_write_hex(id);
|
||||
serial_write("\n");
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
void layer_destroy(layer_t* layer) {
|
||||
if (!layer) return;
|
||||
|
||||
layer_remove(layer);
|
||||
|
||||
if (layer->buffer) {
|
||||
kfree(layer->buffer);
|
||||
layer->buffer = NULL;
|
||||
}
|
||||
|
||||
if (g_focused == layer) g_focused = NULL;
|
||||
if (g_switch_target == layer) {
|
||||
g_switch_target = NULL;
|
||||
g_switch_pending = false;
|
||||
}
|
||||
|
||||
serial_write("LAYER: destroyed '");
|
||||
serial_write(layer->name);
|
||||
serial_write("'\n");
|
||||
}
|
||||
|
||||
layer_t* layer_get_by_id(UINT32 id) {
|
||||
if (id >= LAYER_MAX) return NULL;
|
||||
layer_t* l = &g_layers[id];
|
||||
return l->buffer ? l : NULL;
|
||||
}
|
||||
|
||||
layer_t* layer_get_focused(void) {
|
||||
return g_focused;
|
||||
}
|
||||
|
||||
void layer_set_z(layer_t* layer, SSINT32 z) {
|
||||
if (!layer) return;
|
||||
layer_remove(layer);
|
||||
layer->z = z;
|
||||
layer_insert_sorted(layer);
|
||||
}
|
||||
|
||||
void layer_set_pos(layer_t* layer, SSINT32 x, SSINT32 y) {
|
||||
if (!layer) return;
|
||||
layer->x = x;
|
||||
layer->y = y;
|
||||
}
|
||||
|
||||
void layer_set_visible(layer_t* layer, bool visible) {
|
||||
if (!layer) return;
|
||||
layer->visible = visible;
|
||||
}
|
||||
|
||||
// --- Sorted insert/remove ---
|
||||
|
||||
static void layer_insert_sorted(layer_t* layer) {
|
||||
layer->next = NULL;
|
||||
|
||||
if (!g_layer_list || layer->z < g_layer_list->z) {
|
||||
layer->next = g_layer_list;
|
||||
g_layer_list = layer;
|
||||
return;
|
||||
}
|
||||
|
||||
layer_t* cur = g_layer_list;
|
||||
while (cur->next && cur->next->z <= layer->z) {
|
||||
cur = cur->next;
|
||||
}
|
||||
layer->next = cur->next;
|
||||
cur->next = layer;
|
||||
}
|
||||
|
||||
static void layer_remove(layer_t* layer) {
|
||||
if (!g_layer_list) return;
|
||||
|
||||
if (g_layer_list == layer) {
|
||||
g_layer_list = layer->next;
|
||||
layer->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
layer_t* cur = g_layer_list;
|
||||
while (cur->next && cur->next != layer) {
|
||||
cur = cur->next;
|
||||
}
|
||||
if (cur->next == layer) {
|
||||
cur->next = layer->next;
|
||||
layer->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static layer_t* find_next_window(layer_t* from) {
|
||||
layer_t* start = from ? from->next : g_layer_list;
|
||||
if (!start) start = g_layer_list;
|
||||
|
||||
layer_t* cur = start;
|
||||
do {
|
||||
if (cur->type == LAYER_TYPE_WINDOW && cur->visible) {
|
||||
return cur;
|
||||
}
|
||||
cur = cur->next;
|
||||
if (!cur) cur = g_layer_list;
|
||||
} while (cur != start);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --- Initialization ---
|
||||
|
||||
void layer_init(void) {
|
||||
UINT32 hr = g_gfx.hr;
|
||||
UINT32 vr = g_gfx.vr;
|
||||
|
||||
UINTN buf_size = (UINTN)hr * vr * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
|
||||
g_back_buffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)kmalloc(buf_size);
|
||||
if (!g_back_buffer) {
|
||||
serial_write("LAYER: back buffer alloc FAILED\n");
|
||||
return;
|
||||
}
|
||||
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = g_back_buffer;
|
||||
for (UINTN i = 0; i < (UINTN)hr * vr; i++) {
|
||||
p->Blue = 0; p->Green = 0; p->Red = 0; p->Reserved = 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
// Register keyboard IRQ and unmask
|
||||
idt_set_handler(PIC_IRQ_BASE + 1, ps2_irq_handler);
|
||||
pic_unmask_irq(1);
|
||||
|
||||
serial_write("LAYER: compositor init OK (back buffer = ");
|
||||
serial_write_hex(buf_size);
|
||||
serial_write(" bytes)\n");
|
||||
}
|
||||
|
||||
// --- Compositor task ---
|
||||
|
||||
void layer_compositor_task(void) {
|
||||
serial_write("LAYER: compositor task running\n");
|
||||
|
||||
UINT32 hr = g_gfx.hr;
|
||||
UINT32 vr = g_gfx.vr;
|
||||
|
||||
while (1) {
|
||||
// Process deferred Shift+F10 switch (safe: not inside IRQ)
|
||||
if (g_switch_pending) {
|
||||
g_switch_pending = false;
|
||||
layer_t* target = (layer_t*)g_switch_target;
|
||||
if (target && target->visible && target->type == LAYER_TYPE_WINDOW) {
|
||||
g_focused = target;
|
||||
layer_set_z(target, 99);
|
||||
serial_write("LAYER: Shift+F10 -> '");
|
||||
serial_write(target->name);
|
||||
serial_write("'\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Clear back buffer
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0};
|
||||
draw_set_target(g_back_buffer, hr, vr);
|
||||
draw_rect(0, 0, hr, vr, black);
|
||||
draw_set_default_target();
|
||||
|
||||
// Composite layers from lowest z to highest
|
||||
layer_t* cur = g_layer_list;
|
||||
while (cur) {
|
||||
if (cur->visible && cur->buffer) {
|
||||
SSINT32 sx = 0, sy = 0;
|
||||
SSINT32 dx = cur->x, dy = cur->y;
|
||||
UINT32 sw = cur->w, sh = cur->h;
|
||||
|
||||
if (dx < 0) { sx = -dx; sw -= sx; dx = 0; }
|
||||
if (dy < 0) { sy = -dy; sh -= sy; dy = 0; }
|
||||
if (dx + (SSINT32)sw > (SSINT32)hr) sw = hr - dx;
|
||||
if (dy + (SSINT32)sh > (SSINT32)vr) sh = vr - dy;
|
||||
if (sw == 0 || sh == 0) { cur = cur->next; continue; }
|
||||
|
||||
for (UINT32 row = 0; row < sh; row++) {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* src = cur->buffer + ((UINTN)cur->w * (sy + row)) + sx;
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = g_back_buffer + ((UINTN)hr * (dy + row)) + dx;
|
||||
for (UINT32 col = 0; col < sw; col++) {
|
||||
dst->Blue = src->Blue;
|
||||
dst->Green = src->Green;
|
||||
dst->Red = src->Red;
|
||||
dst->Reserved = src->Reserved;
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// Blit to screen
|
||||
g_gfx.GOP->Blt(
|
||||
g_gfx.GOP,
|
||||
g_back_buffer,
|
||||
EfiBltBufferToVideo,
|
||||
0, 0, 0, 0,
|
||||
hr, vr, 0
|
||||
);
|
||||
|
||||
yield();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <gdt.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
#include <serial.h>
|
||||
|
||||
static gdt_entry g_gdt[7]; // 5 segments + TSS (2 entries)
|
||||
@@ -41,7 +42,7 @@ static void tss_set_descriptor(UINT32 index) {
|
||||
void gdt_init(void) {
|
||||
serial_write("GDT: initializing\n");
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
for (SSINT32 i = 0; i < 7; i++) {
|
||||
g_gdt[i] = {0};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <idt.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
#include <pic.h>
|
||||
#include <serial.h>
|
||||
|
||||
@@ -47,13 +48,13 @@ void idt_init(void) {
|
||||
serial_write("IDT: initializing 256 entries\n");
|
||||
|
||||
// Clear IDT
|
||||
for (int i = 0; i < 256; i++) {
|
||||
for (SSINT32 i = 0; i < 256; i++) {
|
||||
g_idt[i] = {0};
|
||||
g_handlers[i] = NULL;
|
||||
}
|
||||
|
||||
// Install all 256 ISR stubs
|
||||
for (int i = 0; i < 256; i++) {
|
||||
for (SSINT32 i = 0; i < 256; i++) {
|
||||
idt_set_entry(i, (UINT64)isr_stub_table[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <pic.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
#include <serial.h>
|
||||
|
||||
static inline void outb(UINT16 port, UINT8 val) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <pit.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
#include <pic.h>
|
||||
#include <serial.h>
|
||||
|
||||
|
||||
+39
-27
@@ -1,9 +1,11 @@
|
||||
#include <efi.h>
|
||||
#include <graphics/context.h>
|
||||
#include <graphics/draw.h>
|
||||
#include <graphics/layer.h>
|
||||
#include <fonts/pixel_font.h>
|
||||
#include <serial.h>
|
||||
#include <common.h>
|
||||
#include <string_utils.h>
|
||||
#include <memory/pmm.h>
|
||||
#include <memory/heap.h>
|
||||
#include <scheduler.h>
|
||||
@@ -128,7 +130,7 @@ extern "C" void kernel_main() {
|
||||
fs_list();
|
||||
}
|
||||
|
||||
pf_print("Welcome to Sylva OS!\n");
|
||||
// pf_print("Welcome to Sylva OS!\n");
|
||||
serial_write(" Kernel prepared well.\n");
|
||||
|
||||
// --- Interrupt infrastructure ---
|
||||
@@ -155,34 +157,44 @@ extern "C" void kernel_main() {
|
||||
// --- Multitasking demo ---
|
||||
serial_write("Sylva: creating tasks...\n");
|
||||
|
||||
// Task A: prints messages — preemption handles time slicing
|
||||
task_create("taskA", []() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
serial_write("[taskA] running iteration ");
|
||||
serial_write_hex(i);
|
||||
serial_write("\n");
|
||||
for (volatile int j = 0; j < 50000000; j++) {}
|
||||
}
|
||||
serial_write("[taskA] done\n");
|
||||
});
|
||||
// Init compositor (allocates back buffer, registers keyboard handler)
|
||||
layer_init();
|
||||
|
||||
// Task B: prints messages
|
||||
task_create("taskB", []() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
serial_write("[taskB] hello from taskB #");
|
||||
serial_write_hex(i);
|
||||
serial_write("\n");
|
||||
for (volatile int j = 0; j < 50000000; j++) {}
|
||||
}
|
||||
serial_write("[taskB] done\n");
|
||||
});
|
||||
// Create desktop layer (full screen, z=0)
|
||||
layer_t* desktop = layer_create("desktop", LAYER_TYPE_DESKTOP, g_gfx.hr, g_gfx.vr);
|
||||
if (desktop) {
|
||||
layer_set_z(desktop, 0);
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL bg = {180, 80, 40, 0};
|
||||
draw_set_target(desktop->buffer, g_gfx.hr, g_gfx.vr);
|
||||
draw_rect(0, 0, g_gfx.hr, g_gfx.vr, bg);
|
||||
draw_set_default_target();
|
||||
layer_set_pos(desktop, 0, 0);
|
||||
}
|
||||
|
||||
// Task C: short task
|
||||
task_create("taskC", []() {
|
||||
serial_write("[taskC] quick task\n");
|
||||
for (volatile int j = 0; j < 50000000; j++) {}
|
||||
serial_write("[taskC] finished\n");
|
||||
});
|
||||
// Create window 1 (centered)
|
||||
layer_t* win1 = layer_create("window_1", LAYER_TYPE_WINDOW, 300, 200);
|
||||
if (win1) {
|
||||
layer_set_pos(win1, (SSINT32)(g_gfx.hr / 2) - 150, (SSINT32)(g_gfx.vr / 2) - 100);
|
||||
layer_set_z(win1, 1);
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL win_color = {200, 200, 200, 0};
|
||||
draw_set_target(win1->buffer, 300, 200);
|
||||
draw_rect(0, 0, 299, 199, win_color);
|
||||
draw_set_default_target();
|
||||
}
|
||||
|
||||
// Create window 2 (offset from center)
|
||||
layer_t* win2 = layer_create("window_2", LAYER_TYPE_WINDOW, 250, 180);
|
||||
if (win2) {
|
||||
layer_set_pos(win2, (SSINT32)(g_gfx.hr / 2) - 50, (SSINT32)(g_gfx.vr / 2) - 40);
|
||||
layer_set_z(win2, 2);
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL win2_color = {180, 220, 140, 0};
|
||||
draw_set_target(win2->buffer, 250, 180);
|
||||
draw_rect(0, 0, 249, 179, win2_color);
|
||||
draw_set_default_target();
|
||||
}
|
||||
|
||||
// Compositor task (replaces the old demo tasks)
|
||||
task_create("compositor", layer_compositor_task);
|
||||
|
||||
serial_write("Sylva: starting preemptive scheduler\n");
|
||||
scheduler_run(); // never returns
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <memory/heap.h>
|
||||
#include <memory/pmm.h>
|
||||
#include <serial.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
struct heap_block {
|
||||
UINTN size; // includes header; bit 0 = 1 used, 0 free
|
||||
@@ -184,10 +185,7 @@ void* kcalloc(UINTN num, UINTN size) {
|
||||
UINTN total = num * size;
|
||||
void* ptr = kmalloc(total);
|
||||
if (ptr) {
|
||||
UINT8* p = (UINT8*)ptr;
|
||||
for (UINTN i = 0; i < total; i++) {
|
||||
p[i] = 0;
|
||||
}
|
||||
mem_set(ptr, 0, total);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
@@ -216,11 +214,7 @@ void* krealloc(void* ptr, UINTN new_size) {
|
||||
|
||||
void* new_ptr = kmalloc(new_size);
|
||||
if (new_ptr) {
|
||||
UINT8* src = (UINT8*)ptr;
|
||||
UINT8* dst = (UINT8*)new_ptr;
|
||||
for (UINTN i = 0; i < old_size; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
mem_copy(new_ptr, ptr, old_size);
|
||||
kfree(ptr);
|
||||
}
|
||||
return new_ptr;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <memory/pmm.h>
|
||||
#include <common.h>
|
||||
#include <serial.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
extern EFI_SYSTEM_TABLE *ST;
|
||||
|
||||
|
||||
@@ -53,12 +53,7 @@ task_t* task_create(const char* name, void (*entry)(void)) {
|
||||
task->time_slice = TIME_SLICE_DEFAULT;
|
||||
|
||||
// Copy name
|
||||
const char* s = name;
|
||||
char* d = task->name;
|
||||
for (int i = 0; i < TASK_NAME_LEN - 1 && *s; i++) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d = '\0';
|
||||
str_copy(task->name, name, TASK_NAME_LEN);
|
||||
|
||||
// Set up initial stack for first context_switch into this task.
|
||||
// Stack grows downward. context_switch will pop 6 regs then ret.
|
||||
|
||||
+3
-2
@@ -1,4 +1,5 @@
|
||||
#include <serial.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
extern EFI_SYSTEM_TABLE *ST;
|
||||
|
||||
@@ -21,7 +22,7 @@ void serial_write_char(char c) {
|
||||
}
|
||||
}
|
||||
|
||||
void serial_write(const char *str) {
|
||||
void serial_write(String str) {
|
||||
if (!g_serial.SerialIo) {
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, (CHAR16*)L"serial: null io\n");
|
||||
return;
|
||||
@@ -34,7 +35,7 @@ void serial_write(const char *str) {
|
||||
void serial_write_hex(UINTN val) {
|
||||
char buf[19];
|
||||
buf[0] = '0'; buf[1] = 'x';
|
||||
for (int i = 17; i >= 2; i--) {
|
||||
for (SSINT32 i = 17; i >= 2; i--) {
|
||||
UINTN digit = val & 0xF;
|
||||
buf[i] = digit < 10 ? '0' + digit : 'A' + digit - 10;
|
||||
val >>= 4;
|
||||
|
||||
Reference in New Issue
Block a user