summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Lee <me@nwlee.tech>2026-09-26 16:22:04 -0500
committerNathan Lee <me@nwlee.tech>2026-09-26 16:22:04 -0500
commit9660366219c28fc827c24ce7b428ad7e2534ead0 (patch)
treeb4ca2c6d46bc4f0ba46961bc903c130b09b03934
parent548905a86473101325540446f35ffda8acd0c3bb (diff)
scaffold rest of website
-rwxr-xr-xbuild_complete.sh11
-rwxr-xr-xcleanup_artifacts.sh9
-rw-r--r--website-emu/src/dev.js6
-rw-r--r--website-emu/src/lib.rs27
-rw-r--r--website-emu/src/state.rs4
-rw-r--r--website-kernel/Makefile3
-rw-r--r--website-kernel/arch/kernel.c12
-rw-r--r--website-kernel/include/int.h3
-rw-r--r--website-kernel/include/sys.h16
-rw-r--r--website-src/index.html30
-rw-r--r--website-src/style.css51
11 files changed, 157 insertions, 15 deletions
diff --git a/build_complete.sh b/build_complete.sh
new file mode 100755
index 0000000..a76b08b
--- /dev/null
+++ b/build_complete.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+cd website-emu || exit
+wasm-pack build --target web
+cd ../website-kernel || exit
+make all
+cd .. || exit
+mv website-emu/pkg/website_emu.js website-src/website_emu.js
+mv website-emu/pkg/website_emu_bg.wasm website-src/website_emu_bg.wasm
+[ -d "website-src/snippets" ] && rm -rf website-src/snippets
+mv website-emu/pkg/snippets website-src/snippets
+mv website-kernel/Image.bin website-src/vmwebkrnl.bin \ No newline at end of file
diff --git a/cleanup_artifacts.sh b/cleanup_artifacts.sh
new file mode 100755
index 0000000..73d6efa
--- /dev/null
+++ b/cleanup_artifacts.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+[ -d website-emu/pkg ] && rm -rf website-emu/pkg
+cd website-kernel || exit
+make clean
+cd .. || exit
+[ -d website-src/snippets ] && rm -rf website-src/snippets
+[ -f website-src/vmwebkrnl.bin ] && rm -f website-src/vmwebkrnl.bin
+[ -f website-src/website_emu.js ] && rm -f website-src/website_emu.js
+[ -f website-src/website_emu_bg.wasm ] && rm -f website-src/website_emu_bg.wasm
diff --git a/website-emu/src/dev.js b/website-emu/src/dev.js
new file mode 100644
index 0000000..4a22523
--- /dev/null
+++ b/website-emu/src/dev.js
@@ -0,0 +1,6 @@
+export function uart_push_line(line) {
+ const elem = document.createElement("span");
+ elem.classList.add("uart_line");
+ elem.textContent = line;
+ document.body.appendChild(elem);
+} \ No newline at end of file
diff --git a/website-emu/src/lib.rs b/website-emu/src/lib.rs
index ffaa677..b29c901 100644
--- a/website-emu/src/lib.rs
+++ b/website-emu/src/lib.rs
@@ -16,20 +16,20 @@ const CONSOLE_LOAD: u32 = 0x70000000;
const INITRD_LOAD: u32 = 0;
-#[wasm_bindgen]
+#[wasm_bindgen(module = "/src/dev.js")]
extern "C" {
- #[wasm_bindgen(js_namespace = console)]
- fn log(s: &str);
+ fn uart_push_line(line: &str);
}
pub struct Uart {
pub addr: u32,
- pub value: u8
+ pub value: u8,
+ acc: String
}
impl MemoryDevice for Uart {
fn read(&self, address: u32) -> Result<u8, ()> {
- if (address == self.addr) {
+ if address == self.addr {
Ok(self.value)
} else {
Err(())
@@ -37,8 +37,15 @@ impl MemoryDevice for Uart {
}
fn write(&mut self, address: u32, value: u8) -> Result<(), ()> {
- if (address == self.addr) {
+ if address == self.addr {
self.value = value;
+
+ if self.value as char == '\n' {
+ uart_push_line(self.acc.as_str());
+ self.acc = String::new();
+ } else {
+ self.acc.push(self.value as char);
+ }
Ok(())
} else {
Err(())
@@ -76,7 +83,8 @@ pub fn boot(image: &[u8], initrd: &[u8], memory: &[u8]) {
let uart = Uart {
addr: CONSOLE_LOAD,
- value: 0
+ value: 0,
+ acc: "".to_string(),
};
cpu_memory.register_device(
@@ -102,7 +110,7 @@ pub fn boot(image: &[u8], initrd: &[u8], memory: &[u8]) {
state.registers[10] = 0;
state.registers[2] = DRAM_LOAD + memory_len as u32;
- loop {
+ while state.on {
{
handle_instruction(&mut state);
state.registers[0] = 0;
@@ -278,7 +286,8 @@ fn handle_instruction(state: &mut CpuState) {
0 => trap_to_kernel(state), // ecall
258 => return_to_userspace(state), // sret
261 => {
- println!("wfi");
+ state.on = false;
+ return;
}
_ => panic!("Illegal instruction: {:x}", word),
}
diff --git a/website-emu/src/state.rs b/website-emu/src/state.rs
index f26167f..4b32713 100644
--- a/website-emu/src/state.rs
+++ b/website-emu/src/state.rs
@@ -5,6 +5,7 @@ pub struct CpuState {
pub registers: [u32; 32],
pub csr: [u32; 4096],
pub pc: u32,
+ pub on: bool
}
impl CpuState {
@@ -13,7 +14,8 @@ impl CpuState {
memory,
registers: [0u32; 32],
csr: [0u32; 4096],
- pc: 0
+ pc: 0,
+ on: true
}
}
}
diff --git a/website-kernel/Makefile b/website-kernel/Makefile
index eb5a76e..01f259c 100644
--- a/website-kernel/Makefile
+++ b/website-kernel/Makefile
@@ -5,6 +5,7 @@ OBJCOPY = llvm-objcopy
COMPILER = $(shell $(CC) --version | head -n 1)
LINKER = $(shell $(LD) --version | head -n 1)
ARCH_NAME = 32-bit RISC-V, IM_Zicsr ISA, little endian, unknown ELF, System V ABI
+VERSION = 0.1.0-alpha
CFLAGS = \
--target=riscv32-unknown-elf \
@@ -60,7 +61,7 @@ $(KERNEL_ELF): $(ALL_OBJECTS) $(LINKER_SCRIPT)
$(LD) $(LD_FLAGS) -o $@ $(ALL_OBJECTS)
$(KERNEL_BINARY): $(KERNEL_ELF)
@echo " OBJCOPY $@"
- $(OBJCOPY) $(OBJCOPY_FLAGS) $(KERNEL_ELF) $(KERNEL_BIN)
+ $(OBJCOPY) $(OBJCOPY_FLAGS) $(KERNEL_ELF) $(KERNEL_BINARY)
clean:
@echo " CLEAN $(ALL_OBJECTS)"
$(RM) $(ALL_OBJECTS)
diff --git a/website-kernel/arch/kernel.c b/website-kernel/arch/kernel.c
index 28c94d3..fe771ec 100644
--- a/website-kernel/arch/kernel.c
+++ b/website-kernel/arch/kernel.c
@@ -1,9 +1,15 @@
#include <int.h>
#include <log.h>
+#include <sys.h>
#define SERIAL_PORT 0x70000000
-void kernel_main(size_t hart) {
- (void)hart;
- printk("wkern version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME);
+void serial_write(char value) {
+ *(char *)SERIAL_PORT = value;
+}
+
+void kernel_main() {
+ register_console_callback(serial_write);
+
+ printk("webkernel version %s (Compiler %s, Linker %s) on %s\n", VERSION, COMPILER_NAME, LINKER_NAME, ARCH_NAME);
}
diff --git a/website-kernel/include/int.h b/website-kernel/include/int.h
index 2a378e7..754b43e 100644
--- a/website-kernel/include/int.h
+++ b/website-kernel/include/int.h
@@ -1,7 +1,8 @@
#pragma once
#define NULL (void*)0
-typedef __UINTPTR_TYPE__ size_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
diff --git a/website-kernel/include/sys.h b/website-kernel/include/sys.h
new file mode 100644
index 0000000..1aa4a03
--- /dev/null
+++ b/website-kernel/include/sys.h
@@ -0,0 +1,16 @@
+#pragma once
+#include <int.h>
+
+typedef uint8_t device_type_t;
+
+struct boot_args {
+ char *cmd_line;
+ struct device *devices;
+};
+
+struct device {
+ device_type_t device_type;
+ uintptr_t start;
+ size_t size;
+ struct device *next;
+};
diff --git a/website-src/index.html b/website-src/index.html
new file mode 100644
index 0000000..7fa24ee
--- /dev/null
+++ b/website-src/index.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Website</title>
+ <link rel="stylesheet" href="style.css" />
+ <script type="module" src="../website-emu/src/dev.js"></script>
+ <script type="module" defer>
+ import init, { boot } from './website_emu.js';
+ async function run() {
+ await init();
+ const response = await fetch('/vmwebkrnl.bin');
+ if (!response.ok) {
+ console.log("OS image not present, not booting.");
+ return;
+ }
+
+ const vmwebkrnl = new Uint8Array(await response.arrayBuffer());
+ const initrd = new Uint8Array(8);
+ const dram = new Uint8Array(1024 * 1024);
+
+ boot(vmwebkrnl, initrd, dram);
+ }
+ run();
+ </script>
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file
diff --git a/website-src/style.css b/website-src/style.css
new file mode 100644
index 0000000..cc43cde
--- /dev/null
+++ b/website-src/style.css
@@ -0,0 +1,51 @@
+/* Monitor container styling */
+body {
+ margin: 0;
+ padding: 0;
+ background: #1a1a1a;
+ min-height: 100vh;
+ font-family: 'Courier New', Courier, monospace;
+}
+
+/* The individual text lines */
+.uart_line {
+ display: block;
+ color: white;
+ font-family: 'Courier New', Courier, monospace;
+ font-size: 16px;
+ line-height: 1.4;
+ white-space: pre-wrap;
+ word-break: break-word;
+ margin: 0;
+ padding: 0 4px;
+}
+
+.uart_line:last-child::after {
+ content: "▊";
+ margin-left: 4px;
+ animation: blink 1s step-end infinite;
+ color: white;
+}
+
+@keyframes blink {
+ 0%, 50% { opacity: 1; }
+ 50.01%, 100% { opacity: 0; }
+}
+
+/* Scrollbar styling */
+.screen::-webkit-scrollbar {
+ width: 8px;
+}
+
+.screen::-webkit-scrollbar-track {
+ background: #0a0a0a;
+}
+
+.screen::-webkit-scrollbar-thumb {
+ background: #1f4d2b;
+ border-radius: 4px;
+}
+
+.screen::-webkit-scrollbar-thumb:hover {
+ background: #2a6b3a;
+} \ No newline at end of file