Add basic vga kernel module
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,4 +2,4 @@ _o/
|
|||||||
build/
|
build/
|
||||||
picolibc/
|
picolibc/
|
||||||
picolibc-install/
|
picolibc-install/
|
||||||
lib/
|
/lib/
|
||||||
@@ -26,16 +26,19 @@ mkdir -p "$OUT_DIR"
|
|||||||
# Build TypeScript to JavaScript
|
# Build TypeScript to JavaScript
|
||||||
cd src/os
|
cd src/os
|
||||||
echo "Compiling TypeScript to JavaScript..."
|
echo "Compiling TypeScript to JavaScript..."
|
||||||
bun build --outdir ../../build --target node --bundle kernel/index.ts
|
bun build --outdir ../../build --target node --bundle src/index.ts
|
||||||
cd ../../
|
cd ../../
|
||||||
|
|
||||||
# Generate embedded JavaScript header
|
# Generate embedded JavaScript header
|
||||||
echo "Generating embedded JavaScript..."
|
echo "Generating embedded JavaScript..."
|
||||||
|
bun scripts/build_js.js
|
||||||
python3 scripts/embed_js.py build/index.js > "$BUILD_DIR/embedded_js.h"
|
python3 scripts/embed_js.py build/index.js > "$BUILD_DIR/embedded_js.h"
|
||||||
|
|
||||||
|
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
CFLAGS="-m32 -march=i686 -ffreestanding -nostdlib -fno-builtin"
|
CFLAGS="-m32 -march=i686 -ffreestanding -nostdlib -fno-builtin"
|
||||||
CFLAGS="$CFLAGS -I$PICOLIBC_INSTALL/include"
|
CFLAGS="$CFLAGS -I$PICOLIBC_INSTALL/include"
|
||||||
|
CFLAGS="$CFLAGS -I./lib/duktape/src"
|
||||||
CFLAGS="$CFLAGS -I./src/lib"
|
CFLAGS="$CFLAGS -I./src/lib"
|
||||||
CFLAGS="$CFLAGS -I./src"
|
CFLAGS="$CFLAGS -I./src"
|
||||||
CFLAGS="$CFLAGS -I$BUILD_DIR"
|
CFLAGS="$CFLAGS -I$BUILD_DIR"
|
||||||
|
|||||||
9
scripts/build_js.js
Executable file
9
scripts/build_js.js
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#! /usr/bin/env bun
|
||||||
|
import { readFileSync, writeFileSync } from "fs";
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
"build/index.js",
|
||||||
|
readFileSync("build/index.js", "utf-8")
|
||||||
|
.replaceAll("let ", "var ")
|
||||||
|
.replaceAll("const ", "var ")
|
||||||
|
);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <../lib/duktape/src/duktape.h>
|
#include <duktape.h>
|
||||||
#include "embedded_js.h"
|
#include "embedded_js.h"
|
||||||
|
|
||||||
#define WHITE_TXT 0x0F
|
#define WHITE_TXT 0x0F
|
||||||
@@ -10,15 +10,7 @@ unsigned int k_printf(char *message, unsigned int line);
|
|||||||
|
|
||||||
duk_context *ctx;
|
duk_context *ctx;
|
||||||
|
|
||||||
duk_ret_t native_print(duk_context *ctx)
|
duk_ret_t native_addrw(duk_context *ctx)
|
||||||
{
|
|
||||||
const char *msg = duk_to_string(ctx, 0);
|
|
||||||
// k_clear_screen();
|
|
||||||
k_printf((char *)msg, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
duk_ret_t native_write_memory(duk_context *ctx)
|
|
||||||
{
|
{
|
||||||
// Get the address (first argument)
|
// Get the address (first argument)
|
||||||
uint32_t address = (uint32_t)duk_to_uint32(ctx, 0);
|
uint32_t address = (uint32_t)duk_to_uint32(ctx, 0);
|
||||||
@@ -38,13 +30,9 @@ void kmain()
|
|||||||
// Initialize Duktape heap
|
// Initialize Duktape heap
|
||||||
ctx = duk_create_heap_default();
|
ctx = duk_create_heap_default();
|
||||||
|
|
||||||
// Register native print function
|
|
||||||
duk_push_c_function(ctx, native_print, DUK_VARARGS);
|
|
||||||
duk_put_global_string(ctx, "print");
|
|
||||||
|
|
||||||
// Register native memory write function
|
// Register native memory write function
|
||||||
duk_push_c_function(ctx, native_write_memory, 2);
|
duk_push_c_function(ctx, native_addrw, 2);
|
||||||
duk_put_global_string(ctx, "writeMemory");
|
duk_put_global_string(ctx, "$addrw");
|
||||||
|
|
||||||
// Execute embedded JavaScript code from build/index.js
|
// Execute embedded JavaScript code from build/index.js
|
||||||
duk_push_string(ctx, embedded_js_code);
|
duk_push_string(ctx, embedded_js_code);
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
const SCREEN_WIDTH = 80;
|
|
||||||
const SCREEN_HEIGHT = 25;
|
|
||||||
const VIDEO_MEMORY_START = 0xb8000;
|
|
||||||
|
|
||||||
clearScreen();
|
|
||||||
print("Welcome to Lints OS!", 0, 0, 0x0a); // Light green on black
|
|
||||||
|
|
||||||
function clearScreen(): void {
|
|
||||||
for (var row = 0; row < SCREEN_HEIGHT; row++) {
|
|
||||||
for (var col = 0; col < SCREEN_WIDTH; col++) {
|
|
||||||
const address = VIDEO_MEMORY_START + 2 * (row * SCREEN_WIDTH + col);
|
|
||||||
writeMemory(address, 0x20); // ASCII space
|
|
||||||
writeMemory(address + 1, 0x07); // Light grey on black
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeChar(
|
|
||||||
row: number,
|
|
||||||
col: number,
|
|
||||||
char: string,
|
|
||||||
color: number
|
|
||||||
): void {
|
|
||||||
const address = VIDEO_MEMORY_START + 2 * (row * SCREEN_WIDTH + col);
|
|
||||||
writeMemory(address, char.charCodeAt(0));
|
|
||||||
writeMemory(address + 1, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
function print(text: string, row: number, col: number, color: number): void {
|
|
||||||
for (var i = 0; i < text.length; i++) {
|
|
||||||
writeChar(row, col + i, text[i]!, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
src/os/src/index.ts
Normal file
8
src/os/src/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { kmain } from "./kernel";
|
||||||
|
import { kpanic } from "./kernel/panic";
|
||||||
|
|
||||||
|
try {
|
||||||
|
kmain();
|
||||||
|
} catch (e) {
|
||||||
|
kpanic(e instanceof Error ? e.message : String(e));
|
||||||
|
}
|
||||||
12
src/os/src/kernel/index.ts
Normal file
12
src/os/src/kernel/index.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import {
|
||||||
|
kmod_graphics_vga_clear,
|
||||||
|
kmod_graphics_vga_writeChar,
|
||||||
|
} from "./modules/graphics/vga";
|
||||||
|
|
||||||
|
export function kmain() {
|
||||||
|
kmod_graphics_vga_clear();
|
||||||
|
kmod_graphics_vga_writeChar(0, 0, "H", 0x0f);
|
||||||
|
kmod_graphics_vga_writeChar(1, 0, "i", 0x0f);
|
||||||
|
|
||||||
|
throw new Error("Simulated kernel panic");
|
||||||
|
}
|
||||||
3
src/os/src/kernel/modules/graphics/config.ts
Normal file
3
src/os/src/kernel/modules/graphics/config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export const CFG_KMOD_GRAPHICS_VGA_WIDTH = 80;
|
||||||
|
export const CFG_KMOD_GRAPHICS_VGA_HEIGHT = 25;
|
||||||
|
export const CFG_KMOD_GRAPGICS_VGA_MEM_ADDR = 0xb8000;
|
||||||
1
src/os/src/kernel/modules/graphics/graphics.kmod.ts
Normal file
1
src/os/src/kernel/modules/graphics/graphics.kmod.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./vga";
|
||||||
41
src/os/src/kernel/modules/graphics/vga.ts
Normal file
41
src/os/src/kernel/modules/graphics/vga.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { charc } from "../../../lib/libts/byte";
|
||||||
|
import {
|
||||||
|
CFG_KMOD_GRAPGICS_VGA_MEM_ADDR,
|
||||||
|
CFG_KMOD_GRAPHICS_VGA_HEIGHT,
|
||||||
|
CFG_KMOD_GRAPHICS_VGA_WIDTH,
|
||||||
|
} from "./config";
|
||||||
|
|
||||||
|
export function kmod_graphics_vga_getCharAddr(x: number, y: number): number {
|
||||||
|
return (
|
||||||
|
CFG_KMOD_GRAPGICS_VGA_MEM_ADDR + (y * CFG_KMOD_GRAPHICS_VGA_WIDTH + x) * 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_graphics_vga_getColorAddr(x: number, y: number): number {
|
||||||
|
return (
|
||||||
|
CFG_KMOD_GRAPGICS_VGA_MEM_ADDR +
|
||||||
|
(y * CFG_KMOD_GRAPHICS_VGA_WIDTH + x) * 2 +
|
||||||
|
1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_graphics_vga_clear() {
|
||||||
|
for (let y = 0; y < CFG_KMOD_GRAPHICS_VGA_HEIGHT; y++) {
|
||||||
|
for (let x = 0; x < CFG_KMOD_GRAPHICS_VGA_WIDTH; x++) {
|
||||||
|
kmod_graphics_vga_writeChar(x, y, " ", 0x07);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kmod_graphics_vga_writeChar(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
char: string,
|
||||||
|
color: number
|
||||||
|
) {
|
||||||
|
const charAddr = kmod_graphics_vga_getCharAddr(x, y);
|
||||||
|
const colorAddr = kmod_graphics_vga_getColorAddr(x, y);
|
||||||
|
|
||||||
|
$addrw(charAddr, charc(char));
|
||||||
|
$addrw(colorAddr, color);
|
||||||
|
}
|
||||||
21
src/os/src/kernel/panic.ts
Normal file
21
src/os/src/kernel/panic.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import {
|
||||||
|
kmod_graphics_vga_clear,
|
||||||
|
kmod_graphics_vga_writeChar,
|
||||||
|
} from "./modules/graphics/vga";
|
||||||
|
|
||||||
|
export function kpanic(reason?: string) {
|
||||||
|
kmod_graphics_vga_clear();
|
||||||
|
|
||||||
|
const l1 = "KERNEL PANIC!";
|
||||||
|
let l2 = "Unknown: Kernel crashed.";
|
||||||
|
|
||||||
|
if (reason) l2 = "Reason: " + reason;
|
||||||
|
|
||||||
|
for (let i = 0; i < l1.length; i++) {
|
||||||
|
kmod_graphics_vga_writeChar(i, 0, l1[i]!, 0x0c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < l2.length; i++) {
|
||||||
|
kmod_graphics_vga_writeChar(i, 1, l2[i]!, 0x0c);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/os/src/lib/libts/byte.ts
Normal file
3
src/os/src/lib/libts/byte.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function charc(char: string): number {
|
||||||
|
return char.charCodeAt(0);
|
||||||
|
}
|
||||||
1
src/os/src/types/c/bindings.d.ts
vendored
Normal file
1
src/os/src/types/c/bindings.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
declare function $addrw(address: number, value: number): void;
|
||||||
1
src/os/types/kernel/functions.d.ts
vendored
1
src/os/types/kernel/functions.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
declare function writeMemory(address: number, value: number): void;
|
|
||||||
Reference in New Issue
Block a user