Hardware target.
Bare metal WebNux.
WebNux 1.2.0 runs on 10 hardware CPU architectures plus the browser. Flash a kernel image to real hardware and boot it directly — no OS underneath, no hypervisor. The same Webware architecture that powers the web kernel also drives bare-metal machines.
Flashing & Boot
Choose the right method for your hardware:
BOOTX64.EFI (or BOOTIA32.EFI) to the /EFI/BOOT/ directory of your EFI partition. Most UEFI firmware will detect and boot it automatically.fastboot boot kernel.img. For permanent flash: fastboot flash boot kernel.img. Requires an unlocked bootloader.BOOTAA64.EFI on UEFI-capable ARM64 boards. For U-Boot: fatload mmc 0 $loadaddr kernel.img && bootm $loadaddr.build_riscv32.sh), then load via U-Boot. All 32-bit targets require the corresponding cross toolchain.# x86_64 UEFI cp BOOTX64.EFI /boot/EFI/BOOT/BOOTX64.EFI # ARM32 Android (fastboot) fastboot boot kernel.img # RISC-V 32 — build then U-Boot ./build_riscv32.sh # then in U-Boot: fatload mmc 0 0x80000000 kernel-riscv32.img bootm 0x80000000
Hardware Drivers
WebNux 1.2.0 includes the following hardware drivers. All drivers include x86-specific inline assembly guards so the kernel builds cleanly on every architecture.
| Driver | Category | Architectures |
|---|---|---|
| AHCI | Storage (SATA) | x86, x86_64 |
| ATA / IDE | Storage (legacy) | x86, x86_64 |
| NVMe | Storage (PCIe) | x86_64, ARM64 |
| SD card | Storage | ARM32, ARM64, RISC-V |
| e1000 | Network (Intel) | x86, x86_64 |
| RTL8139 | Network (Realtek) | x86, x86_64 |
| VirtIO-net | Network (VM) | All |
| Bluetooth | Wireless | ARM32, ARM64, x86_64 |
| WiFi | Wireless | ARM32, ARM64, x86_64 |
| NFC | Wireless (short range) | ARM32, ARM64 |
| VGA/Framebuffer | Display | x86, x86_64 |
| UART / PL011 | Serial | All (arch-specific) |
Architecture-specific code
Some subsystems have architecture-specific implementations:
| Architecture | Specific subsystems |
|---|---|
| x86 / x86_64 | IDT, PIC, PIT, keyboard, CPUID, RTC, TSS, ring3 page tables, fast syscalls (SYSENTER/SYSCALL) |
| ARM32 | Device tree parsing, PL011 UART, ARM timer, AEABI division helpers |
| ARM64 | PSCI power management, GIC interrupt controller, Device tree |
| RISC-V | SBI interface, PLIC interrupt controller, CLINT timer |
| MIPS | CP0 coprocessor, TLB management, MIPS exception vectors |
| PowerPC | Open Firmware device tree, PowerPC exception vectors, BAT registers |
Filesystems
WebNux includes a VFS layer with two filesystem implementations:
| Filesystem | Notes |
|---|---|
| FAT32 | Read/write. Used for EFI system partitions and removable media. |
| EXT2 | Read/write. Linux-compatible. Used for root and data partitions. |
| VFS layer | Abstraction over both filesystems. Uniform API for path-based I/O. |
kernel-os.js
Full WebNux kernel.
The default kernel — all subsystems merged into one file. Boots with a black screen, initialises every layer (PMM, VMM, BSD sockets, SysV IPC, capabilities, ELF loader, kprobes, /proc, ACPI, cpufreq, KMod), then fires onReady(). Exposes both WebOSKernel and the unified WebNux namespace.
Getting started
Drop in the script tag and call onReady(). The kernel handles its own boot sequence.
<script src="https://webnux.pages.dev/kernel-os.js"></script> <script> WebOSKernel.onReady(kernel => { // your OS starts here document.body.innerHTML = '<div id="desktop"></div>'; }); </script>
App Store
Register apps with kernel.appStore.register(meta). Apps with store: true are persisted and visible to any WebOS running the same kernel version.
WebOSKernel.onReady(kernel => { kernel.appStore.register({ id: 'com.example.notes', name: 'Notes', version: '1.0.0', kernelVersion: '1.2.0', store: true, sourceCode: '<h1>My Notes App</h1>', }); const apps = kernel.appStore.list(); });
Cloud
Firebase connects lazily — no overhead unless you use it. loadApps() fetches the apps Firestore collection and auto-registers everything.
WebOSKernel.onReady(async kernel => { await kernel.cloud.loadApps(); const data = await kernel.cloud.fetch('settings'); const app = await kernel.cloud.getApp('com.example.notes'); });
Launching apps
kernel.launch(appId) checks the local AppStore, falls back to Firebase, builds a sandboxed iframe, and returns it ready to place in your OS UI.
WebOSKernel.onReady(async kernel => { const iframe = await kernel.launch('com.example.notes'); document.getElementById('window-container').appendChild(iframe); kernel.events.on('app:ready', ({ name }) => { console.log(name, 'is live'); }); });
Events
| Event | Payload | When |
|---|---|---|
| kernel:booting | { version } | Boot sequence starts |
| kernel:ready | { version } | Boot complete, onReady() fires |
| cloud:connected | — | Firebase first connected |
| cloud:apps:loaded | { count } | loadApps() finished |
| app:ready | { id, name, iframe } | launch() iframe loaded |
| app:error | { id, error } | launch() failed |
| appstore:registered | { id, name } | App registered |
| service:registered | { name } | Service registered |
API reference
| Method | Description |
|---|---|
| kernel.onReady(cb) | Register a boot callback. Safe to call before or after boot. |
| kernel.launch(appId) | Full app pipeline. Returns a sandboxed HTMLIFrameElement. |
| kernel.register(name, svc) | Register a named service. |
| kernel.resolve(name) | Get a registered service. Throws WK_E005 if not found. |
| kernel.use(fn) | Add middleware to the request pipeline. |
| kernel.plugin({ name, install }) | Install a plugin. |
| kernel.handle(method, url) | Dispatch through the router. |
| kernel.uptime() | Seconds since boot. |
| kernel.appStore.register(meta) | Register an app locally. |
| kernel.appStore.list() | All registered apps. |
| kernel.cloud.loadApps() | Fetch & register cloud apps from Firestore. |
| kernel.cloud.fetch(collection) | Fetch all docs from a Firestore collection. |
| kernel.events.on(event, fn) | Subscribe to a kernel event. |
| kernel.events.emit(event, data) | Emit a custom event. |
| kernel.router.get/post/put/delete(path, fn) | Register a route handler. |
kernel-sms.js
Messaging kernel.
Trimmed for conversation-driven WebOSes. No AppStore, no launch(). Adds cloud.send() for writing messages to Firestore and cloud.subscribe() for real-time updates.
Getting started
<script src="https://webnux.pages.dev/kernel-sms.js"></script> <script> WebOSKernel.onReady(kernel => { // your messaging OS starts here }); </script>
Sending messages
kernel.cloud.send(collection, message) writes to Firestore with a server timestamp. Returns the new document ID.
const id = await kernel.cloud.send('messages', { from: 'alice', text: 'Hello!', channel: 'general', });
Real-time updates
kernel.cloud.subscribe(collection, cb) opens a Firestore onSnapshot listener. Returns an unsubscribe function.
const unsub = await kernel.cloud.subscribe('messages', messages => { renderMessages(messages); }); // call unsub() to stop listening
API reference
| Method | Description |
|---|---|
| kernel.cloud.send(collection, msg) | Write a message to Firestore. Returns new doc ID. |
| kernel.cloud.subscribe(collection, cb) | Real-time listener. Returns unsubscribe function. |
| kernel.cloud.fetch(collection) | One-time fetch of all docs. |
| kernel.events.on('cloud:messages:updated', fn) | Fires every time the snapshot updates. |
kernel-tools.js
Headless kernel.
No UI, no boot screen, no app launching. Boots instantly and registers four built-in tool services: dev:console, dev:inspector, util:calc, and util:notes.
Getting started
<script src="https://webnux.pages.dev/kernel-tools.js"></script> <script> WebOSKernel.onReady(kernel => { const con = kernel.resolve('dev:console'); const cal = kernel.resolve('util:calc'); }); </script>
dev:console
Intercepts console.log/warn/error/info/debug from the moment the kernel loads. Build a visible log panel in your UI.
con.history(); // all captured entries con.tail(50); // last 50 entries con.filter('error'); // only errors con.clear(); // wipe history
dev:inspector
Dumps a snapshot of kernel state — uptime, services, plugins, routes, heap memory.
const snap = ins.snapshot(); // { version, mode, uptime, services, memoryMB, … } ins.print(); // logs formatted snapshot to console
util:calc
Safe math expression evaluator. No arbitrary code execution — strips anything non-numeric before evaluating.
cal.evaluate('2 + 2'); // 4 cal.evaluate('(10 * 3) / 2'); // 15 cal.evaluate('100 % 7'); // 2
util:notes
In-memory key/value note store. Session-only — wire your own persistence if needed.
nts.set('todo', 'Fix the kernel'); nts.get('todo'); // { id, content, updatedAt } nts.list(); // all notes nts.search('kernel'); // notes matching substring nts.delete('todo');
Auth kernels.
Login-gated WebOS.
Modes 4 and 5 are identical to Modes 1 and 2 — same API, same events — with one addition: the kernel holds the boot sequence behind a login screen until the user authenticates via Firebase Auth. onReady() only fires after a successful sign-in.
WebOSKernel.onReady(async kernel => { // user is guaranteed to be signed in here console.log(kernel.auth.currentUser.email); await kernel.auth.signOut(); // returns to login on next load });
WebNux
The unified kernel namespace.
kernel-os.js exposes a second global — WebNux — that wraps every subsystem into a clean, namespaced API. Both globals point at the same kernel instance.
WebNux.onReady(nx => { console.log(nx.version); // '1.2.0' console.log(nx.history); // ['Web Kernel', 'WebNix', 'WebNux'] console.log(nx.manifest()); // full boot report });
WebNux.mm — Memory
Physical memory manager (buddy allocator), SLUB allocator, and virtual memory maps. Page size: 4 KiB. Orders follow the buddy system (order 0 = 4 KiB, order 9 = 2 MiB huge page).
| Method | Description |
|---|---|
| nx.mm.alloc(order) | Allocate 2order contiguous pages. Returns PFN or -1 on OOM. |
| nx.mm.free(pfn, order) | Return a buddy block. Coalesces with buddy if both free. |
| nx.mm.stats() | totalMB, freeMB, usedMB, fragmentation score. |
| nx.mm.kmalloc(size) | SLUB: allocate slab object. Returns handle. |
| nx.mm.kfree(ptr) | Return slab object to its cache. |
| nx.mm.allocHuge() | Allocate a 2 MiB huge page (order-9). |
| nx.mm.freeHuge(pfn) | Return a huge page. |
| nx.mm.createMap(pid) | Create a new per-process virtual memory map. |
WebNux.proc — Processes
Spawn tasks, fork processes, create threads, run ELF or JS-native executables. Each task gets a PID, memory map, and capability set.
| Method | Description |
|---|---|
| nx.proc.spawn(opts) | Create a new task. opts: { name, ppid, type }. Returns Task. |
| nx.proc.fork(pid, name) | Fork with copy-on-write memory. Returns child Task. |
| nx.proc.thread(tgid, name) | Spawn a thread inside an existing thread group. |
| nx.proc.execve(path, fn, argv, envp) | Run a JS-native or ELF executable. Returns PID. |
| nx.proc.exit(pid, code) | Mark task as zombie with exit code. |
| nx.proc.reap(pid) | Release zombie task resources. |
| nx.proc.list() | All running tasks. |
WebNux.net — Networking
BSD socket API over simulated IPv4 / TCP / UDP. Loopback delivery works — packets sent to a local port land in the peer socket's receive queue.
| Method | Description |
|---|---|
| nx.net.socket(family, type) | Create a socket. Returns file descriptor. |
| nx.net.bind(fd, addr, port) | Bind to local address and port. |
| nx.net.listen(fd) | Mark as passive (server). |
| nx.net.connect(fd, addr, port) | Connect to remote. Simulates SYN handshake. |
| nx.net.accept(fd) | Promise → connected client fd. |
| nx.net.send(fd, data) | Send data on TCP socket. |
| nx.net.recv(fd, len) | Promise → Uint8Array up to len bytes. |
| nx.net.sendto(fd, data, addr, port) | Send UDP datagram. |
| nx.net.close(fd) | Close socket. Sends FIN for TCP. |
| nx.net.netstat() | All open sockets with state and byte counts. |
| nx.net.ifconfig() | Network interfaces: lo, eth0, wlan0. |
| nx.net.routes() | IPv4 routing table. |
WebNux.ipc — IPC
SysV message queues, semaphores, shared memory, and kernel ring-buffer pipes.
| Method | Description |
|---|---|
| nx.ipc.pipe() | Create a ring-buffer pipe. Returns pipe ID. |
| nx.ipc.msgget(key) | Create/attach SysV message queue. |
| nx.ipc.msgsnd(key, mtype, data) | Send typed message to queue. |
| nx.ipc.msgrcv(key, mtype, maxLen) | Receive message. Promise → { mtype, data }. |
| nx.ipc.semget(key, nsems) | Create semaphore set. |
| nx.ipc.semop(key, semnum, op) | Atomically modify semaphore. |
| nx.ipc.shmget(key, size) | Create shared memory segment. |
| nx.ipc.shmat(key) | Attach to shm. Returns Uint8Array view. |
| nx.ipc.ipcs() | List all active queues, semaphores, shm segments. |
WebNux.sec — Security
Linux capability model (41 caps), user/group database, SENux MAC, and seccomp.
| Method | Description |
|---|---|
| nx.sec.CAP | Capability name → number map. e.g. CAP.NET_ADMIN = 12. |
| nx.sec.hasCap(pid, cap) | true if process has capability in effective set. |
| nx.sec.requireCap(pid, cap) | Throws "Operation not permitted" if cap missing. |
| nx.sec.getpwnam(name) | Look up user by name. |
| nx.sec.useradd(opts) | Add user to database. Returns uid. |
| nx.sec.passwd() | /etc/passwd formatted string. |
WebNux.power — Power & CPU
ACPI power states and CPU frequency scaling. ACPI is wired to the browser's Page Visibility API — automatically emits S3 on tab switch and S0 on return.
| Method | Description |
|---|---|
| nx.power.state() | Current ACPI state: S0, S1, S3, S4, S5, or G3. |
| nx.power.sleep(state) | Transition to power state. Returns Promise. |
| nx.power.wake() | Force transition back to S0. |
| nx.power.cpuMHz() | Current CPU frequency in MHz. |
| nx.power.governor() | Active cpufreq governor name. |
| nx.power.setGovernor(name) | Switch governor: performance, powersave, ondemand, schedutil… |
WebNux.mod — Kernel Modules
Load and unload kernel modules at runtime. A module is a plain JS object with name, init(kernel), and optionally exit(kernel).
const myMod = { name: 'hello_world', version: '1.0.0', license: 'GPL', init(k) { k.events.emit('hello:loaded', {}); }, exit(k) { console.log('unloaded'); }, }; nx.mod.insmod(myMod); // load nx.mod.lsmod(); // list all nx.mod.rmmod('hello_world'); // unload
WebNux.fs — Filesystem
Access the live /proc virtual filesystem, block devices, VFS, and OPFS persistent storage.
| Method | Description |
|---|---|
| nx.fs.procRead(path) | Read a live /proc file. e.g. /proc/meminfo, /proc/1/maps. |
| nx.fs.procLs(dir) | List all /proc paths under a prefix. |
| nx.fs.vfs() | Returns the VirtualFileSystem instance (FAT32 + EXT2 on hardware). |
| nx.fs.opfs() | OPFS subsystem for browser persistent storage. |
| nx.fs.bdev(name) | Get block device by name (e.g. 'vda'). |
| nx.fs.bdevList() | All registered block devices. |
| nx.fs.bdevCreate(name, sizeMB) | Create an in-memory block device. |
nx.fs.procRead('/proc/meminfo') recomputes on every call — always reflects current PMM state. Same for /proc/cpuinfo, /proc/uptime, and all live entries.