Compare commits

...

10 Commits

Author SHA1 Message Date
9882280973 Merge pull request 'Switch to EFI version' (#1) from dev-efi-port into main
Reviewed-on: http://git.martinpetr.dev/marti/Lints/pulls/1
2025-12-04 19:10:34 +01:00
c289ac6f38 Add readme and license 2025-12-04 19:04:29 +01:00
868b5700cd Remove unused lib 2025-12-04 17:11:24 +01:00
092781ba57 Extend PCI driver 2025-12-03 21:31:39 +01:00
7defc557b2 Add PCI driver 2025-12-03 21:17:23 +01:00
e4b18fc8d7 Implement sysfs 2025-12-03 20:41:52 +01:00
19e034a982 Add console module 2025-12-03 20:05:06 +01:00
4b4c3022eb Change entrypoint function 2025-12-03 18:56:16 +01:00
e3dce14c64 Add TS code embedding 2025-12-03 18:32:35 +01:00
35b16bfc49 Add basic print program 2025-12-02 22:38:22 +01:00
86 changed files with 2378 additions and 122272 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
old/ old/
out/ out/
node_modules/
*.iso *.iso
*.img *.img

View File

@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View File

@@ -2,7 +2,7 @@
## What the hell is this? ## What the hell is this?
Lints is an experimental operating system kernel written almost entirely in TypeScript. This is not some in-browser system emulator or WebAssembly hack; Lints actually runs on real hardware (or a hardware emulator like QEMU) by leveraging a JavaScript engine with a small C kernel (just some basic memory management needed by the JS engine) and JS-to-C bindings for purposes like writting data to pointers, etc. Lints is an experimental operating system kernel written almost entirely in TypeScript. This is not some in-browser system emulator or WebAssembly hack; Lints actually runs on real hardware (or a virtual machine) by leveraging a JavaScript engine with a small C kernel (just some basic memory management needed by the JS engine) and JS-to-C bindings for purposes like writting data to pointers, etc.
## Why? ## Why?
@@ -16,12 +16,26 @@ Lints is an experimental operating system kernel written almost entirely in Type
Please don't. Please don't.
If you really want to, make sure you have Docker installed, then run: If you really want to, make sure you have VirtualBox and Bun installed, then run:
```bash ```bash
./scripts/run-kernel.sh bun install
``` ```
To run in VirtualBox:
```bash
st run vbox
```
To get bootable ISO:
```bash
st run build
```
The built ISO can be found in `out/` directory.
## If you are an employer looking at this... ## If you are an employer looking at this...
I would appreciate if you messaged me and gave me some well-paid job. Also... I would appreciate if you messaged me and gave me some well-paid job. Also...

17
bun.lock Normal file
View File

@@ -0,0 +1,17 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"sailet": "^0.1.1",
},
},
},
"packages": {
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
"sailet": ["sailet@0.1.1", "", { "dependencies": { "chalk": "^5.6.2" }, "peerDependencies": { "typescript": "^5" }, "bin": { "sailet": "dist/cli/index.js", "st": "dist/cli/index.js" } }, "sha512-zKcCvANgxqB2YY/XbLtgLomHJvOvcYHDg0qpZ831XxORUm45oVFNWeBItaZzxFGZDfoXNXr6VqzDuRIoukMXaA=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
}
}

View File

@@ -1,29 +0,0 @@
#ifndef COMPAT_MATH_H
#define COMPAT_MATH_H
#define HUGE_VAL (__builtin_huge_val())
#define NAN (__builtin_nan(""))
#define INFINITY (__builtin_inf())
double fabs(double x);
double floor(double x);
double ceil(double x);
double fmod(double x, double y);
double pow(double x, double y);
double sqrt(double x);
double sin(double x);
double cos(double x);
double tan(double x);
double asin(double x);
double acos(double x);
double atan(double x);
double atan2(double y, double x);
double exp(double x);
double log(double x);
double log10(double x);
double cbrt(double x);
double log2(double x);
double trunc(double x);
#endif

View File

@@ -1,9 +0,0 @@
#ifndef COMPAT_SETJMP_H
#define COMPAT_SETJMP_H
typedef void *jmp_buf[5];
#define setjmp(env) __builtin_setjmp(env)
#define longjmp(env, val) __builtin_longjmp(env, val)
#endif

View File

@@ -1,14 +0,0 @@
#ifndef COMPAT_STDARG_H
#define COMPAT_STDARG_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Base.h>
#include_next <stdarg.h>
#ifndef va_copy
#define va_copy(dest, src) VA_COPY(dest, src)
#endif
#endif

View File

@@ -1,31 +0,0 @@
#ifndef COMPAT_STDINT_H
#define COMPAT_STDINT_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Base.h>
#include_next <stdint.h>
typedef int8_t int_least8_t;
typedef uint8_t uint_least8_t;
typedef int16_t int_least16_t;
typedef uint16_t uint_least16_t;
typedef int32_t int_least32_t;
typedef uint32_t uint_least32_t;
typedef int64_t int_least64_t;
typedef uint64_t uint_least64_t;
typedef int8_t int_fast8_t;
typedef uint8_t uint_fast8_t;
typedef int16_t int_fast16_t;
typedef uint16_t uint_fast16_t;
typedef int32_t int_fast32_t;
typedef uint32_t uint_fast32_t;
typedef int64_t int_fast64_t;
typedef uint64_t uint_fast64_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
#endif

View File

@@ -1,14 +0,0 @@
#ifndef COMPAT_STDIO_H
#define COMPAT_STDIO_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Base.h>
#include_next <stdio.h>
#include <stdarg.h>
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int snprintf(char *str, size_t size, const char *format, ...);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef COMPAT_TIME_H
#define COMPAT_TIME_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Base.h>
#include_next <time.h>
double difftime(time_t time1, time_t time0);
#endif

View File

@@ -1,12 +0,0 @@
/* Dummy windows.h for Duktape compatibility in EFI */
#ifndef WINDOWS_H
#define WINDOWS_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Uefi.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,996 +0,0 @@
{
"type": "duk_source_meta",
"comment": "Metadata for prepared Duktape sources and configuration",
"git_commit": "b5d069a96ba0989c444dad8e6f002a0a057b4df0",
"git_branch": "master",
"git_describe": "v2.5.0-393-gb5d069a9",
"duk_version": 29999,
"duk_version_string": "2.99.99",
"line_map": [
{
"original_file": "duk_unicode_tables.c",
"original_line": 1,
"combined_line": 159
},
{
"original_file": "duk_internal.h",
"original_line": 1,
"combined_line": 164
},
{
"original_file": "duk_dblunion.h",
"original_line": 1,
"combined_line": 201
},
{
"original_file": "duk_fltunion.h",
"original_line": 1,
"combined_line": 621
},
{
"original_file": "duk_replacements.h",
"original_line": 1,
"combined_line": 661
},
{
"original_file": "duk_jmpbuf.h",
"original_line": 1,
"combined_line": 691
},
{
"original_file": "duk_exception.h",
"original_line": 1,
"combined_line": 716
},
{
"original_file": "duk_forwdecl.h",
"original_line": 1,
"combined_line": 748
},
{
"original_file": "duk_tval.h",
"original_line": 1,
"combined_line": 881
},
{
"original_file": "duk_builtins.h",
"original_line": 1,
"combined_line": 1582
},
{
"original_file": "duk_internal.h",
"original_line": 45,
"combined_line": 3156
},
{
"original_file": "duk_util.h",
"original_line": 1,
"combined_line": 3158
},
{
"original_file": "duk_strings.h",
"original_line": 1,
"combined_line": 3954
},
{
"original_file": "duk_js_bytecode.h",
"original_line": 1,
"combined_line": 4130
},
{
"original_file": "duk_lexer.h",
"original_line": 1,
"combined_line": 4604
},
{
"original_file": "duk_js_compiler.h",
"original_line": 1,
"combined_line": 5040
},
{
"original_file": "duk_regexp.h",
"original_line": 1,
"combined_line": 5273
},
{
"original_file": "duk_heaphdr.h",
"original_line": 1,
"combined_line": 5362
},
{
"original_file": "duk_refcount.h",
"original_line": 1,
"combined_line": 5848
},
{
"original_file": "duk_api_internal.h",
"original_line": 1,
"combined_line": 6897
},
{
"original_file": "duk_hstring.h",
"original_line": 1,
"combined_line": 7337
},
{
"original_file": "duk_hobject.h",
"original_line": 1,
"combined_line": 7536
},
{
"original_file": "duk_hcompfunc.h",
"original_line": 1,
"combined_line": 8163
},
{
"original_file": "duk_hnatfunc.h",
"original_line": 1,
"combined_line": 8423
},
{
"original_file": "duk_hboundfunc.h",
"original_line": 1,
"combined_line": 8468
},
{
"original_file": "duk_hbufobj.h",
"original_line": 1,
"combined_line": 8511
},
{
"original_file": "duk_hthread.h",
"original_line": 1,
"combined_line": 8657
},
{
"original_file": "duk_harray.h",
"original_line": 1,
"combined_line": 9075
},
{
"original_file": "duk_henv.h",
"original_line": 1,
"combined_line": 9187
},
{
"original_file": "duk_hbuffer.h",
"original_line": 1,
"combined_line": 9243
},
{
"original_file": "duk_hproxy.h",
"original_line": 1,
"combined_line": 9591
},
{
"original_file": "duk_heap.h",
"original_line": 1,
"combined_line": 9623
},
{
"original_file": "duk_debugger.h",
"original_line": 1,
"combined_line": 10385
},
{
"original_file": "duk_debug.h",
"original_line": 1,
"combined_line": 10537
},
{
"original_file": "duk_error.h",
"original_line": 1,
"combined_line": 10734
},
{
"original_file": "duk_unicode.h",
"original_line": 1,
"combined_line": 11456
},
{
"original_file": "duk_unicode_ids_noa.h",
"original_line": 1,
"combined_line": 11640
},
{
"original_file": "duk_unicode.h",
"original_line": 185,
"combined_line": 11643
},
{
"original_file": "duk_unicode_ids_noabmp.h",
"original_line": 1,
"combined_line": 11645
},
{
"original_file": "duk_unicode.h",
"original_line": 187,
"combined_line": 11648
},
{
"original_file": "duk_unicode_ids_m_let_noa.h",
"original_line": 1,
"combined_line": 11652
},
{
"original_file": "duk_unicode.h",
"original_line": 191,
"combined_line": 11655
},
{
"original_file": "duk_unicode_ids_m_let_noabmp.h",
"original_line": 1,
"combined_line": 11657
},
{
"original_file": "duk_unicode.h",
"original_line": 193,
"combined_line": 11660
},
{
"original_file": "duk_unicode_idp_m_ids_noa.h",
"original_line": 1,
"combined_line": 11664
},
{
"original_file": "duk_unicode.h",
"original_line": 197,
"combined_line": 11667
},
{
"original_file": "duk_unicode_idp_m_ids_noabmp.h",
"original_line": 1,
"combined_line": 11669
},
{
"original_file": "duk_unicode.h",
"original_line": 199,
"combined_line": 11672
},
{
"original_file": "duk_unicode_caseconv.h",
"original_line": 1,
"combined_line": 11675
},
{
"original_file": "duk_unicode.h",
"original_line": 202,
"combined_line": 11679
},
{
"original_file": "duk_unicode_re_canon_lookup.h",
"original_line": 1,
"combined_line": 11682
},
{
"original_file": "duk_unicode.h",
"original_line": 205,
"combined_line": 11685
},
{
"original_file": "duk_unicode_re_canon_bitmap.h",
"original_line": 1,
"combined_line": 11689
},
{
"original_file": "duk_unicode.h",
"original_line": 209,
"combined_line": 11695
},
{
"original_file": "duk_json.h",
"original_line": 1,
"combined_line": 11783
},
{
"original_file": "duk_js.h",
"original_line": 1,
"combined_line": 11852
},
{
"original_file": "duk_numconv.h",
"original_line": 1,
"combined_line": 11999
},
{
"original_file": "duk_bi_protos.h",
"original_line": 1,
"combined_line": 12107
},
{
"original_file": "duk_selftest.h",
"original_line": 1,
"combined_line": 12185
},
{
"original_file": "duk_prop.h",
"original_line": 1,
"combined_line": 12201
},
{
"original_file": "duk_internal.h",
"original_line": 77,
"combined_line": 12298
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 6,
"combined_line": 12300
},
{
"original_file": "duk_unicode_ids_noa.c",
"original_line": 1,
"combined_line": 12317
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 23,
"combined_line": 12369
},
{
"original_file": "duk_unicode_ids_noabmp.c",
"original_line": 1,
"combined_line": 12373
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 27,
"combined_line": 12403
},
{
"original_file": "duk_unicode_ids_m_let_noa.c",
"original_line": 1,
"combined_line": 12409
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 33,
"combined_line": 12413
},
{
"original_file": "duk_unicode_ids_m_let_noabmp.c",
"original_line": 1,
"combined_line": 12417
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 37,
"combined_line": 12421
},
{
"original_file": "duk_unicode_idp_m_ids_noa.c",
"original_line": 1,
"combined_line": 12427
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 43,
"combined_line": 12457
},
{
"original_file": "duk_unicode_idp_m_ids_noabmp.c",
"original_line": 1,
"combined_line": 12461
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 47,
"combined_line": 12480
},
{
"original_file": "duk_unicode_caseconv.c",
"original_line": 1,
"combined_line": 12490
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 57,
"combined_line": 12595
},
{
"original_file": "duk_unicode_re_canon_lookup.c",
"original_line": 1,
"combined_line": 12598
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 60,
"combined_line": 18426
},
{
"original_file": "duk_unicode_re_canon_bitmap.c",
"original_line": 1,
"combined_line": 18430
},
{
"original_file": "duk_unicode_tables.c",
"original_line": 64,
"combined_line": 18446
},
{
"original_file": "duk_replacements.c",
"original_line": 1,
"combined_line": 18447
},
{
"original_file": "duk_debug_macros.c",
"original_line": 1,
"combined_line": 18529
},
{
"original_file": "duk_builtins.c",
"original_line": 2,
"combined_line": 18621
},
{
"original_file": "duk_error_macros.c",
"original_line": 1,
"combined_line": 23804
},
{
"original_file": "duk_unicode_support.c",
"original_line": 1,
"combined_line": 24000
},
{
"original_file": "duk_util_memrw.c",
"original_line": 1,
"combined_line": 25219
},
{
"original_file": "duk_util_misc.c",
"original_line": 1,
"combined_line": 25367
},
{
"original_file": "duk_hobject_class.c",
"original_line": 1,
"combined_line": 25532
},
{
"original_file": "duk_alloc_default.c",
"original_line": 1,
"combined_line": 25661
},
{
"original_file": "duk_api_buffer.c",
"original_line": 1,
"combined_line": 25693
},
{
"original_file": "duk_api_bytecode.c",
"original_line": 1,
"combined_line": 25766
},
{
"original_file": "duk_api_call.c",
"original_line": 1,
"combined_line": 26546
},
{
"original_file": "duk_api_codec.c",
"original_line": 1,
"combined_line": 27072
},
{
"original_file": "duk_api_compile.c",
"original_line": 1,
"combined_line": 28010
},
{
"original_file": "duk_api_debug.c",
"original_line": 1,
"combined_line": 28185
},
{
"original_file": "duk_api_heap.c",
"original_line": 1,
"combined_line": 28446
},
{
"original_file": "duk_api_inspect.c",
"original_line": 1,
"combined_line": 28655
},
{
"original_file": "duk_api_memory.c",
"original_line": 1,
"combined_line": 28958
},
{
"original_file": "duk_api_object.c",
"original_line": 1,
"combined_line": 29038
},
{
"original_file": "duk_api_random.c",
"original_line": 1,
"combined_line": 30159
},
{
"original_file": "duk_api_readable.c",
"original_line": 2,
"combined_line": 30169
},
{
"original_file": "duk_api_stack.c",
"original_line": 1,
"combined_line": 30525
},
{
"original_file": "duk_api_string.c",
"original_line": 1,
"combined_line": 37426
},
{
"original_file": "duk_api_time.c",
"original_line": 1,
"combined_line": 37817
},
{
"original_file": "duk_bi_array.c",
"original_line": 1,
"combined_line": 37927
},
{
"original_file": "duk_bi_boolean.c",
"original_line": 1,
"combined_line": 39581
},
{
"original_file": "duk_bi_buffer.c",
"original_line": 1,
"combined_line": 39650
},
{
"original_file": "duk_bi_cbor.c",
"original_line": 1,
"combined_line": 42576
},
{
"original_file": "duk_bi_date.c",
"original_line": 1,
"combined_line": 44504
},
{
"original_file": "duk_bi_date_unix.c",
"original_line": 1,
"combined_line": 46402
},
{
"original_file": "duk_bi_date_windows.c",
"original_line": 1,
"combined_line": 46750
},
{
"original_file": "duk_bi_duktape.c",
"original_line": 1,
"combined_line": 46945
},
{
"original_file": "duk_bi_encoding.c",
"original_line": 1,
"combined_line": 47095
},
{
"original_file": "duk_bi_error.c",
"original_line": 1,
"combined_line": 47646
},
{
"original_file": "duk_bi_function.c",
"original_line": 1,
"combined_line": 48046
},
{
"original_file": "duk_bi_global.c",
"original_line": 1,
"combined_line": 48500
},
{
"original_file": "duk_bi_json.c",
"original_line": 1,
"combined_line": 49221
},
{
"original_file": "duk_bi_math.c",
"original_line": 1,
"combined_line": 52561
},
{
"original_file": "duk_bi_number.c",
"original_line": 1,
"combined_line": 53052
},
{
"original_file": "duk_bi_object.c",
"original_line": 1,
"combined_line": 53316
},
{
"original_file": "duk_bi_performance.c",
"original_line": 1,
"combined_line": 54033
},
{
"original_file": "duk_bi_pointer.c",
"original_line": 1,
"combined_line": 54064
},
{
"original_file": "duk_bi_promise.c",
"original_line": 1,
"combined_line": 54138
},
{
"original_file": "duk_bi_proxy.c",
"original_line": 1,
"combined_line": 54182
},
{
"original_file": "duk_bi_reflect.c",
"original_line": 1,
"combined_line": 54233
},
{
"original_file": "duk_bi_regexp.c",
"original_line": 1,
"combined_line": 54321
},
{
"original_file": "duk_bi_string.c",
"original_line": 1,
"combined_line": 54549
},
{
"original_file": "duk_bi_symbol.c",
"original_line": 1,
"combined_line": 56036
},
{
"original_file": "duk_bi_thread.c",
"original_line": 1,
"combined_line": 56208
},
{
"original_file": "duk_bi_thrower.c",
"original_line": 1,
"combined_line": 56532
},
{
"original_file": "duk_debug_fixedbuffer.c",
"original_line": 1,
"combined_line": 56541
},
{
"original_file": "duk_debug_vsnprintf.c",
"original_line": 1,
"combined_line": 56610
},
{
"original_file": "duk_debugger.c",
"original_line": 1,
"combined_line": 57855
},
{
"original_file": "duk_error_augment.c",
"original_line": 1,
"combined_line": 60927
},
{
"original_file": "duk_error_longjmp.c",
"original_line": 1,
"combined_line": 61528
},
{
"original_file": "duk_error_misc.c",
"original_line": 1,
"combined_line": 61635
},
{
"original_file": "duk_error_throw.c",
"original_line": 1,
"combined_line": 61813
},
{
"original_file": "duk_hbuffer_alloc.c",
"original_line": 1,
"combined_line": 61972
},
{
"original_file": "duk_hbuffer_assert.c",
"original_line": 1,
"combined_line": 62106
},
{
"original_file": "duk_hbuffer_ops.c",
"original_line": 1,
"combined_line": 62119
},
{
"original_file": "duk_hbufobj_misc.c",
"original_line": 2,
"combined_line": 62197
},
{
"original_file": "duk_heap_alloc.c",
"original_line": 1,
"combined_line": 62319
},
{
"original_file": "duk_heap_finalize.c",
"original_line": 1,
"combined_line": 63595
},
{
"original_file": "duk_heap_hashstring.c",
"original_line": 1,
"combined_line": 64044
},
{
"original_file": "duk_heap_markandsweep.c",
"original_line": 1,
"combined_line": 64165
},
{
"original_file": "duk_heap_memory.c",
"original_line": 1,
"combined_line": 65771
},
{
"original_file": "duk_heap_misc.c",
"original_line": 1,
"combined_line": 66205
},
{
"original_file": "duk_heap_refcount.c",
"original_line": 1,
"combined_line": 66392
},
{
"original_file": "duk_heap_stringcache.c",
"original_line": 1,
"combined_line": 67364
},
{
"original_file": "duk_heap_stringtable.c",
"original_line": 1,
"combined_line": 67865
},
{
"original_file": "duk_heaphdr_assert.c",
"original_line": 1,
"combined_line": 69108
},
{
"original_file": "duk_hobject_alloc.c",
"original_line": 1,
"combined_line": 69199
},
{
"original_file": "duk_hobject_array.c",
"original_line": 2,
"combined_line": 69479
},
{
"original_file": "duk_hobject_assert.c",
"original_line": 1,
"combined_line": 69758
},
{
"original_file": "duk_hobject_lookup.c",
"original_line": 2,
"combined_line": 69998
},
{
"original_file": "duk_hobject_misc.c",
"original_line": 1,
"combined_line": 70556
},
{
"original_file": "duk_hobject_pc2line.c",
"original_line": 1,
"combined_line": 71019
},
{
"original_file": "duk_hobject_props.c",
"original_line": 1,
"combined_line": 71265
},
{
"original_file": "duk_hobject_proxy.c",
"original_line": 2,
"combined_line": 71721
},
{
"original_file": "duk_hobject_resize.c",
"original_line": 2,
"combined_line": 71885
},
{
"original_file": "duk_hstring_assert.c",
"original_line": 1,
"combined_line": 73228
},
{
"original_file": "duk_hstring_misc.c",
"original_line": 1,
"combined_line": 73250
},
{
"original_file": "duk_hthread_alloc.c",
"original_line": 1,
"combined_line": 73479
},
{
"original_file": "duk_hthread_builtins.c",
"original_line": 1,
"combined_line": 73538
},
{
"original_file": "duk_hthread_misc.c",
"original_line": 1,
"combined_line": 74438
},
{
"original_file": "duk_hthread_stacks.c",
"original_line": 1,
"combined_line": 74535
},
{
"original_file": "duk_js_arith.c",
"original_line": 1,
"combined_line": 74898
},
{
"original_file": "duk_js_call.c",
"original_line": 1,
"combined_line": 75039
},
{
"original_file": "duk_js_compiler.c",
"original_line": 1,
"combined_line": 77862
},
{
"original_file": "duk_js_executor.c",
"original_line": 1,
"combined_line": 86010
},
{
"original_file": "duk_js_ops.c",
"original_line": 1,
"combined_line": 91409
},
{
"original_file": "duk_js_prop.c",
"original_line": 2,
"combined_line": 92848
},
{
"original_file": "duk_js_var.c",
"original_line": 1,
"combined_line": 93095
},
{
"original_file": "duk_lexer.c",
"original_line": 1,
"combined_line": 94829
},
{
"original_file": "duk_numconv.c",
"original_line": 1,
"combined_line": 97281
},
{
"original_file": "duk_prop_defown.c",
"original_line": 1,
"combined_line": 99623
},
{
"original_file": "duk_prop_delete.c",
"original_line": 1,
"combined_line": 101144
},
{
"original_file": "duk_prop_enum.c",
"original_line": 1,
"combined_line": 102280
},
{
"original_file": "duk_prop_get.c",
"original_line": 1,
"combined_line": 102538
},
{
"original_file": "duk_prop_getown.c",
"original_line": 1,
"combined_line": 104476
},
{
"original_file": "duk_prop_has.c",
"original_line": 1,
"combined_line": 105079
},
{
"original_file": "duk_prop_ownpropkeys.c",
"original_line": 1,
"combined_line": 105712
},
{
"original_file": "duk_prop_set.c",
"original_line": 1,
"combined_line": 106347
},
{
"original_file": "duk_prop_util.c",
"original_line": 1,
"combined_line": 109579
},
{
"original_file": "duk_regexp_compiler.c",
"original_line": 1,
"combined_line": 109893
},
{
"original_file": "duk_regexp_executor.c",
"original_line": 1,
"combined_line": 111194
},
{
"original_file": "duk_selftest.c",
"original_line": 1,
"combined_line": 112187
},
{
"original_file": "duk_tval.c",
"original_line": 2,
"combined_line": 112934
},
{
"original_file": "duk_unicode_wtf8.c",
"original_line": 1,
"combined_line": 113085
},
{
"original_file": "duk_util_bitdecoder.c",
"original_line": 1,
"combined_line": 114166
},
{
"original_file": "duk_util_bitencoder.c",
"original_line": 1,
"combined_line": 114330
},
{
"original_file": "duk_util_bufwriter.c",
"original_line": 1,
"combined_line": 114373
},
{
"original_file": "duk_util_cast.c",
"original_line": 1,
"combined_line": 114659
},
{
"original_file": "duk_util_double.c",
"original_line": 1,
"combined_line": 114831
},
{
"original_file": "duk_util_hashbytes.c",
"original_line": 1,
"combined_line": 115174
},
{
"original_file": "duk_util_memory.c",
"original_line": 1,
"combined_line": 115236
},
{
"original_file": "duk_util_tinyrandom.c",
"original_line": 1,
"combined_line": 115272
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,392 +0,0 @@
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
// EDK2 CRT Support Header
#include <CrtLibSupport.h>
// Global variables required by CrtLibSupport.h
int errno = 0;
FILE *stderr = NULL;
// Better malloc/free with size tracking
typedef struct {
size_t size;
char data[];
} AllocHeader;
void *my_malloc(size_t size) {
AllocHeader *hdr;
if (gBS->AllocatePool(EfiLoaderData, size + sizeof(AllocHeader), (void**)&hdr) != EFI_SUCCESS) {
return NULL;
}
hdr->size = size;
return hdr->data;
}
void my_free(void *ptr) {
if (ptr) {
AllocHeader *hdr = (AllocHeader*)((char*)ptr - sizeof(AllocHeader));
gBS->FreePool(hdr);
}
}
void *my_realloc(void *ptr, size_t size) {
if (!ptr) return my_malloc(size);
if (size == 0) {
my_free(ptr);
return NULL;
}
AllocHeader *old_hdr = (AllocHeader*)((char*)ptr - sizeof(AllocHeader));
size_t old_size = old_hdr->size;
void *new_ptr = my_malloc(size);
if (!new_ptr) return NULL;
CopyMem(new_ptr, ptr, old_size < size ? old_size : size);
my_free(ptr);
return new_ptr;
}
// Redirect standard malloc/free/realloc to our versions
#undef malloc
#undef free
#undef realloc
void *malloc(size_t size) { return my_malloc(size); }
void free(void *ptr) { my_free(ptr); }
void *realloc(void *ptr, size_t size) { return my_realloc(ptr, size); }
void *calloc(size_t nmemb, size_t size) {
size_t total = nmemb * size;
void *ptr = malloc(total);
if (ptr) {
SetMem(ptr, total, 0);
}
return ptr;
}
// IO
int printf(const char *format, ...) {
return 0;
}
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {
return (int)AsciiVSPrint(str, size, format, ap);
}
int snprintf(char *str, size_t size, const char *format, ...) {
VA_LIST Marker;
VA_START(Marker, format);
UINTN Return = AsciiVSPrint(str, size, format, Marker);
VA_END(Marker);
return (int)Return;
}
// sprintf is a macro in CrtLibSupport.h, so we don't define it.
// Math functions
// Duktape needs math functions for proper numeric conversions and bitwise operations.
// EDK2 doesn't provide a standard math library, so we implement basic versions here.
double fabs(double x) {
return x < 0.0 ? -x : x;
}
double floor(double x) {
if (x >= 0.0) {
return (double)(INT64)x;
} else {
INT64 i = (INT64)x;
return (double)((x == (double)i) ? i : i - 1);
}
}
double ceil(double x) {
if (x >= 0.0) {
INT64 i = (INT64)x;
return (double)((x == (double)i) ? i : i + 1);
} else {
return (double)(INT64)x;
}
}
double trunc(double x) {
return (double)(INT64)x;
}
double fmod(double x, double y) {
if (y == 0.0) return 0.0;
INT64 quotient = (INT64)(x / y);
return x - quotient * y;
}
// Newton-Raphson square root implementation
double sqrt(double x) {
if (x < 0.0) return 0.0; // Return 0 for negative (should be NaN)
if (x == 0.0) return 0.0;
double guess = x;
double epsilon = 0.00001;
// Newton-Raphson: x_new = (x_old + n/x_old) / 2
for (int i = 0; i < 50; i++) {
double next = (guess + x / guess) / 2.0;
if (fabs(next - guess) < epsilon) break;
guess = next;
}
return guess;
}
// Power function using binary exponentiation for integer exponents
double pow(double base, double exponent) {
// Handle special cases
if (exponent == 0.0) return 1.0;
if (base == 0.0) return 0.0;
if (base == 1.0) return 1.0;
if (exponent == 1.0) return base;
// Check if exponent is an integer
INT64 exp_int = (INT64)exponent;
if ((double)exp_int == exponent) {
// Integer exponent - use binary exponentiation
double result = 1.0;
double current = base;
UINT64 n = (exp_int < 0) ? -exp_int : exp_int;
while (n > 0) {
if (n & 1) result *= current;
current *= current;
n >>= 1;
}
return (exp_int < 0) ? (1.0 / result) : result;
}
// For non-integer exponents, return 0 (would need exp/log)
return 0.0;
}
// Trigonometric functions - stubs (not needed for bitwise ops)
double sin(double x) { return 0.0; }
double cos(double x) { return 0.0; }
double tan(double x) { return 0.0; }
double asin(double x) { return 0.0; }
double acos(double x) { return 0.0; }
double atan(double x) { return 0.0; }
double atan2(double y, double x) { return 0.0; }
double exp(double x) { return 0.0; }
double log(double x) { return 0.0; }
double log10(double x) { return 0.0; }
double cbrt(double x) { return 0.0; }
double log2(double x) { return 0.0; }
// Other
void abort(void) {
// CpuDeadLoop();
while(1);
}
void exit(int status) {
// CpuDeadLoop();
while(1);
}
// Global gBS
EFI_BOOT_SERVICES *gBS = NULL;
int _fltused = 0;
// Stack probe (needed for MSVC ABI)
void __chkstk(void) { return; }
// Memory functions
#undef memset
#undef memcpy
#undef memcmp
void *memset(void *s, int c, size_t n) {
unsigned char *p = s;
while (n--) {
*p++ = (unsigned char)c;
}
return s;
}
void *memcpy(void *dest, const void *src, size_t n) {
char *d = dest;
const char *s = src;
while (n--) {
*d++ = *s++;
}
return dest;
}
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
while (n--) {
if (*p1 != *p2) {
return *p1 - *p2;
}
p1++;
p2++;
}
return 0;
}
void *SetMem(void *Buffer, UINTN Length, UINT8 Value) {
return memset(Buffer, Value, Length);
}
void *CopyMem(void *Destination, const void *Source, UINTN Length) {
return memcpy(Destination, Source, Length);
}
INTN CompareMem(const void *Destination, const void *Source, UINTN Length) {
return (INTN)memcmp(Destination, Source, Length);
}
// String functions
UINTN AsciiStrnLenS(const CHAR8 *String, UINTN MaxSize) {
UINTN len = 0;
while (len < MaxSize && String[len] != 0) {
len++;
}
return len;
}
INTN AsciiStrnCmp(const CHAR8 *FirstString, const CHAR8 *SecondString, UINTN Length) {
if (Length == 0) return 0;
while (Length > 0 && *FirstString && *SecondString) {
if (*FirstString != *SecondString) break;
FirstString++;
SecondString++;
Length--;
}
if (Length == 0) return 0;
return *FirstString - *SecondString;
}
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
}
// Print functions
// Minimal vsnprintf implementation
#include <stdarg.h>
static void simple_append(char **str, size_t *size, char c) {
if (*size > 1) {
**str = c;
(*str)++;
(*size)--;
}
}
static void simple_append_str(char **str, size_t *size, const char *s) {
while (*s) {
simple_append(str, size, *s++);
}
}
static void simple_append_hex(char **str, size_t *size, UINT64 num) {
char buf[17];
const char *digits = "0123456789ABCDEF";
int i = 0;
if (num == 0) {
simple_append(str, size, '0');
return;
}
while (num > 0) {
buf[i++] = digits[num % 16];
num /= 16;
}
while (i > 0) {
simple_append(str, size, buf[--i]);
}
}
static void simple_append_dec(char **str, size_t *size, INT64 num) {
char buf[21];
int i = 0;
int neg = 0;
if (num < 0) {
neg = 1;
num = -num;
}
if (num == 0) {
simple_append(str, size, '0');
return;
}
while (num > 0) {
buf[i++] = (num % 10) + '0';
num /= 10;
}
if (neg) simple_append(str, size, '-');
while (i > 0) {
simple_append(str, size, buf[--i]);
}
}
UINTN AsciiVSPrint(CHAR8 *StartOfBuffer, UINTN BufferSize, CONST CHAR8 *FormatString, VA_LIST Marker) {
char *str = StartOfBuffer;
size_t size = BufferSize;
const char *fmt = FormatString;
while (*fmt) {
if (*fmt == '%') {
fmt++;
if (*fmt == 's') {
char *s = VA_ARG(Marker, char*);
simple_append_str(&str, &size, s ? s : "(null)");
} else if (*fmt == 'd') {
int d = VA_ARG(Marker, int);
simple_append_dec(&str, &size, d);
} else if (*fmt == 'x' || *fmt == 'X') {
unsigned int x = VA_ARG(Marker, unsigned int);
simple_append_hex(&str, &size, x);
} else if (*fmt == 'p') {
void *p = VA_ARG(Marker, void*);
simple_append_hex(&str, &size, (UINT64)p);
} else if (*fmt == '%') {
simple_append(&str, &size, '%');
} else {
simple_append(&str, &size, '%');
simple_append(&str, &size, *fmt);
}
} else {
simple_append(&str, &size, *fmt);
}
fmt++;
}
*str = 0;
return (UINTN)(str - StartOfBuffer);
}
UINTN AsciiSPrint(CHAR8 *StartOfBuffer, UINTN BufferSize, CONST CHAR8 *FormatString, ...) {
VA_LIST Marker;
VA_START(Marker, FormatString);
UINTN ret = AsciiVSPrint(StartOfBuffer, BufferSize, FormatString, Marker);
VA_END(Marker);
return ret;
}
// Time functions
struct tm *gmtime(const time_t *timep) { return NULL; }
time_t mktime(struct tm *tm) { return 0; }
int sscanf(const char *str, const char *format, ...) { return 0; }
time_t time(time_t *tloc) { return 0; }
double difftime(time_t time1, time_t time0) { return (double)(time1 - time0); }
// Needed for CrtLibSupport headers to work?
// They use VA_LIST etc which are in Base.h

View File

@@ -1,12 +0,0 @@
#include "efi.h"
#include "main.h"
extern EFI_BOOT_SERVICES *gBS;
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
gBS = SystemTable->BootServices;
// Initialize standard library (if needed)
// ...
return kernel_main(SystemTable);
}

View File

@@ -1,13 +0,0 @@
#ifndef EFI_H
#define EFI_H
#ifndef MDE_CPU_X64
#define MDE_CPU_X64
#endif
#include <Uefi.h>
// Map legacy names if needed, or update main.c
typedef EFI_SYSTEM_TABLE EfiSystemTable;
#endif

View File

@@ -1,147 +0,0 @@
#include "main.h"
#include "efi.h"
#include "efi.h"
#include <Protocol/CpuIo2.h>
#include <Protocol/PciRootBridgeIo.h>
#include "duktape.h"
#include "embedded_js.h"
duk_context *ctx;
EFI_SYSTEM_TABLE* systemTable;
void halt() {
for (;;) {}
}
void ascii_to_utf16(const char *ascii, CHAR16 *utf16) {
while (*ascii) {
*utf16++ = (CHAR16)*ascii++;
}
*utf16 = 0;
}
duk_ret_t native_systable_conout_output_string(duk_context *ctx) {
CHAR16 buffer[256];
ascii_to_utf16(duk_safe_to_string(ctx, 0), buffer);
systemTable->ConOut->OutputString(systemTable->ConOut, buffer);
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;
}
duk_ret_t native_systable_io_dword_in(duk_context *ctx) {
EFI_CPU_IO2_PROTOCOL* cpuIo;
EFI_GUID cpuIoGuid = EFI_CPU_IO2_PROTOCOL_GUID;
systemTable->BootServices->LocateProtocol(&cpuIoGuid, NULL, (void**)&cpuIo);
UINT32 data;
cpuIo->Io.Read(cpuIo, EfiCpuIoWidthUint32, duk_to_uint(ctx, 0), 1, &data);
duk_push_uint(ctx, data);
return 1;
}
duk_ret_t native_systable_io_dword_out(duk_context *ctx) {
EFI_CPU_IO2_PROTOCOL* cpuIo;
EFI_GUID cpuIoGuid = EFI_CPU_IO2_PROTOCOL_GUID;
systemTable->BootServices->LocateProtocol(&cpuIoGuid, NULL, (void**)&cpuIo);
UINT32 data = duk_to_uint(ctx, 1);
cpuIo->Io.Write(cpuIo, EfiCpuIoWidthUint32, duk_to_uint(ctx, 0), 1, &data);
return 0;
}
duk_ret_t native_systable_pci_read_config(duk_context *ctx) {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL* pci;
EFI_GUID pciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
systemTable->BootServices->LocateProtocol(&pciGuid, NULL, (void**)&pci);
UINT64 bus = duk_to_uint(ctx, 0);
UINT64 device = duk_to_uint(ctx, 1);
UINT64 func = duk_to_uint(ctx, 2);
UINT64 offset = duk_to_uint(ctx, 3);
UINT64 address = (bus << 24) | (device << 16) | (func << 8) | (offset & 0xff);
UINT32 data = 0;
pci->Pci.Read(pci, EfiPciWidthUint32, address, 1, &data);
duk_push_uint(ctx, data);
return 1;
}
duk_ret_t native_systable_pci_write_config(duk_context *ctx) {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL* pci;
EFI_GUID pciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
systemTable->BootServices->LocateProtocol(&pciGuid, NULL, (void**)&pci);
UINT64 bus = duk_to_uint(ctx, 0);
UINT64 device = duk_to_uint(ctx, 1);
UINT64 func = duk_to_uint(ctx, 2);
UINT64 offset = duk_to_uint(ctx, 3);
UINT64 address = (bus << 24) | (device << 16) | (func << 8) | (offset & 0xff);
UINT32 data = duk_to_uint(ctx, 4);
pci->Pci.Write(pci, EfiPciWidthUint32, address, 1, &data);
return 0;
}
int kernel_main(EFI_SYSTEM_TABLE *st) {
systemTable = st;
systemTable->ConOut->ClearScreen(systemTable->ConOut);
systemTable->ConOut->OutputString(systemTable->ConOut, L"START\r\n");
ctx = duk_create_heap_default();
duk_push_c_function(ctx, native_systable_conout_output_string, 1);
duk_put_global_string(ctx, "$___native_systable_conout_outputString");
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_c_function(ctx, native_systable_io_dword_in, 1);
duk_put_global_string(ctx, "$___native_systable_io_dword_in");
duk_push_c_function(ctx, native_systable_io_dword_out, 2);
duk_put_global_string(ctx, "$___native_systable_io_dword_out");
duk_push_c_function(ctx, native_systable_pci_read_config, 4);
duk_put_global_string(ctx, "$___native_systable_pci_read_config");
duk_push_c_function(ctx, native_systable_pci_write_config, 5);
duk_put_global_string(ctx, "$___native_systable_pci_write_config");
systemTable->ConOut->OutputString(systemTable->ConOut, L"RUN\r\n");
duk_push_string(ctx, EMBEDDED_JS);
duk_int_t returnCode = duk_peval(ctx);
/*if (returnCode != 0)
{
duk_safe_to_stacktrace(ctx, -1);
CHAR16 buffer[256];
ascii_to_utf16(duk_safe_to_string(ctx, -1), buffer);
systemTable->ConOut->OutputString(systemTable->ConOut, buffer);
}
duk_pop(ctx);*/
systemTable->ConOut->OutputString(systemTable->ConOut, L"!!! KERNEL EXITED UNEXPECTEDLY !!!\r\n");
halt();
return 0;
}

View File

@@ -1,8 +0,0 @@
#include "efi.h"
#ifndef MAIN_H
#define MAIN_H
int kernel_main(EFI_SYSTEM_TABLE* systemTable);
#endif

1
edk2

Submodule edk2 deleted from aacfbe667e

View File

@@ -1,12 +0,0 @@
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));
}

View File

@@ -1,126 +0,0 @@
import { Logger } from "../../../libs/logger";
import { Path } from "../../../libs/path";
import { sysfs, sysfs_mkdir, sysfs_writeFile } from "../../filesystem/sysfs";
export function kdriver_dev_pci_init() {
sysfs_mkdir("/pci");
}
export function kdriver_dev_pci_detectDevices() {
Logger.log("[PCI] Scanning...");
for (let bus = 0; bus < 256; bus++) {
for (let device = 0; device < 32; device++) {
kdriver_dev_pci_checkDevice(bus, device, 0);
const headerType = kdriver_dev_pci_getHeaderType(bus, device, 0);
if ((headerType & 0x80) !== 0) {
for (let func = 1; func < 8; func++) {
kdriver_dev_pci_checkDevice(bus, device, func);
}
}
}
}
}
export function kdriver_dev_pci_checkDevice(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 0);
if (data === 0 || data === -1) return;
const vendorId = data & 0xffff;
const deviceId = data >>> 16;
if (vendorId === 0 || vendorId === 0xffff) return;
const classCode = kdriver_dev_pci_getClassCode(bus, device, func);
const subclass = kdriver_dev_pci_getSubclass(bus, device, func);
const filename = bus + ":" + device + ":" + func;
Logger.log(
"[PCI] Found device pci:" +
filename +
" (vendor:" +
vendorId.toString(16) +
", device:" +
deviceId.toString(16) +
", class:" +
classCode.toString(16) +
", subclass:" +
subclass.toString(16) +
")"
);
const dirname = Path.join("/pci", filename);
sysfs_mkdir(dirname);
sysfs_writeFile(Path.join(dirname, "vendor"), "Intel");
/*sysfs_writeFile(Path.join(dirname, "vendor"), vendorId.toString(16));
sysfs_writeFile(Path.join(dirname, "device"), deviceId.toString(16));
sysfs_writeFile(Path.join(dirname, "class"), classCode.toString(16));
sysfs_writeFile(Path.join(dirname, "subclass"), subclass.toString(16));*/
}
export function kdriver_dev_pci_getDeviceId(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 0);
return data >>> 16;
}
export function kdriver_dev_pci_getVendorId(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 0);
return data & 0xffff;
}
export function kdriver_dev_pci_getClassCode(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 8);
return (data >> 24) & 0xff;
}
export function kdriver_dev_pci_getSubclass(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 8);
return (data >> 16) & 0xff;
}
export function kdriver_dev_pci_getHeaderType(
bus: number,
device: number,
func: number
) {
const data = kdriver_dev_pci_readConfigDword(bus, device, func, 12);
return (data >> 16) & 0xff;
}
export function kdriver_dev_pci_readConfigDword(
bus: number,
device: number,
func: number,
offset: number
) {
return $___native_systable_pci_read_config(bus, device, func, offset);
}

View File

@@ -1,106 +0,0 @@
import { Logger } from "../../libs/logger";
import { Path } from "../../libs/path";
import {
FilesystemType,
type Filesystem,
type FilesystemEntity,
} from "../../types/kernel/filesystem";
const sysfs_data: FilesystemEntity[] = [];
export function sysfs(): Filesystem {
return {
type: FilesystemType.SYSFS,
mkdir: sysfs_mkdir,
ls: sysfs_ls,
writeFile(path, content) {
throw new Error("Cannot write to sysfs");
},
};
}
export function sysfs_root(): FilesystemEntity {
/*return {
name: "$root",
path: "/",
size: 0,
isDirectory: true,
contents: null,
};*/
}
export function sysfs_get(path: string): FilesystemEntity | null {
if (path == "" || path == "/") return sysfs_root();
for (let i = 0; i < sysfs_data.length; i++) {
Logger.log(sysfs_data[i]);
if (sysfs_data[i]!.path === path) {
return sysfs_data[i]!;
}
}
return null;
}
export function sysfs_mkdir(path: string) {
if (sysfs_get(path)) return;
const parent = sysfs_get(Path.dirname(path));
if (!parent || !parent.isDirectory) return;
Logger.log(path);
/*sysfs_data.push({
name: Path.filename(path),
path: path,
size: 0,
isDirectory: true,
contents: 0,
});*/
}
export function sysfs_ls(path: string): FilesystemEntity[] | null {
/*const entity = sysfs_get(path);
if (!entity || !entity.isDirectory) return null;
const result: FilesystemEntity[] = [];
const prefix = path + "/";
for (let i = 0; i < globalThis.sysfs_data.length; i++) {
const itemPath = globalThis.sysfs_data[i]!.path;
// Only include direct children (no additional slashes after the prefix)
if (
itemPath.startsWith(prefix) &&
!itemPath.substring(prefix.length).includes("/")
) {
result.push(globalThis.sysfs_data[i]!);
}
}
return result;*/
}
export function sysfs_createFile(path: string, content: string) {
if (sysfs_get(path)) return;
/*const parent = sysfs_getParent(path);
if (!parent || !parent.isDirectory) return;
globalThis.sysfs_data.push({
name: Path.filename(path),
path: path,
size: content.length,
isDirectory: false,
contents: content,
});*/
}
export function sysfs_writeFile(path: string, content: string) {
const entity = sysfs_get(path);
/*if (!entity) return sysfs_createFile(path, content);
if (entity.isDirectory) return;
entity.contents = content;*/
}

View File

@@ -1,26 +0,0 @@
import { Logger } from "../libs/logger";
import { kdriver_dev_pci_detectDevices } from "./drivers/dev/pci.kdriver";
import { sysfs_ls } from "./filesystem/sysfs";
import {
kmod_console_clearScreen,
kmod_console_outputString,
} from "./modules/console/console.kmod";
import { kmod_drivers_init } from "./modules/drivers.kmod";
export function kmain() {
kmod_console_clearScreen();
Logger.log("[Kernel] Starting kernel...");
kmod_drivers_init();
kdriver_dev_pci_detectDevices();
/*const files = sysfs_ls("/");
files!.forEach(function (file) {
Logger.log(file.name);
});*/
return 0;
}

View File

@@ -1,11 +0,0 @@
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);
}

View File

@@ -1,12 +0,0 @@
import { Logger } from "../../libs/logger";
import { kdriver_dev_pci_init } from "../drivers/dev/pci.kdriver";
const drivers = [kdriver_dev_pci_init];
export function kmod_drivers_init() {
Logger.log("[Kernel] Initializing drivers...");
for (let i = 0; i < drivers.length; i++) {
drivers[i]!();
}
}

View File

@@ -1,12 +0,0 @@
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);
}

View File

@@ -1,7 +0,0 @@
export function dwordin(port: number): number {
return $___native_systable_io_dwordin(port);
}
export function dwordout(port: number, value: number) {
$___native_systable_io_dwordout(port, value);
}

View File

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

View File

@@ -1,12 +0,0 @@
export const Path = {
join(p1: string, p2: string): string {
if (p1.endsWith("/")) return p1 + p2;
else return p1 + "/" + p2;
},
filename(path: string): string {
return path.split("/").pop()!;
},
dirname(path: string): string {
return path.split("/").slice(0, -1).join("/");
},
};

View File

@@ -1,26 +0,0 @@
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;
declare function $___native_systable_io_dwordin(port: number): number;
declare function $___native_systable_io_dwordout(
port: number,
value: number
): void;
declare function $___native_systable_pci_read_config(
bus: number,
device: number,
func: number,
offset: number
): number;
declare function $___native_systable_pci_write_config(
bus: number,
device: number,
func: number,
offset: number,
value: number
): void;

View File

@@ -1,18 +0,0 @@
export enum FilesystemType {
SYSFS,
}
export interface Filesystem {
type: FilesystemType;
mkdir(path: string): void;
ls(path: string): FilesystemEntity[] | null;
writeFile(path: string, content: string): void;
}
export type FilesystemEntity = {
name: string;
path: string;
size: number;
isDirectory: boolean;
contents: string | number | number[] | null;
};

5
package.json Normal file
View File

@@ -0,0 +1,5 @@
{
"dependencies": {
"sailet": "^0.1.1"
}
}

18
sailet.config.ts Normal file
View File

@@ -0,0 +1,18 @@
// sailet.config.ts
import { script, step, cmd, $ } from "sailet";
script("build", () => [
step("Prepare", () => [cmd($`./src/scripts/prepare_build.sh`)]),
step("Build EFI", () => [
cmd($`./src/scripts/build_system.sh`),
cmd($`./src/scripts/embed_system.sh`),
cmd($`./src/scripts/build_core.sh`),
]),
step("Build ISO", () => [cmd($`./src/scripts/build_iso.sh`)]),
]);
script("vbox", () => [
step("Build", () => [cmd($`st run build`)]),
step("Run", () => [cmd($`./src/scripts/run_vbox.sh`)]),
]);

View File

@@ -1,11 +0,0 @@
mkdir -p out
mkdir -p out/core
mkdir -p out/img/EFI/BOOT
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 -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 -Icore/compat -Iedk2/MdePkg/Include -Iedk2/MdePkg/Include/X64 -Iedk2/CryptoPkg/Library/Include -c core/src/compat.c -o out/core/compat.o
lld-link -filealign:16 -subsystem:efi_application -nodefaultlib -dll -entry:efi_main out/core/main.o out/core/efi.o out/lib/duktape.o out/core/compat.o -out:out/img/EFI/BOOT/BOOTX64.EFI

View File

@@ -1,7 +0,0 @@
# 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

View File

@@ -1,20 +0,0 @@
#!/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`
);

View File

@@ -1 +0,0 @@
./scripts/build_ts.sh && ./scripts/build_c.sh && ./scripts/out_to_iso.sh && ./scripts/run_vbox.sh

View File

@@ -1,22 +0,0 @@
#!/bin/bash
VM_NAME="LintsEFI"
ISO_PATH="$(pwd)/out/lints.iso"
# Check if VM exists
if VBoxManage list vms | grep -q "\"$VM_NAME\""; then
echo "VM '$VM_NAME' already exists."
else
echo "Creating VM '$VM_NAME'..."
VBoxManage createvm --name "$VM_NAME" --ostype "Other_64" --register
VBoxManage modifyvm "$VM_NAME" --memory 128 --firmware efi --graphicscontroller vmsvga
VBoxManage storagectl "$VM_NAME" --name "IDE Controller" --add ide
fi
# Attach ISO (force unmount first just in case)
echo "Attaching ISO..."
VBoxManage storageattach "$VM_NAME" --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium emptydrive --forceunmount
VBoxManage storageattach "$VM_NAME" --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium "$ISO_PATH"
# Start VM
echo "Starting VM..."
VBoxManage startvm "$VM_NAME"

9
src/core/compat/assert.h Normal file
View File

@@ -0,0 +1,9 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#define assert(x) ((void)0)
#define NDEBUG 1

0
src/core/compat/ctype.h Normal file
View File

0
src/core/compat/fenv.h Normal file
View File

View File

@@ -0,0 +1,27 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"
#define PRIX64 "llX"
#define PRId32 "d"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIdPTR "ld"
#define PRIuPTR "lu"
#define PRIxPTR "lx"
#define PRIXPTR "lX"
#endif

195
src/core/compat/main.c Normal file
View File

@@ -0,0 +1,195 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#define NULL ((void*)0)
// EFI definitions
typedef uint64_t EFI_STATUS;
typedef void* EFI_HANDLE;
#define EFI_SUCCESS 0
typedef struct {
uint64_t signature;
uint32_t revision;
uint32_t headerSize;
uint32_t crc32;
uint32_t reserved;
} EFI_TABLE_HEADER;
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef EFI_STATUS (*EFI_TEXT_STRING)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
uint16_t *String
);
typedef EFI_STATUS (*EFI_TEXT_CLEAR_SCREEN)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
);
typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
void *reset;
EFI_TEXT_STRING OutputString;
void *testString;
void *queryMode;
void *setMode;
void *setAttribute;
EFI_TEXT_CLEAR_SCREEN ClearScreen;
void *setCursorPosition;
void *enableCursor;
void *mode;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef struct EFI_SYSTEM_TABLE {
EFI_TABLE_HEADER hdr;
uint16_t *firmwareVendor;
uint32_t firmwareRevision;
void *consoleInHandle;
void *conIn;
void *consoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
void *standardErrorHandle;
void *stdErr;
void *runtimeServices;
void *bootServices;
uint64_t numberOfTableEntries;
void *configurationTable;
} EFI_SYSTEM_TABLE;
static EFI_SYSTEM_TABLE *gST = NULL;
static void Print(uint16_t *str) {
if (gST && gST->ConOut)
gST->ConOut->OutputString(gST->ConOut, str);
}
static uint16_t *AsciiToUnicode(const char *ascii) {
static uint16_t buffer[1024];
int i;
for (i = 0; ascii[i] && i < 1023; i++) {
buffer[i] = (uint16_t)ascii[i];
}
buffer[i] = 0;
return buffer;
}
// stdio implementation
int printf(const char *format, ...) {
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
Print(AsciiToUnicode(buf));
return ret;
}
int fprintf(FILE *stream, const char *format, ...) {
if (stream != stdout && stream != stderr) return 0;
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
Print(AsciiToUnicode(buf));
return ret;
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
if (stream != stdout && stream != stderr) return 0;
const char *p = ptr;
size_t total = size * nmemb;
char buf[1025];
size_t i = 0;
while (i < total) {
size_t chunk = total - i;
if (chunk > 1024) chunk = 1024;
memcpy(buf, p + i, chunk);
buf[chunk] = 0;
Print(AsciiToUnicode(buf));
i += chunk;
}
return nmemb;
}
int fputc(int c, FILE *stream) {
if (stream != stdout && stream != stderr) return c;
char buf[2] = { (char)c, 0 };
Print(AsciiToUnicode(buf));
return c;
}
int putchar(int c) {
return fputc(c, stdout);
}
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
(void)ImageHandle;
gST = SystemTable;
gST->ConOut->ClearScreen(gST->ConOut);
Print(L"UEFI QuickJS\r\n");
Print(L"============\r\n\r\n");
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
Print(L"Failed to create runtime\r\n");
return EFI_SUCCESS;
}
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
Print(L"Failed to create context\r\n");
JS_FreeRuntime(rt);
return EFI_SUCCESS;
}
Print(L"QuickJS initialized!\r\n\r\n");
// Test Classes
const char *code =
"class Test { "
" constructor(val) { this.val = val; } "
" getVal() { return this.val; } "
"} "
"let t = new Test(42); "
"t.getVal();";
Print(L"Evaluating code...\r\n");
JSValue val = JS_Eval(ctx, code, strlen(code), "<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(val)) {
JSValue ex = JS_GetException(ctx);
const char *str = JS_ToCString(ctx, ex);
if (str) {
printf("Exception: %s\n", str);
JS_FreeCString(ctx, str);
} else {
printf("Exception: [unknown]\n");
}
JS_FreeValue(ctx, ex);
} else {
const char *str = JS_ToCString(ctx, val);
if (str) {
printf("Result: %s\n", str);
JS_FreeCString(ctx, str);
} else {
printf("Result: [unknown]\n");
}
JS_FreeValue(ctx, val);
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
Print(L"\r\nSuccess!\r\n");
Print(L"\r\nPress Ctrl+C...\r\n");
for(;;);
return EFI_SUCCESS;
}

51
src/core/compat/math.h Normal file
View File

@@ -0,0 +1,51 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _MATH_H
#define _MATH_H
#define NAN (__builtin_nan(""))
#define INFINITY (__builtin_inf())
#define signbit(x) __builtin_signbit(x)
double floor(double x);
double ceil(double x);
double fabs(double x);
double modf(double x, double *iptr);
double fmod(double x, double y);
double sqrt(double x);
double pow(double x, double y);
double log(double x);
double exp(double x);
double sin(double x);
double cos(double x);
double tan(double x);
int isnan(double x);
int isinf(double x);
int isfinite(double x);
double trunc(double x);
double fmin(double x, double y);
double fmax(double x, double y);
double hypot(double x, double y);
double acos(double x);
double asin(double x);
double atan(double x);
double atan2(double y, double x);
double cbrt(double x);
double cosh(double x);
double expm1(double x);
double log1p(double x);
double log2(double x);
double log10(double x);
double sinh(double x);
double tanh(double x);
double asinh(double x);
double acosh(double x);
double atanh(double x);
double round(double x);
long int lrint(double x);
#endif

664
src/core/compat/minilibc.c Normal file
View File

@@ -0,0 +1,664 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
extern int printf(const char *format, ...);
// Basic libc stub implementations for Elk
// String functions
void *memset(void *s, int c, size_t n) {
unsigned char *p = s;
while (n--) *p++ = (unsigned char)c;
return s;
}
void *memcpy(void *dest, const void *src, size_t n) {
unsigned char *d = dest;
const unsigned char *s = src;
while (n--) *d++ = *s++;
return dest;
}
void *memmove(void *dest, const void *src, size_t n) {
unsigned char *d = dest;
const unsigned char *s = src;
if (d < s) {
while (n--) *d++ = *s++;
} else {
d += n;
s += n;
while (n--) *--d = *--s;
}
return dest;
}
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = s1, *p2 = s2;
while (n--) {
if (*p1 != *p2) return *p1 - *p2;
p1++;
p2++;
}
return 0;
}
size_t strlen(const char *s) {
size_t len = 0;
while (s[len]) len++;
return len;
}
int strcmp(const char *s1, const char *s2) {
while (*s1 && (*s1 == *s2)) {
s1++;
s2++;
}
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
s1++;
s2++;
n--;
}
if (n == 0) return 0;
return *(unsigned char *)s1 - *(unsigned char *)s2;
}
char *strcpy(char *dest, const char *src) {
char *d = dest;
while ((*d++ = *src++));
return dest;
}
char *strncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n && src[i]; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}
// Math functions - basic implementations
double floor(double x) {
if (x >= 0) {
return (double)(int64_t)x;
} else {
int64_t i = (int64_t)x;
return (i == x) ? x : (double)(i - 1);
}
}
double ceil(double x) {
if (x >= 0) {
int64_t i = (int64_t)x;
return (i == x) ? x : (double)(i + 1);
} else {
return (double)(int64_t)x;
}
}
double fabs(double x) {
return x < 0 ? -x : x;
}
double modf(double x, double *iptr) {
*iptr = (double)(int64_t)x;
return x - *iptr;
}
double fmod(double x, double y) {
if (y == 0.0) return 0.0;
return x - floor(x / y) * y;
}
// Simple sqrt using Newton's method
double sqrt(double x) {
if (x < 0) return 0.0;
if (x == 0) return 0.0;
double guess = x / 2.0;
double prev;
int iterations = 10;
while (iterations--) {
prev = guess;
guess = (guess + x / guess) / 2.0;
if (fabs(guess - prev) < 0.0001) break;
}
return guess;
}
double pow(double x, double y) {
// Very basic pow - only handles integer exponents
if (y == 0.0) return 1.0;
if (y < 0.0) return 1.0 / pow(x, -y);
double result = 1.0;
int64_t exp = (int64_t)y;
while (exp--) result *= x;
return result;
}
double log(double x) {
// Simplified log (not accurate, just enough for Elk)
if (x <= 0) return 0.0;
return 0.0; // Stub
}
double exp(double x) {
// Simplified exp
(void)x;
return 1.0; // Stub
}
double sin(double x) {
(void)x;
return 0.0; // Stub
}
double cos(double x) {
(void)x;
return 1.0; // Stub
}
double tan(double x) {
(void)x;
return 0.0; // Stub
}
int isnan(double x) {
return x != x;
}
int isinf(double x) {
return x == __builtin_inf() || x == -__builtin_inf();
}
int isfinite(double x) {
return !isnan(x) && !isinf(x);
}
// Stdlib functions
double strtod(const char *str, char **endptr) {
double result = 0.0;
double sign = 1.0;
double scale = 0.1;
int decimal = 0;
while (*str == ' ' || *str == '\t') str++;
if (*str == '-') {
sign = -1.0;
str++;
} else if (*str == '+') {
str++;
}
while (*str) {
if (*str >= '0' && *str <= '9') {
if (decimal) {
result += (*str - '0') * scale;
scale *= 0.1;
} else {
result = result * 10.0 + (*str - '0');
}
} else if (*str == '.' && !decimal) {
decimal = 1;
} else {
break;
}
str++;
}
if (endptr) *endptr = (char *)str;
return result * sign;
}
long strtol(const char *str, char **endptr, int base) {
long result = 0;
int sign = 1;
while (*str == ' ') str++;
if (*str == '-') {
sign = -1;
str++;
}
while (*str >= '0' && *str <= '9') {
result = result * base + (*str - '0');
str++;
}
if (endptr) *endptr = (char *)str;
return result * sign;
}
#define HEAP_SIZE (8 * 1024 * 1024)
static unsigned char heap[HEAP_SIZE];
static size_t heap_pos = 0;
void *malloc(size_t size) {
size = (size + 7) & ~7;
size_t total = size + 8;
if (heap_pos + total > HEAP_SIZE) {
printf("malloc failed: OOM\n");
return (void*)0;
}
*(size_t*)&heap[heap_pos] = size;
void *ptr = &heap[heap_pos + 8];
heap_pos += total;
return ptr;
}
void free(void *ptr) {
(void)ptr;
}
void *realloc(void *ptr, size_t size) {
if (!ptr) return malloc(size);
size_t *p_size = (size_t*)((char*)ptr - 8);
size_t old_size = *p_size;
if (size <= old_size) return ptr;
void *new_ptr = malloc(size);
if (!new_ptr) return (void*)0;
memcpy(new_ptr, ptr, old_size);
return new_ptr;
}
void *calloc(size_t nmemb, size_t size) {
size_t total = nmemb * size;
void *ptr = malloc(total);
if (ptr) memset(ptr, 0, total);
return ptr;
}
void abort(void) {
printf("ABORT called!\n");
while(1);
}
// stdio functions
int vsnprintf(char *str, size_t size, const char *format, __builtin_va_list ap) {
size_t i = 0;
const char *p = format;
while (*p && i < size - 1) {
if (*p != '%') {
str[i++] = *p++;
continue;
}
p++; // Skip '%'
// Parse flags, width, precision, length modifiers
int precision = -1;
// Flags (ignored for now)
while (*p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '0') p++;
// Width
if (*p == '*') {
__builtin_va_arg(ap, int); // Consume width
p++;
} else {
while (*p >= '0' && *p <= '9') p++;
}
// Precision
if (*p == '.') {
p++;
if (*p == '*') {
precision = __builtin_va_arg(ap, int);
p++;
} else {
int val = 0;
while (*p >= '0' && *p <= '9') {
val = val * 10 + (*p - '0');
p++;
}
precision = val;
}
}
// Length modifiers (ignored)
while (*p == 'h' || *p == 'l' || *p == 'L' || *p == 'z' || *p == 't') p++;
if (*p == 'd' || *p == 'i') {
int val = __builtin_va_arg(ap, int);
char buf[32];
int pos = 0;
int neg = 0;
if (val < 0) { neg = 1; val = -val; }
if (val == 0) buf[pos++] = '0';
while (val) {
buf[pos++] = '0' + (val % 10);
val /= 10;
}
if (neg) buf[pos++] = '-';
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
} else if (*p == 'u') {
unsigned int val = __builtin_va_arg(ap, unsigned int);
char buf[32];
int pos = 0;
if (val == 0) buf[pos++] = '0';
while (val) {
buf[pos++] = '0' + (val % 10);
val /= 10;
}
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
} else if (*p == 's') {
const char *s = __builtin_va_arg(ap, const char *);
if (!s) s = "(null)";
size_t len = 0;
const char *tmp = s;
while (*tmp++) len++;
if (precision >= 0 && len > (size_t)precision) len = (size_t)precision;
size_t k = 0;
while (k < len && i < size - 1) str[i++] = s[k++];
} else if (*p == 'c') {
char c = (char)__builtin_va_arg(ap, int);
if (i < size - 1) str[i++] = c;
} else if (*p == 'g' || *p == 'f') {
// Basic double support
double val = __builtin_va_arg(ap, double);
int ival = (int)val;
// Print integer part
char buf[32];
int pos = 0;
int neg = 0;
if (val < 0) { neg = 1; val = -val; ival = -ival; }
if (ival == 0) buf[pos++] = '0';
int temp = ival;
while (temp) {
buf[pos++] = '0' + (temp % 10);
temp /= 10;
}
if (neg) buf[pos++] = '-';
while (pos > 0 && i < size - 1) str[i++] = buf[--pos];
// Simple decimal part (up to 4 digits)
val -= (int)val;
if (val > 0.0001) {
if (i < size - 1) str[i++] = '.';
for (int k=0; k<4 && val > 0.0001 && i < size-1; k++) {
val *= 10;
int digit = (int)val;
str[i++] = '0' + digit;
val -= digit;
}
}
} else {
if (i < size - 1) str[i++] = *p;
}
p++;
}
str[i] = '\0';
return i;
}
int snprintf(char *str, size_t size, const char *format, ...) {
__builtin_va_list ap;
__builtin_va_start(ap, format);
int ret = vsnprintf(str, size, format, ap);
__builtin_va_end(ap);
return ret;
}
// Compiler intrinsics for Windows target
void __chkstk(void) {
// Stack checking - not needed for UEFI
}
int _fltused = 0; // Floating point used marker
char *strchr(const char *s, int c) {
while (*s != (char)c) {
if (!*s++) {
return (void*)0;
}
}
return (char *)s;
}
double trunc(double x) {
return (x > 0) ? floor(x) : ceil(x);
}
double fmin(double x, double y) {
return (x < y) ? x : y;
}
double fmax(double x, double y) {
return (x > y) ? x : y;
}
double hypot(double x, double y) {
return sqrt(x*x + y*y);
}
double acos(double x) { (void)x; return 0.0; }
double asin(double x) { (void)x; return 0.0; }
double atan(double x) { (void)x; return 0.0; }
double atan2(double y, double x) { (void)y; (void)x; return 0.0; }
double cbrt(double x) { (void)x; return 0.0; }
double cosh(double x) { (void)x; return 0.0; }
double expm1(double x) { (void)x; return 0.0; }
double log1p(double x) { (void)x; return 0.0; }
double log2(double x) { (void)x; return 0.0; }
double log10(double x) { (void)x; return 0.0; }
double sinh(double x) { (void)x; return 0.0; }
double tanh(double x) { (void)x; return 0.0; }
double asinh(double x) { (void)x; return 0.0; }
double acosh(double x) { (void)x; return 0.0; }
double atanh(double x) { (void)x; return 0.0; }
double round(double x) {
return (x >= 0.0) ? floor(x + 0.5) : ceil(x - 0.5);
}
long int lrint(double x) {
return (long int)round(x);
}
size_t _msize(void *ptr) {
if (!ptr) return 0;
return *(size_t*)((char*)ptr - 8);
}
int fesetround(int round) { (void)round; return 0; }
int fegetround(void) { return 0; }
int errno = 0;
#include "time.h"
#include "sys/time.h"
time_t time(time_t *t) {
if (t) *t = 0;
return 0;
}
static struct tm tm_buf;
struct tm *gmtime(const time_t *timep) {
(void)timep;
// Stub: return 1970-01-01
tm_buf.tm_year = 70;
tm_buf.tm_mon = 0;
tm_buf.tm_mday = 1;
return &tm_buf;
}
struct tm *localtime(const time_t *timep) {
return gmtime(timep);
}
time_t mktime(struct tm *tm) {
(void)tm;
return 0;
}
int gettimeofday(struct timeval *tv, struct timezone *tz) {
if (tv) {
tv->tv_sec = 0;
tv->tv_usec = 0;
}
return 0;
}
void *memchr(const void *s, int c, size_t n) {
const unsigned char *p = s;
while (n--) {
if (*p == (unsigned char)c) return (void *)p;
p++;
}
return (void*)0;
}
char *strcat(char *dest, const char *src) {
char *d = dest;
while (*d) d++;
while ((*d++ = *src++));
return dest;
}
char *strncat(char *dest, const char *src, size_t n) {
char *d = dest;
while (*d) d++;
while (n-- && *src) *d++ = *src++;
*d = 0;
return dest;
}
char *strstr(const char *haystack, const char *needle) {
size_t len = strlen(needle);
if (len == 0) return (char *)haystack;
while (*haystack) {
if (!memcmp(haystack, needle, len)) return (char *)haystack;
haystack++;
}
return (void*)0;
}
char *strdup(const char *s) {
size_t len = strlen(s) + 1;
char *new = malloc(len);
if (new) memcpy(new, s, len);
return new;
}
char *strrchr(const char *s, int c) {
const char *found = (void*)0;
while (*s) {
if (*s == (char)c) found = s;
s++;
}
if (*s == (char)c) found = s;
return (char *)found;
}
int abs(int j) {
return (j < 0) ? -j : j;
}
int isdigit(int c) {
return (c >= '0' && c <= '9');
}
int isspace(int c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r');
}
int isupper(int c) {
return (c >= 'A' && c <= 'Z');
}
int islower(int c) {
return (c >= 'a' && c <= 'z');
}
int isalpha(int c) {
return isupper(c) || islower(c);
}
int isalnum(int c) {
return isalpha(c) || isdigit(c);
}
int tolower(int c) {
return isupper(c) ? c + 32 : c;
}
int toupper(int c) {
return islower(c) ? c - 32 : c;
}
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
// Simple bubble sort for now
if (nmemb < 2 || size == 0) return;
char *b = (char *)base;
// Byte-by-byte swap to avoid malloc
for (size_t i = 0; i < nmemb - 1; i++) {
for (size_t j = 0; j < nmemb - i - 1; j++) {
if (compar(b + j * size, b + (j + 1) * size) > 0) {
char *p1 = b + j * size;
char *p2 = b + (j + 1) * size;
for (size_t k = 0; k < size; k++) {
char t = p1[k];
p1[k] = p2[k];
p2[k] = t;
}
}
}
}
}
#include "setjmp.h"
int setjmp(jmp_buf env) {
(void)env;
return 0;
}
void longjmp(jmp_buf env, int val) {
(void)env; (void)val;
printf("longjmp called!\n");
abort();
}

18
src/core/compat/setjmp.h Normal file
View File

@@ -0,0 +1,18 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _SETJMP_H
#define _SETJMP_H
#include <stdint.h>
// x86_64 jmp_buf: rbx, rbp, r12, r13, r14, r15, rsp, rip
typedef uint64_t jmp_buf[8];
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
#endif

12
src/core/compat/stdarg.h Normal file
View File

@@ -0,0 +1,12 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)

23
src/core/compat/stdio.h Normal file
View File

@@ -0,0 +1,23 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#include <stdarg.h>
#include <stddef.h>
typedef struct FILE FILE;
#define stdout ((FILE*)1)
#define stderr ((FILE*)2)
#define stdin ((FILE*)0)
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int fputc(int c, FILE *stream);
int putchar(int c);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

20
src/core/compat/stdlib.h Normal file
View File

@@ -0,0 +1,20 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#pragma once
#include <stddef.h>
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
double strtod(const char *str, char **endptr);
long strtol(const char *str, char **endptr, int base);
void abort(void);
#define alloca __builtin_alloca
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
int abs(int j);
size_t _msize(void *ptr);

29
src/core/compat/string.h Normal file
View File

@@ -0,0 +1,29 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _STRING_H
#define _STRING_H
#include <stddef.h>
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strstr(const char *haystack, const char *needle);
char *strdup(const char *s);
void *memchr(const void *s, int c, size_t n);
#endif

View File

@@ -0,0 +1,24 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
#include "time.h"
struct timeval {
long tv_sec;
long tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif

31
src/core/compat/time.h Normal file
View File

@@ -0,0 +1,31 @@
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
#ifndef _TIME_H
#define _TIME_H
#include <stddef.h>
typedef long time_t;
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
time_t time(time_t *t);
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
time_t mktime(struct tm *tm);
#endif

184
src/core/efi.h Normal file
View File

@@ -0,0 +1,184 @@
#ifndef EFI_H
#define EFI_H
#include <stdint.h>
#define NULL ((void*)0)
// Basic Types
typedef uint64_t UINT64;
typedef uint32_t UINT32;
typedef uint16_t UINT16;
typedef uint8_t UINT8;
typedef uintptr_t UINTN;
typedef intptr_t INTN;
typedef void VOID;
typedef uint64_t EFI_STATUS;
typedef void* EFI_HANDLE;
#define EFI_SUCCESS 0
#define EFI_ERROR(status) (((INTN)(status)) < 0)
typedef struct {
UINT32 Data1;
UINT16 Data2;
UINT16 Data3;
UINT8 Data4[8];
} EFI_GUID;
typedef struct {
uint64_t signature;
uint32_t revision;
uint32_t headerSize;
uint32_t crc32;
uint32_t reserved;
} EFI_TABLE_HEADER;
// Simple Text Output Protocol
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
typedef EFI_STATUS (*EFI_TEXT_STRING)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
uint16_t *String
);
typedef EFI_STATUS (*EFI_TEXT_CLEAR_SCREEN)(
struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
);
typedef struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL {
void *reset;
EFI_TEXT_STRING OutputString;
void *testString;
void *queryMode;
void *setMode;
void *setAttribute;
EFI_TEXT_CLEAR_SCREEN ClearScreen;
void *setCursorPosition;
void *enableCursor;
void *mode;
} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
// Boot Services
typedef struct {
EFI_TABLE_HEADER Hdr;
void *RaiseTPL;
void *RestoreTPL;
void *AllocatePages;
void *FreePages;
void *GetMemoryMap;
void *AllocatePool;
void *FreePool;
void *CreateEvent;
void *SetTimer;
void *WaitForEvent;
void *SignalEvent;
void *CloseEvent;
void *CheckEvent;
void *InstallProtocolInterface;
void *ReinstallProtocolInterface;
void *UninstallProtocolInterface;
void *HandleProtocol;
void *Reserved;
void *RegisterProtocolNotify;
void *LocateHandle;
void *LocateDevicePath;
void *InstallConfigurationTable;
void *LoadImage;
void *StartImage;
void *Exit;
void *UnloadImage;
void *ExitBootServices;
void *GetNextMonotonicCount;
void *Stall;
void *SetWatchdogTimer;
void *ConnectController;
void *DisconnectController;
void *OpenProtocol;
void *CloseProtocol;
void *OpenProtocolInformation;
void *ProtocolsPerHandle;
void *LocateHandleBuffer;
EFI_STATUS (*LocateProtocol)(EFI_GUID *Protocol, void *Registration, void **Interface);
void *InstallMultipleProtocolInterfaces;
void *UninstallMultipleProtocolInterfaces;
void *CalculateCrc32;
void *CopyMem;
void *SetMem;
void *CreateEventEx;
} EFI_BOOT_SERVICES;
// PCI Root Bridge IO Protocol
#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \
{ 0x2f707ebb, 0x4a1a, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }
typedef enum {
EfiPciWidthUint8,
EfiPciWidthUint16,
EfiPciWidthUint32,
EfiPciWidthUint64,
EfiPciWidthFifoUint8,
EfiPciWidthFifoUint16,
EfiPciWidthFifoUint32,
EfiPciWidthFifoUint64,
EfiPciWidthFillUint8,
EfiPciWidthFillUint16,
EfiPciWidthFillUint32,
EfiPciWidthFillUint64,
EfiPciWidthMaximum
} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH;
typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;
typedef
EFI_STATUS
(*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM) (
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
UINT64 Address,
UINTN Count,
VOID *Buffer
);
typedef struct {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write;
} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS;
struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL {
void *ParentHandle;
void *PollMem;
void *PollIo;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci;
void *CopyMem;
void *Map;
void *Unmap;
void *AllocateBuffer;
void *FreeBuffer;
void *Flush;
void *GetAttributes;
void *SetAttributes;
void *Configuration;
UINT32 SegmentNumber;
};
// System Table
typedef struct EFI_SYSTEM_TABLE {
EFI_TABLE_HEADER hdr;
uint16_t *firmwareVendor;
uint32_t firmwareRevision;
void *consoleInHandle;
void *conIn;
void *consoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
void *standardErrorHandle;
void *stdErr;
void *runtimeServices;
EFI_BOOT_SERVICES *BootServices;
uint64_t numberOfTableEntries;
void *configurationTable;
} EFI_SYSTEM_TABLE;
#endif

203
src/core/main.c Normal file
View File

@@ -0,0 +1,203 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#include "efi.h"
#include "util.h"
#include "system_prog.h"
static EFI_SYSTEM_TABLE *gST = NULL;
void print(uint16_t *str) {
if (gST && gST->ConOut)
gST->ConOut->OutputString(gST->ConOut, str);
}
int printf(const char *format, ...) {
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
print(AsciiToUnicode(buf));
return ret;
}
int fprintf(FILE *stream, const char *format, ...) {
if (stream != stdout && stream != stderr) return 0;
char buf[1024];
va_list ap;
va_start(ap, format);
int ret = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
print(AsciiToUnicode(buf));
return ret;
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
if (stream != stdout && stream != stderr) return 0;
const char *p = ptr;
size_t total = size * nmemb;
char buf[1025];
size_t i = 0;
while (i < total) {
size_t chunk = total - i;
if (chunk > 1024) chunk = 1024;
memcpy(buf, p + i, chunk);
buf[chunk] = 0;
print(AsciiToUnicode(buf));
i += chunk;
}
return nmemb;
}
int fputc(int c, FILE *stream) {
if (stream != stdout && stream != stderr) return c;
char buf[2] = { (char)c, 0 };
print(AsciiToUnicode(buf));
return c;
}
int putchar(int c) {
return fputc(c, stdout);
}
// ------------------------------- Kernel C TS bindings -------------------------------
JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
const char *str = JS_ToCString(ctx, argv[0]);
if (!str) return JS_EXCEPTION;
print(AsciiToUnicode(str));
print(L"\r\n");
JS_FreeCString(ctx, str);
return JS_UNDEFINED;
}
JSValue jsKCClearScreen(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
gST->ConOut->ClearScreen(gST->ConOut);
return JS_UNDEFINED;
}
JSValue jsKCPCIReadDword(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
uint32_t addr_u32;
JS_ToUint32(ctx, &addr_u32, argv[0]);
UINT64 addr = (UINT64)addr_u32; // Ensure type matches EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_RW's Address parameter
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL* pci;
EFI_GUID pciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
EFI_STATUS status = gST->BootServices->LocateProtocol(&pciGuid, NULL, (void**)&pci);
if (EFI_ERROR(status)) {
return JS_ThrowInternalError(ctx, "Failed to locate PCI Root Bridge IO Protocol: %d", status);
}
UINT32 data = 0;
status = pci->Pci.Read(pci, EfiPciWidthUint32, addr, 1, &data);
return JS_NewUint32(ctx, data);
}
void initKC(JSContext *ctx) {
JSValue global = JS_GetGlobalObject(ctx);
JSValue kc = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, global, "kc", kc);
JS_SetPropertyStr(ctx, kc, "println", JS_NewCFunction(ctx, jsKCPrintln, "println", 1));
JS_SetPropertyStr(ctx, kc, "clearScreen", JS_NewCFunction(ctx, jsKCClearScreen, "clearScreen", 0));
JS_SetPropertyStr(ctx, kc, "pciReadDword", JS_NewCFunction(ctx, jsKCPCIReadDword, "pciReadDword", 1));
JS_FreeValue(ctx, global);
}
// ------------------------------------- EFI main -------------------------------------
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
(void)ImageHandle;
gST = SystemTable;
gST->ConOut->ClearScreen(gST->ConOut);
print(L"Booting LintsOS...\r\n");
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
print(L"!!! Kernel panic: Failed to create runtime !!!\r\n");
return EFI_SUCCESS;
}
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
print(L"!!! Kernel panic: Failed to create context !!!\r\n");
JS_FreeRuntime(rt);
return EFI_SUCCESS;
}
initKC(ctx);
JSValue val;
JSValue eval_result = JS_Eval(ctx, SYSTEM_PROG_JS, strlen(SYSTEM_PROG_JS), "<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(eval_result)) val = eval_result;
else {
JS_FreeValue(ctx, eval_result);
JSValue global_obj = JS_GetGlobalObject(ctx);
JSValue kentry_func = JS_GetPropertyStr(ctx, global_obj, "KEntry");
if (JS_IsFunction(ctx, kentry_func)) val = JS_Call(ctx, kentry_func, JS_UNDEFINED, 0, NULL);
else val = JS_ThrowReferenceError(ctx, "KEntry function not found or not callable");
JS_FreeValue(ctx, kentry_func);
JS_FreeValue(ctx, global_obj);
}
if (JS_IsException(val)) {
JSValue ex = JS_GetException(ctx);
const char *str = JS_ToCString(ctx, ex);
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else printf("!!! Kernel panic: [unknown] !!!\n");
JS_FreeValue(ctx, ex);
} else {
const char *str = JS_ToCString(ctx, val);
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else printf("!!! Kernel panic: [unknown] !!!\n");
JS_FreeValue(ctx, val);
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
for(;;);
return EFI_SUCCESS;
}

32
src/core/util.c Normal file
View File

@@ -0,0 +1,32 @@
#include "util.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#include "efi.h"
void halt() {
for(;;);
}
//---------------------------------------------------------------
//
// !!! AI GENERATE SLOP, PLEASE FIX !!!
//
//---------------------------------------------------------------
uint16_t *AsciiToUnicode(const char *ascii) {
static uint16_t buffer[1024];
int i;
for (i = 0; ascii[i] && i < 1023; i++) {
buffer[i] = (uint16_t)ascii[i];
}
buffer[i] = 0;
return buffer;
}

13
src/core/util.h Normal file
View File

@@ -0,0 +1,13 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#ifndef UTIL_H
#define UTIL_H
void halt();
uint16_t *AsciiToUnicode(const char *ascii);
#endif

1
src/lib/quickjs Submodule

Submodule src/lib/quickjs added at 177e1b32a4

150
src/scripts/build_core.sh Executable file
View File

@@ -0,0 +1,150 @@
#!/bin/bash
set -e
mkdir -p out
mkdir -p out/core
mkdir -p out/lib
mkdir -p out/lib/quickjs
mkdir -p out/img
mkdir -p out/img/EFI/BOOT
# Compile minilibc
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-D_GNU_SOURCE \
-DUEFI \
-O2 \
-c src/core/compat/minilibc.c -o out/core/minilibc.o
# Compile QuickJS
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/lib/quickjs/cutils.c -o out/lib/quickjs/cutils.o
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/lib/quickjs/libunicode.c -o out/lib/quickjs/libunicode.o
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/lib/quickjs/libregexp.c -o out/lib/quickjs/libregexp.o
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/lib/quickjs/dtoa.c -o out/lib/quickjs/dtoa.o
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/lib/quickjs/quickjs.c -o out/lib/quickjs/quickjs.o
# Compile util.c
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/core/util.c -o out/core/util.o
# Compile main application
clang -target x86_64-pc-win32-coff \
-ffreestanding \
-fno-stack-protector \
-fshort-wchar \
-mno-red-zone \
-Isrc/core/compat \
-Isrc/lib/quickjs \
-Iout/system \
-D_GNU_SOURCE \
-DUEFI \
-DCONFIG_VERSION=\"2021-03-27\" \
-DJS_LIMB_BITS=32 \
-DNDEBUG \
-O2 \
-c src/core/main.c -o out/core/main.o
# Link
lld-link \
-filealign:16 \
-subsystem:efi_application \
-nodefaultlib \
-dll \
-entry:efi_main \
out/core/main.o \
out/core/util.o \
out/core/minilibc.o \
out/lib/quickjs/cutils.o \
out/lib/quickjs/libunicode.o \
out/lib/quickjs/libregexp.o \
out/lib/quickjs/dtoa.o \
out/lib/quickjs/quickjs.o \
-out:out/img/EFI/BOOT/bootx64.efi
echo "Built efi app: out/img/EFI/BOOT/bootx64.efi"

View File

@@ -7,13 +7,7 @@ mmd -i out/fat.img ::/EFI
mmd -i out/fat.img ::/EFI/BOOT mmd -i out/fat.img ::/EFI/BOOT
# Copy the EFI application # Copy the EFI application
mcopy -i out/fat.img out/img/EFI/BOOT/BOOTX64.EFI ::/EFI/BOOT mcopy -i out/fat.img out/img/EFI/BOOT/bootx64.efi ::/EFI/BOOT
# Verify content
echo "Verifying FAT image content:"
mdir -i out/fat.img -/ ::
# Create the ISO # Create the ISO
# -e specifies the boot image (the FAT image)
# -no-emul-boot is required for UEFI
xorriso -as mkisofs -R -f -e /fat.img -no-emul-boot -volid LintsEFI -o out/lints.iso out/img out/fat.img xorriso -as mkisofs -R -f -e /fat.img -no-emul-boot -volid LintsEFI -o out/lints.iso out/img out/fat.img

7
src/scripts/build_system.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -e
mkdir -p out
mkdir -p out/system
bun build --outdir out/system src/system/src/__.ts

28
src/scripts/embed_system.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
set -e
echo "#ifndef SYSTEM_PROG_H" > out/system/system_prog.h
echo "#define SYSTEM_PROG_H" >> out/system/system_prog.h
echo "const char* SYSTEM_PROG_JS = \\" >> out/system/system_prog.h
remove_mode=false
while IFS= read -r line; do
if [ "$remove_mode" = true ]; then
remove_mode=false
continue
fi
ESCAPED_LINE=$(echo "$line" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g')
if echo "$line" | grep -q "___remove_next_line"; then
remove_mode=true
continue
fi
echo "\"${ESCAPED_LINE}\\n\"" >> out/system/system_prog.h
done < out/system/__.js
echo ";" >> out/system/system_prog.h
echo "#endif" >> out/system/system_prog.h

5
src/scripts/prepare_build.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -e
rm -rf out

49
src/scripts/run_vbox.sh Executable file
View File

@@ -0,0 +1,49 @@
#!/bin/bash
set -e # Exit on error
VM_NAME="LintsOS"
DISK_IMG="${1:-out/fat.img}"
# Remove existing VM if it exists
if VBoxManage list vms | grep -q "\"${VM_NAME}\""; then
VBoxManage unregistervm ${VM_NAME} --delete 2>/dev/null || true
fi
# Remove old VDI if it exists
if [ -f "uefi-disk.vdi" ]; then
rm -f uefi-disk.vdi
fi
VBoxManage createvm --name "${VM_NAME}" --ostype "Other_64" --register
VBoxManage modifyvm "${VM_NAME}" \
--memory 512 \
--vram 16 \
--cpus 1 \
--firmware efi \
--boot1 disk \
--boot2 none \
--boot3 none \
--boot4 none \
--graphicscontroller vmsvga \
--mouse usbtablet
VBoxManage storagectl "${VM_NAME}" \
--name "SATA Controller" \
--add sata \
--controller IntelAhci \
--portcount 1 \
--bootable on
VBoxManage convertfromraw ${DISK_IMG} out/test-disk.vdi --format VDI
VBoxManage storageattach "${VM_NAME}" \
--storagectl "SATA Controller" \
--port 0 \
--device 0 \
--type hdd \
--medium out/test-disk.vdi
# Start the VM
VBoxManage startvm "${VM_NAME}"

View File

@@ -1,4 +1,4 @@
# os # lints-system
To install dependencies: To install dependencies:
@@ -9,7 +9,7 @@ bun install
To run: To run:
```bash ```bash
bun run index.ts bun run src/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. This project was created using `bun init` in bun v1.2.20. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.

View File

@@ -2,7 +2,7 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"workspaces": { "workspaces": {
"": { "": {
"name": "os", "name": "lints-system",
"devDependencies": { "devDependencies": {
"@types/bun": "latest", "@types/bun": "latest",
}, },

View File

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

10
src/system/src/__.ts Normal file
View File

@@ -0,0 +1,10 @@
// DO NOT EDIT, REMOVE OR IMPORT THIS FILE
// This is used for bundler to not remove the KEntry function (called by C code)
// The function will be removed after bundling
import { KEntry } from "./entry";
declare function ___remove_next_line(): void;
// Mark the KEntry for removal
___remove_next_line();
KEntry();

5
src/system/src/entry.ts Normal file
View File

@@ -0,0 +1,5 @@
import { KMain } from "./kernel";
export function KEntry() {
KMain();
}

View File

@@ -0,0 +1,93 @@
import { Logger } from "../../../lib/logger";
import { numtohex } from "../../../util/hex";
import { SysFS } from "../../filesystem/sys.fs";
import { KernelDriver } from "../kdriver";
export class PCIKDriver extends KernelDriver {
static instance: PCIKDriver = new this();
constructor() {
super("pci");
}
static init() {
PCIKDriver.instance.init();
}
override init() {
super.init();
SysFS.instance.pMkdir("/pci");
this.#detectDevices();
}
#detectDevices() {
Logger.log("[PCI] Scanning...");
for (let bus = 0; bus < 256; bus++) {
for (let device = 0; device < 32; device++) {
this.#checkDevice(bus, device, 0);
const headerType = this.#getHeaderType(bus, device, 0);
if ((headerType & 0x80) === 0) continue;
for (let func = 1; func < 8; func++) {
this.#checkDevice(bus, device, func);
}
}
}
}
#checkDevice(bus: number, device: number, func: number) {
const data = this.#readConfig(bus, device, func, 0);
if (data === 0 || data === 0xffffffff) return;
const vendorId = this.#getDeviceVendorId(bus, device, func);
const deviceId = this.#getDeviceId(bus, device, func);
const classId = this.#getDeviceClass(bus, device, func);
const subclassId = this.#getDeviceSubclass(bus, device, func);
const filename = `pci.${bus}.${device}.${func}`;
Logger.log(
`[PCI] Found device: ${filename} (vendor: ${numtohex(
vendorId
)}, device: ${numtohex(deviceId)}, class: ${numtohex(
classId
)}, subclass: ${numtohex(subclassId)})`
);
SysFS.instance.pMkdir(`/pci/${filename}`);
SysFS.instance.pWriteFile(`/pci/${filename}/vendor`, numtohex(vendorId));
SysFS.instance.pWriteFile(`/pci/${filename}/device`, numtohex(deviceId));
SysFS.instance.pWriteFile(`/pci/${filename}/class`, numtohex(classId));
SysFS.instance.pWriteFile(
`/pci/${filename}/subclass`,
numtohex(subclassId)
);
}
#getDeviceId(bus: number, device: number, func: number) {
return this.#readConfig(bus, device, func, 0) >>> 16;
}
#getDeviceVendorId(bus: number, device: number, func: number) {
return this.#readConfig(bus, device, func, 0) & 0xffff;
}
#getDeviceClass(bus: number, device: number, func: number) {
return (this.#readConfig(bus, device, func, 8) >> 24) & 0xff;
}
#getDeviceSubclass(bus: number, device: number, func: number) {
return (this.#readConfig(bus, device, func, 8) >> 16) & 0xff;
}
#getHeaderType(bus: number, device: number, func: number) {
return (this.#readConfig(bus, device, func, 12) >> 16) & 0xff;
}
#readConfig(bus: number, device: number, func: number, offset: number) {
return kc.pciReadDword((bus << 16) | (device << 11) | (func << 8) | offset);
}
}

View File

@@ -0,0 +1,20 @@
import { Logger } from "../../lib/logger";
export class KernelDriver {
#name: string;
#initialized: boolean = false;
constructor(name: string) {
this.#name = name;
}
init() {
Logger.log(`[Kernel] Initializing ${this.#name} driver...`);
this.#initialized = true;
}
get initialized() {
return this.#initialized;
}
}

View File

@@ -0,0 +1,51 @@
export class FSEntity {
#name: string;
#path: string;
#size: number;
#type: "d" | "f";
#content: string | string[] | FSEntity[];
constructor(
name: string,
path: string,
size: number,
type: "d" | "f",
content: string | string[] | FSEntity[]
) {
this.#name = name;
this.#path = path;
this.#size = size;
this.#type = type;
this.#content = content;
}
get name() {
return this.#name;
}
get path() {
return this.#path;
}
get size() {
return this.#size;
}
get type() {
return this.#type;
}
get content() {
return this.#content;
}
set content(content: string | string[] | FSEntity[]) {
this.#content = content;
this.#size =
this.#type == "d"
? 0
: content instanceof Array
? this.#content.length
: this.#content.length;
}
}

View File

@@ -0,0 +1,61 @@
import { Logger } from "../../../lib/logger";
import { FSEntity } from "./entity";
export class FileSystem {
#id: string;
#root: FSEntity;
constructor(id: string) {
this.#id = id;
this.#root = new FSEntity("", "/", 0, "d", []);
}
get id() {
return this.#id;
}
protected getEntity(path: string) {
if (path === "/") return this.#root;
const parts = path.split("/");
let entity = this.#root;
for (let i = 1; i < parts.length; i++) {
if (!entity.content || entity.content.length === 0) return null;
if (entity.type !== "d") return null;
entity = (entity.content as FSEntity[]).find((e) => e.name === parts[i])!;
}
return entity;
}
mkdir(path: string) {
throw new Error("FS::Mkdir Not implemented");
}
ls(path: string) {
throw new Error("FS::Ls Not implemented");
}
readFile(path: string) {
throw new Error("FS::ReadFile Not implemented");
}
writeFile(path: string, content: string) {
throw new Error("FS::WriteFile Not implemented");
}
createFile(path: string) {
throw new Error("FS::CreateFile Not implemented");
}
remove(path: string) {
throw new Error("FS::Remove Not implemented");
}
stat(path: string) {
throw new Error("FS::Stat Not implemented");
}
}

View File

@@ -0,0 +1,75 @@
import { Logger } from "../../lib/logger";
import { Path } from "../../lib/path";
import { FSEntity } from "./fs/entity";
import { FileSystem } from "./fs/fs";
export class SysFS extends FileSystem {
static instance: SysFS = new this();
constructor() {
super("sysfs");
}
override mkdir(path: string): void {
throw new Error("SysFS::Mkdir sysfs is read-only");
}
public pMkdir(path: string): void {
const parent = this.getEntity(Path.dirname(path));
if (!parent || parent.type !== "d") return;
(parent.content as FSEntity[]).push(
new FSEntity(Path.filename(path), path, 0, "d", [])
);
}
public pWriteFile(path: string, content: string): void {
const parent = this.getEntity(Path.dirname(path));
if (!parent || parent.type !== "d") return;
const existing = (parent.content as FSEntity[]).find(
(e) => e.name === Path.filename(path)
);
if (existing) {
existing.content = content;
return;
}
(parent.content as FSEntity[]).push(
new FSEntity(Path.filename(path), path, content.length, "f", content)
);
}
override ls(path: string): FSEntity[] {
const entity = this.getEntity(path);
if (!entity || entity.type !== "d") return [];
return entity.content as FSEntity[];
}
override createFile(path: string): void {
throw new Error("SysFS::CreateFile sysfs is read-only");
}
override writeFile(path: string, content: string): void {
throw new Error("SysFS::WriteFile sysfs is read-only");
}
override readFile(path: string): string {
const entity = this.getEntity(path);
if (!entity || entity.type !== "f") return "";
return entity.content as string;
}
override remove(path: string): void {
throw new Error("SysFS::Remove sysfs is read-only");
}
override stat(path: string): FSEntity | null {
const entity = this.getEntity(path);
if (!entity) return null;
return entity;
}
}

View File

@@ -0,0 +1,17 @@
import { Logger } from "../lib/logger";
import { SysFS } from "./filesystem/sys.fs";
import { ConsoleKModule } from "./modules/console/console.kmod";
import { DriverKModule } from "./modules/driver";
import { VFSKModule } from "./modules/vfs/vfs.kmod";
export function KMain() {
Logger.clear();
Logger.log("[Kernel] Initializing kernel...");
ConsoleKModule.init();
VFSKModule.init();
VFSKModule.instance.mount(SysFS.instance, "/sys");
DriverKModule.init();
}

View File

@@ -0,0 +1,25 @@
import { KernelModule } from "../kmod";
export class ConsoleKModule extends KernelModule {
static instance: ConsoleKModule = new this();
constructor() {
super("console");
}
static init() {
ConsoleKModule.instance.init();
}
println(msg: string) {
if (!this.initialized) return;
kc.println(msg);
}
clear() {
if (!this.initialized) return;
kc.clearScreen();
}
}

View File

@@ -0,0 +1,25 @@
import { PCIKDriver } from "../drivers/dev/pci.drv";
import type { KernelDriver } from "../drivers/kdriver";
import { KernelModule } from "./kmod";
export const DRIVERS: KernelDriver[] = [PCIKDriver.instance];
export class DriverKModule extends KernelModule {
static instance: DriverKModule = new this();
constructor() {
super("driver");
}
static init() {
DriverKModule.instance.init();
}
override init() {
super.init();
for (const driver of DRIVERS) {
driver.init();
}
}
}

View File

@@ -0,0 +1,20 @@
import { Logger } from "../../lib/logger";
export class KernelModule {
#name: string;
#initialized: boolean = false;
constructor(name: string) {
this.#name = name;
}
init() {
Logger.log(`[Kernel] Initializing ${this.#name} module...`);
this.#initialized = true;
}
get initialized() {
return this.#initialized;
}
}

View File

@@ -0,0 +1,89 @@
import { Logger } from "../../../lib/logger";
import type { FileSystem } from "../../filesystem/fs/fs";
import { KernelModule } from "../kmod";
export class VFSKModule extends KernelModule {
static instance: VFSKModule = new this();
#mounts: Map<string, FileSystem> = new Map();
constructor() {
super("vfs");
}
static init() {
VFSKModule.instance.init();
}
mount(fs: FileSystem, mountPoint: string) {
if (!this.initialized) return;
Logger.log(`[VFS] Mounting ${fs.id} at ${mountPoint}`);
this.#mounts.set(mountPoint, fs);
}
#resolveMount(path: string) {
const parts = path.split("/");
for (let i = 0; i < parts.length; i++) {
const mountPoint = parts.slice(0, i + 1).join("/");
if (this.#mounts.has(mountPoint))
return {
fs: this.#mounts.get(mountPoint)!,
path: parts.slice(i + 1).join("/"),
};
}
return null;
}
mkdir(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
mount.fs.mkdir(mount.path);
}
ls(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
return mount.fs.ls(mount.path);
}
createFile(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
mount.fs.createFile(mount.path);
}
writeFile(path: string, content: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
mount.fs.writeFile(mount.path, content);
}
readFile(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
return mount.fs.readFile(mount.path);
}
remove(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
mount.fs.remove(mount.path);
}
stat(path: string) {
const mount = this.#resolveMount(path);
if (!mount) return;
return mount.fs.stat(mount.path);
}
}

View File

@@ -0,0 +1,25 @@
import { ConsoleKModule } from "../kernel/modules/console/console.kmod";
export class Logger {
static log(msg: string) {
if (!ConsoleKModule.instance.initialized)
return Logger.fallbackConsolePrintln(msg);
ConsoleKModule.instance.println(msg);
}
static clear() {
if (!ConsoleKModule.instance.initialized)
return Logger.fallbackConsoleClearScreen();
ConsoleKModule.instance.clear();
}
static fallbackConsolePrintln(msg: string) {
kc.println(msg);
}
static fallbackConsoleClearScreen() {
kc.clearScreen();
}
}

View File

@@ -0,0 +1,13 @@
export class Path {
static dirname(path: string) {
return path.split("/").slice(0, -1).join("/");
}
static filename(path: string) {
return path.split("/").pop()!;
}
static join(...paths: string[]) {
return paths.join("/");
}
}

5
src/system/src/types/kc.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
declare namespace kc {
function println(msg: string): void;
function clearScreen(): void;
function pciReadDword(addr: number): number;
}

View File

@@ -0,0 +1,3 @@
export function numtohex(num: number) {
return num.toString(16);
}