feat: panic, printf, logo and something i dont remember
This commit is contained in:
+1
-1
@@ -1,3 +1,3 @@
|
||||
.cache
|
||||
build
|
||||
kirby.h
|
||||
.venv
|
||||
+23
-11
@@ -58,13 +58,12 @@ int main()
|
||||
|
||||
status = gBS->AllocatePool(EfiLoaderData, sizeof(Bootinfo), (void**)&boot_info);
|
||||
|
||||
boot_info->base = (uintn_t*)gop->Mode->FrameBufferBase;
|
||||
boot_info->base_size = gop->Mode->FrameBufferSize;
|
||||
boot_info->height = gop->Mode->Information->VerticalResolution;
|
||||
boot_info->width = gop->Mode->Information->HorizontalResolution;
|
||||
boot_info->pitch = gop->Mode->Information->PixelsPerScanLine;
|
||||
boot_info->framebuffer.base = (uintn_t*)gop->Mode->FrameBufferBase;
|
||||
boot_info->framebuffer.base_size = gop->Mode->FrameBufferSize;
|
||||
boot_info->framebuffer.height = gop->Mode->Information->VerticalResolution;
|
||||
boot_info->framebuffer.width = gop->Mode->Information->HorizontalResolution;
|
||||
boot_info->framebuffer.pitch = gop->Mode->Information->PixelsPerScanLine;
|
||||
|
||||
// woah letsgoo
|
||||
uintn_t map_size = 0;
|
||||
efi_memory_descriptor_t *map = NULL;
|
||||
uintn_t map_key;
|
||||
@@ -75,17 +74,30 @@ int main()
|
||||
|
||||
gBS->GetMemoryMap(&map_size, NULL, &map_key, &desc_size, &desc_version);
|
||||
map_size += 4096;
|
||||
gBS->AllocatePool(EfiLoaderData, map_size, (void**)&map);
|
||||
status = gBS->ExitBootServices(IM, map_key);
|
||||
// woah letsgoo
|
||||
status = gBS->AllocatePool(EfiLoaderData, map_size, (void**)&map);
|
||||
if (EFI_ERROR(status)) {
|
||||
ST->ConOut->OutputString(ST->ConOut, L"Failed to allocate pool");
|
||||
}
|
||||
|
||||
do {
|
||||
status = gBS->GetMemoryMap(&map_size, map, &map_key, &desc_size, &desc_version);
|
||||
if (EFI_ERROR(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
boot_info->mem.descriptor_size = desc_size;
|
||||
boot_info->mem.descriptor_version = desc_version;
|
||||
boot_info->mem.map_size = map_size;
|
||||
boot_info->mem.map_key = map_key;
|
||||
boot_info->mem.map = map;
|
||||
|
||||
while (EFI_ERROR(status)) {
|
||||
gBS->GetMemoryMap(&map_size, map, &map_key, &desc_size, &desc_version);
|
||||
status = gBS->ExitBootServices(IM, map_key);
|
||||
if (status == EFI_SUCCESS) {
|
||||
break; // FUCK OFF;
|
||||
}
|
||||
map_size += 2 * desc_size;
|
||||
}
|
||||
} while (EFI_ERROR(status));
|
||||
|
||||
typedef void (__attribute__((sysv_abi)) *kentry)(Bootinfo*);
|
||||
kentry kmain = (kentry)kernel_addr;
|
||||
|
||||
@@ -9,4 +9,17 @@ typedef struct {
|
||||
bi_u64 width;
|
||||
bi_u64 height;
|
||||
bi_u64 pitch;
|
||||
} BI_Framebuffer;
|
||||
|
||||
typedef struct {
|
||||
void *map;
|
||||
bi_u64 map_size;
|
||||
bi_u64 descriptor_size;
|
||||
bi_u32 map_key;
|
||||
bi_u32 descriptor_version;
|
||||
} BI_MemoryMap;
|
||||
|
||||
typedef struct {
|
||||
BI_Framebuffer framebuffer;
|
||||
BI_MemoryMap mem;
|
||||
} Bootinfo;
|
||||
@@ -21,6 +21,7 @@ add_executable(kernel
|
||||
src/modules/memory.c
|
||||
src/modules/serial.c
|
||||
src/modules/console.c
|
||||
src/modules/panic.c
|
||||
data/font8x8_basic.c
|
||||
)
|
||||
|
||||
|
||||
+1265
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,8 @@
|
||||
void console_init(SG_Context *ctx);
|
||||
void console_clear(u32 color);
|
||||
void console_set_color(u32 color);
|
||||
void console_set_cursor_pos(SG_Point *p);
|
||||
void kprint(const char *str);
|
||||
void kprintf(const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "types.h"
|
||||
|
||||
static inline int abs(int n) {
|
||||
return (n < 0) ? -n : n;
|
||||
}
|
||||
|
||||
static inline i64 i64abs(i64 n) {
|
||||
return (n < 0) ? -n : n;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
__attribute__((noreturn)) void panic(const char *msg);
|
||||
+2
-5
@@ -2,12 +2,10 @@ ENTRY(kmain)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Смещаем точку сборки на 1МБ (как ты и грузишь) */
|
||||
. = 0x100000;
|
||||
|
||||
/* Сначала идет КОД. Это самое важное. */
|
||||
.text : {
|
||||
*(.text.entry) /* Если будет ассемблерный трамплин */
|
||||
*(.text.entry)
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
@@ -24,12 +22,11 @@ SECTIONS
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
/* ВЫРЕЗАЕМ ВЕСЬ МУСОР LINUX/GNU */
|
||||
/DISCARD/ : {
|
||||
*(.note*)
|
||||
*(.comment*)
|
||||
*(.eh_frame*)
|
||||
*(.interp) /* <--- Вот эта гадость содержала путь к ld-linux */
|
||||
*(.interp)
|
||||
*(.dynsym)
|
||||
*(.dynstr)
|
||||
}
|
||||
|
||||
+10
-5
@@ -4,22 +4,27 @@
|
||||
|
||||
#include "shitgui.h"
|
||||
#include "serial.h"
|
||||
#include "panic.h" // IWYU pragma: keep
|
||||
#include "../data/logo.h"
|
||||
|
||||
void kmain(Bootinfo* info) {
|
||||
u32 *fb = (u32*)info->base;
|
||||
u32 *fb = (u32*)info->framebuffer.base;
|
||||
if (!fb) return;
|
||||
|
||||
SG_Context sg_ctx = {0};
|
||||
sg_ctx.fb = fb;
|
||||
sg_ctx.height = info->height;
|
||||
sg_ctx.width = info->width;
|
||||
sg_ctx.pitch = info->pitch;
|
||||
sg_ctx.height = info->framebuffer.height;
|
||||
sg_ctx.width = info->framebuffer.width;
|
||||
sg_ctx.pitch = info->framebuffer.pitch;
|
||||
|
||||
serial_init();
|
||||
console_init(&sg_ctx);
|
||||
console_clear(0xFFFFFF);
|
||||
console_set_color(0x000000);
|
||||
kprint("Welcome to termOS!!!");
|
||||
SG_Point logo_point = {sg_ctx.width-100, 100};
|
||||
sg_put_img(&sg_ctx, &logo_point, &logo_img);
|
||||
kprint("Welcome to termOS!!!\n");
|
||||
kprintf("MemoryMap located at %x; \nMemory map size is %d", (u64)info->mem.map, (u64)info->mem.map_size);
|
||||
|
||||
while (1) { __asm__("hlt"); }
|
||||
}
|
||||
@@ -2,6 +2,10 @@
|
||||
#include "serial.h"
|
||||
#include "font.h"
|
||||
#include "shitgui.h"
|
||||
#include "math.h"
|
||||
#include "types.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
static SG_Context *ctx_ptr = nullptr;
|
||||
static SG_Point s_cursor_pos = {0};
|
||||
@@ -28,6 +32,12 @@ void console_clear(u32 color) {
|
||||
s_cursor_pos.y = 0;
|
||||
}
|
||||
|
||||
void console_set_cursor_pos(SG_Point *p) {
|
||||
if (!p) return;
|
||||
s_cursor_pos.x = p->x;
|
||||
s_cursor_pos.y = p->y;
|
||||
}
|
||||
|
||||
static void console_putc(char c) {
|
||||
serial_writec(c);
|
||||
if (!ctx_ptr) return;
|
||||
@@ -48,7 +58,91 @@ static void console_putc(char c) {
|
||||
|
||||
|
||||
void kprint(const char *str) {
|
||||
for (int i = 0; str[i] != '\0'; i++) console_putc(str[i]);
|
||||
for (i32 i = 0; str[i] != '\0'; i++) console_putc(str[i]);
|
||||
}
|
||||
|
||||
static void print_dec(const i64 n) {
|
||||
if (n < 0) console_putc('-');
|
||||
u64 u = abs(n);
|
||||
char buffer[32];
|
||||
i32 i = 0;
|
||||
|
||||
do {
|
||||
buffer[i] = (u % 10) + '0';
|
||||
u /= 10;
|
||||
i++;
|
||||
} while (u > 0);
|
||||
|
||||
while (--i >= 0) {
|
||||
console_putc(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_hex(u64 u) {
|
||||
console_putc('0');
|
||||
console_putc('x');
|
||||
|
||||
if (u == 0) {
|
||||
console_putc('0');
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[16];
|
||||
i32 i = 0;
|
||||
|
||||
while (u > 0) {
|
||||
i32 digit = u % 16;
|
||||
if (digit < 10) { buffer[i] = digit + '0'; }
|
||||
else { buffer[i] = digit - 10 + 'a'; }
|
||||
u /= 16;
|
||||
i++;
|
||||
}
|
||||
|
||||
while (--i >= 0) {
|
||||
console_putc(buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void kprintf(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
for (i32 i = 0; fmt[i] != '\0'; i++) {
|
||||
if (fmt[i] == '%') {
|
||||
i++;
|
||||
switch (fmt[i]) {
|
||||
case 's': {
|
||||
const char *str = va_arg(args, const char*);
|
||||
if (!str) str = "undefined";
|
||||
kprint(str);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
char c = (char)va_arg(args, int);
|
||||
console_putc(c);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
i32 num = va_arg(args, i32);
|
||||
print_dec(num);
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
u64 num = va_arg(args, u64);
|
||||
print_hex(num);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console_putc(fmt[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console_putc(fmt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void console_set_color(u32 color) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "panic.h"
|
||||
#include "console.h"
|
||||
#include "shitgui.h"
|
||||
|
||||
static void hlt_loop() {
|
||||
while (1) {
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__((noreturn)) void panic(const char *msg) {
|
||||
console_clear(0xFF0000);
|
||||
console_set_color(0xFFFFFF);
|
||||
|
||||
kprintf("\n\n");
|
||||
kprintf(" KERNEL PANIC \n");
|
||||
kprintf("-------------------\n");
|
||||
kprintf(" Reason: %s\n", msg);
|
||||
kprintf("-------------------\n");
|
||||
kprintf(" System halted.\n");
|
||||
|
||||
hlt_loop();
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "shitgui.h"
|
||||
|
||||
#define SHITGUI_TRANSPARENCY_KEY 0xFF00FF
|
||||
|
||||
void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img) {
|
||||
if (!ctx->fb || !img) return;
|
||||
@@ -17,7 +18,8 @@ void sg_put_img(SG_Context *ctx, SG_Point *p, SG_Image *img) {
|
||||
volatile u32 *dest_ptr = &ctx->fb[(start_y + y) * ctx->pitch + start_x];
|
||||
u32 *src_ptr = &img->buffer[y * img->width];
|
||||
for (u32 x = 0; x < draw_w; x++) {
|
||||
dest_ptr[x] = src_ptr[x];
|
||||
u32 color = src_ptr[x];
|
||||
if (color != SHITGUI_TRANSPARENCY_KEY) dest_ptr[x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
from PIL import Image
|
||||
|
||||
# НАШ МАГИЧЕСКИЙ ЦВЕТ (ЯДОВИТО-РОЗОВЫЙ)
|
||||
# Выбран, потому что его редко используют в реальных картинках.
|
||||
TRANSPARENCY_KEY = 0xFF00FF
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print(f"Usage: {sys.argv[0]} <input_image> <output_header_name>")
|
||||
sys.exit(1)
|
||||
|
||||
input_path = sys.argv[1]
|
||||
output_name = sys.argv[2]
|
||||
|
||||
try:
|
||||
# Конвертируем в RGBA, чтобы получить доступ к альфа-каналу
|
||||
img = Image.open(input_path).convert("RGBA")
|
||||
except Exception as e:
|
||||
print(f"Error opening image: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
width, height = img.size
|
||||
pixels = list(img.getdata())
|
||||
|
||||
# --- Генерация хедера ---
|
||||
c_code = []
|
||||
c_code.append(f"#pragma once")
|
||||
c_code.append(f'#include "shitgui.h"')
|
||||
c_code.append(f"")
|
||||
c_code.append(f"// Transparency Key (Magic Number for transparent pixels)")
|
||||
c_code.append(f"#define {output_name.upper()}_TRANSPARENCY_KEY 0x{TRANSPARENCY_KEY:06X}")
|
||||
c_code.append(f"")
|
||||
c_code.append(f"// Image: {width}x{height}")
|
||||
c_code.append(f"static const u32 {output_name}_data[] = {{")
|
||||
|
||||
line = " "
|
||||
for i, p in enumerate(pixels):
|
||||
r, g, b, a = p
|
||||
|
||||
# ГЛАВНОЕ ИЗМЕНЕНИЕ: Проверяем прозрачность
|
||||
# Если альфа < 128 (условно, "прозрачный"), используем ключ
|
||||
if a < 128:
|
||||
val = TRANSPARENCY_KEY
|
||||
else:
|
||||
val = (r << 16) | (g << 8) | b
|
||||
|
||||
line += f"0x{val:06X}, "
|
||||
|
||||
if (i + 1) % 8 == 0:
|
||||
c_code.append(line.strip())
|
||||
line = " "
|
||||
|
||||
if line.strip():
|
||||
c_code.append(line.strip())
|
||||
|
||||
c_code.append(f"}};")
|
||||
c_code.append(f"")
|
||||
c_code.append(f"static SG_Image {output_name}_img = {{")
|
||||
c_code.append(f" .width = {width},")
|
||||
c_code.append(f" .height = {height},")
|
||||
c_code.append(f" .buffer = (u32*){output_name}_data")
|
||||
c_code.append(f"}};")
|
||||
|
||||
# Сохраняем в файл
|
||||
output_filename = f"{output_name}.h"
|
||||
with open(output_filename, "w") as f:
|
||||
f.write("\n".join(c_code))
|
||||
|
||||
print(f"Done! Saved '{output_filename}' with transparency key 0x{TRANSPARENCY_KEY:06X}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1265
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user