Add typescript kernel loader

This commit is contained in:
2025-11-29 23:14:51 +01:00
parent b7f619b8c3
commit af5d8c709b
15 changed files with 224 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
#include "main.h" #include "main.h"
#include "efi.h" #include "efi.h"
#include "duktape.h" #include "duktape.h"
#include "embedded_js.h"
duk_context *ctx; duk_context *ctx;
EFI_SYSTEM_TABLE* systemTable; EFI_SYSTEM_TABLE* systemTable;
@@ -16,7 +17,7 @@ void ascii_to_utf16(const char *ascii, CHAR16 *utf16) {
*utf16 = 0; *utf16 = 0;
} }
duk_ret_t native_log(duk_context *ctx) { duk_ret_t native_systable_conout_output_string(duk_context *ctx) {
CHAR16 buffer[256]; CHAR16 buffer[256];
ascii_to_utf16(duk_safe_to_string(ctx, 0), buffer); ascii_to_utf16(duk_safe_to_string(ctx, 0), buffer);
systemTable->ConOut->OutputString(systemTable->ConOut, buffer); systemTable->ConOut->OutputString(systemTable->ConOut, buffer);
@@ -24,14 +25,30 @@ duk_ret_t native_log(duk_context *ctx) {
return 0; return 0;
} }
duk_ret_t native_systable_conout_clear_screen(duk_context *ctx) {
systemTable->ConOut->ClearScreen(systemTable->ConOut);
return 0;
}
duk_ret_t native_systable_conout_set_attribute(duk_context *ctx) {
systemTable->ConOut->SetAttribute(systemTable->ConOut, duk_to_uint(ctx, 0));
return 0;
}
int kernel_main(EFI_SYSTEM_TABLE *st) { int kernel_main(EFI_SYSTEM_TABLE *st) {
systemTable = st; systemTable = st;
ctx = duk_create_heap_default(); ctx = duk_create_heap_default();
duk_push_c_function(ctx, native_log, 1); duk_push_c_function(ctx, native_systable_conout_output_string, 1);
duk_put_global_string(ctx, "$log"); duk_put_global_string(ctx, "$___native_systable_conout_outputString");
duk_push_string(ctx, "var a = 1 + 2; $log(a);"); duk_push_c_function(ctx, native_systable_conout_clear_screen, 0);
duk_put_global_string(ctx, "$___native_systable_conout_clearScreen");
duk_push_c_function(ctx, native_systable_conout_set_attribute, 1);
duk_put_global_string(ctx, "$___native_systable_conout_setAttribute");
duk_push_string(ctx, EMBEDDED_JS);
duk_int_t returnCode = duk_peval(ctx); duk_int_t returnCode = duk_peval(ctx);
if (returnCode != 0) if (returnCode != 0)

34
os/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store

15
os/README.md Normal file
View File

@@ -0,0 +1,15 @@
# os
To install dependencies:
```bash
bun install
```
To run:
```bash
bun run index.ts
```
This project was created using `bun init` in bun v1.2.20. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.

25
os/bun.lock Normal file
View File

@@ -0,0 +1,25 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "os",
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"typescript": "^5",
},
},
},
"packages": {
"@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
"bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
}
}

12
os/package.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "os",
"module": "src/index.ts",
"type": "module",
"private": true,
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}

12
os/src/index.ts Normal file
View File

@@ -0,0 +1,12 @@
import { kmain } from "./kernel";
import { kpanic } from "./kernel/panic";
try {
const res = kmain();
if (res != 0) {
kpanic("Kernel returned non-zero exit code");
}
} catch (e) {
kpanic(e instanceof Error ? e.message : String(e));
}

13
os/src/kernel/index.ts Normal file
View File

@@ -0,0 +1,13 @@
import { Logger } from "../libs/logger";
import {
kmod_console_clearScreen,
kmod_console_outputString,
} from "./modules/console/console.kmod";
export function kmain() {
kmod_console_clearScreen();
Logger.log("[Kernel] Starting kernel...");
return 0;
}

View File

@@ -0,0 +1,11 @@
export function kmod_console_clearScreen() {
$___native_systable_conout_clearScreen();
}
export function kmod_console_setAttribute(attribute: number) {
$___native_systable_conout_setAttribute(attribute);
}
export function kmod_console_outputString(string: string) {
$___native_systable_conout_outputString(string);
}

12
os/src/kernel/panic.ts Normal file
View File

@@ -0,0 +1,12 @@
import {
kmod_console_clearScreen,
kmod_console_outputString,
kmod_console_setAttribute,
} from "./modules/console/console.kmod";
export function kpanic(message: string) {
kmod_console_clearScreen();
kmod_console_setAttribute(0x0c);
kmod_console_outputString("Kernel panic: \\r\\n");
kmod_console_outputString(message);
}

7
os/src/libs/logger.ts Normal file
View File

@@ -0,0 +1,7 @@
import { kmod_console_outputString } from "../kernel/modules/console/console.kmod";
export const Logger = {
log: function (message: string) {
kmod_console_outputString(message + "\\r\\n");
},
};

5
os/src/types/global_c_bindings.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
declare function $___native_systable_conout_outputString(string: string): void;
declare function $___native_systable_conout_clearScreen(): void;
declare function $___native_systable_conout_setAttribute(
attribute: number
): void;

29
os/tsconfig.json Normal file
View File

@@ -0,0 +1,29 @@
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}

View File

@@ -4,7 +4,7 @@ mkdir -p out/img/EFI/BOOT
mkdir -p out/lib mkdir -p out/lib
clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -c core/src/efi.c -o out/core/efi.o clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -c core/src/efi.c -o out/core/efi.o
clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Icore/compat -Icore/lib/duktape/src -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/src/main.c -o out/core/main.o clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Icore/compat -Icore/lib/duktape/src -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -Iout -c core/src/main.c -o out/core/main.o
clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -DDUK_F_GENERIC -U_WIN32 -UWIN32 -U_WIN64 -UWIN64 -Icore/compat -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/lib/duktape/src/duktape.c -o out/lib/duktape.o clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -DDUK_F_GENERIC -U_WIN32 -UWIN32 -U_WIN64 -UWIN64 -Icore/compat -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/lib/duktape/src/duktape.c -o out/lib/duktape.o
clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Icore/compat -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/src/compat.c -o out/core/compat.o clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -Icore/compat -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/src/compat.c -o out/core/compat.o

7
scripts/build_ts.sh Executable file
View File

@@ -0,0 +1,7 @@
# Build TypeScript to JavaScript
cd os
echo "Compiling TypeScript to JavaScript..."
bun build --outdir ../out/os --target node --bundle src/index.ts
cd ..
./scripts/process_js.js

20
scripts/process_js.js Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const fs = require("fs");
const script = fs.readFileSync("out/os/index.js", "utf-8");
const processed = script
/*.replaceAll("let ", "var ")
.replaceAll("const ", "var ")*/
.replaceAll("\n`", "\\n`")
.replaceAll("`", "'");
fs.writeFileSync(
"out/embedded_js.h",
`
#ifndef EMBEDDED_JS_H
#define EMBEDDED_JS_H
const char *EMBEDDED_JS = "${processed
.replaceAll('"', '\\"')
.replaceAll("\n", "\\n")}";
#endif`
);