mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
a0cd95cdc948d2c17c485a9a0b38642e7b3fd3c8
95
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a0cd95cdc9 |
docs: add Contributing, Security, and Roadmap docs; link them from the README
Create docs/CONTRIBUTING.md (build/verify workflow, coding style, kernel gotchas, commit & PR conventions), docs/SECURITY.md (supported versions, private vulnerability reporting, documented caveats), and docs/ROADMAP.md (shipped in v1.0.0 plus near/mid/long-term plans). Add a Documentation and Contributing section to the README pointing at all four docs. Note: used the conventional CONTRIBUTING.md / SECURITY.md filenames (in docs/) so GitHub auto-detects them as community-health files. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
bc4e19bb37 |
build: add Linux-style version/codename block to the Makefile
Mirror the Linux kernel Makefile header: VERSION / PATCHLEVEL / SUBLEVEL / EXTRAVERSION / NAME at the top, where NAME carries the release codename (Titan). Resolves to 1.0.0-stable, kept in sync with include/init/version.h. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
8023338df2 |
release(v1.0.0): first stable SUB-OS -- logo in README, graduate 0.2.0-lts to 1.0.0-stable
Promote SUB-OS out of alpha/beta to its first stable milestone. Bump version.h to 1.0.0 with the "1.0.0-stable" banner string across every arch target (codename Titan). Drop the ASCII wordmark from the README in favour of the official circular SUB-OS logo image, and update the version and release badges plus the Official Release link to v1.0.0. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXXv1.0.0 |
||
|
|
cf7bf59481 |
feat(brand): official SUB-OS logo -- add "OS" to the dragon mark
Take the circular SUB dragon logo and lock up an "OS" wordmark beneath the "SUB" letters, in the dragon's accent blue (#08B3FA) with the same oblique cut and black keyline, so the mark reads "SUB-OS" as one unit. Store the artwork in assets/ as the canonical source and regenerate the boot splash asset (init/logo_data.c) from it; the "OS" stays legible at the 160x160 boot resolution. Point mklogo.py's example at the new source. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
db962de248 |
feat(lib): baseline JPEG decoder -- the browser shows photos
Adds a from-scratch baseline JPEG decoder (ITU-T T.81, SOF0 sequential DCT), so the Web app now displays the web's dominant photo format alongside PNG and BMP. image_decode dispatches on the JPEG magic, so the browser needs no change beyond that. lib/jpeg.c handles grayscale and YCbCr, arbitrary chroma subsampling (4:4:4/4:2:2/4:2:0), restart markers, and multiple DQT/DHT tables. Huffman uses canonical tables (counts + symbols, like the inflate decoder) to avoid a large fast-table; the transform is the standard fixed-point integer row/column IDCT; colour is integer YCbCr->RGB. All heap-allocated, no floating point, so it is safe in the freestanding kernel. Progressive (SOF2) and arithmetic-coded JPEGs are rejected rather than mis-decoded. Verified on the host against PIL-encoded references before going in the kernel, the same way the crypto and PNG decoders were: grayscale decodes at mean absolute error 0.9/channel, 4:4:4 at 1.7 (pure IDCT rounding vs libjpeg), and 4:2:0 at 4.3 (nearest-neighbour chroma upsampling softens colour edges -- a known, visually-fine artifact). In QEMU the Web app fetched a 400x260 JPEG over HTTP and rendered it correctly -- gradient, an antialiased red circle, a green box, a yellow diagonal. Builds clean on x86_64, aarch64 and armv8i. Limits: baseline only (no progressive), and chroma upsampling is nearest-neighbour rather than the smoother interpolation libjpeg uses. The browser still shows images by URL, not inline in a page. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
fe33ddc79b |
feat(lib,gui): the browser shows images -- a PNG/BMP decoder, DEFLATE and all
The Web app could only render text. Now it decodes and displays images, so a
picture on the web actually shows up.
- lib/inflate.c DEFLATE / zlib decompressor (RFC 1950/1951): the algorithm
every PNG needs. Canonical Huffman, all three block types,
decodes into a caller buffer -- no allocation, integer only.
- lib/image.c PNG decoder (8-bit RGB/RGBA/grayscale/gray+alpha, and
1/2/4/8-bit grayscale & palette, non-interlaced; tRNS
transparency) plus BMP (24/32-bit). Parses chunks,
inflates IDAT, undoes the five scanline filters, and expands
to a flat 0xAARRGGBB buffer ready for gui_gfx_blit. A pixel
cap guards the heap.
- Web app: if a response body sniffs as an image it is decoded once and drawn
instead of text -- scaled to fit the panel width, vertically scrollable,
alpha-composited over the background. The per-fetch cap grew to 128 KB so
real images and longer pages fit.
Both decoders were verified on the host against generated references before
going in the kernel: inflate round-trips six zlib/raw streams (empty, back-
references, dynamic Huffman, stored blocks, 20 KB random, mixed); the image
decoder reproduces PIL-made PNGs of every supported colour type -- grayscale,
RGB, RGBA, 4-bit palette, gray+alpha -- and a BMP, with exact pixel matches.
In QEMU the Web app fetched a 360x240 PNG over HTTP and rendered it perfectly:
gradient, an antialiased red circle, a green box, a yellow diagonal, shown as
"image 360x240". Builds clean on x86_64, aarch64 and armv8i.
Still image-by-URL, not inline <img> within a page (that needs sub-resource
fetching and layout); and no JPEG/GIF (different codecs). PNG and BMP cover a
large share of the web's images.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
8a55ac345b |
feat(crypto,net): TLS 1.3 client -- SUB-OS can now browse HTTPS sites
The browser could only reach plain HTTP, which is almost none of the real
web. This adds a from-scratch TLS 1.3 client so it can fetch https:// pages,
including real sites on the open internet.
Crypto primitives (all integer-only, freestanding, verified on the host
against their RFC test vectors before going in the kernel):
- crypto/x25519.c X25519 ECDH (RFC 7748), compact TweetNaCl field
arithmetic.
- crypto/chacha20poly1305.c ChaCha20 + Poly1305 AEAD (RFC 8439).
- crypto/hkdf.c HMAC-SHA256, HKDF (RFC 2104/5869) and the TLS 1.3
HKDF-Expand-Label / Derive-Secret helpers, on top
of the existing SHA-256.
A host harness checked every one against its published vectors (X25519 s6.1,
ChaCha20 s2.4.2, AEAD s2.8.2 incl. tamper rejection, HKDF TC1) -- all pass.
TLS 1.3 client (net/tls.c), single suite TLS_CHACHA20_POLY1305_SHA256 over
X25519: ClientHello (with SNI and ALPN http/1.1) -> ServerHello -> the RFC 8446
key schedule over a running transcript hash -> decrypt the server flight ->
send Finished -> switch to application keys. A small record layer handles the
plaintext-then-AEAD split and the middlebox ChangeCipherSpec. All large buffers
live in the heap-allocated connection, never on the 16 KB worker stack.
http_client routes https:// through TLS instead of raw TCP, so the async
worker, webget, netcheck and the GUI Web app all get HTTPS for free; the
redirect follower now follows http->https upgrades. The Web app's default page
is now https://example.com/.
Verified end to end on x86_64: the handshake interoperates with openssl
s_server (TLS 1.3, ChaCha20) -- GET returned HTTP 200 with the decrypted body
-- and, over QEMU's NAT, `webget https://example.com/` and the GUI Web app both
loaded the real Example Domain page served by Cloudflare over TLS 1.3 (HTTP
200, 828 bytes). The server only accepts our Finished if the transcript hash
and key schedule match byte-for-byte, so a 200 is proof the whole stack is
correct. Builds clean on x86_64, aarch64 and armv8i.
SECURITY CAVEAT, stated plainly: the server certificate is NOT verified. The
channel is encrypted and interoperates, but a man-in-the-middle could
impersonate the peer. Real certificate-chain validation (X.509 parsing,
signature checks, a CA bundle, hostname matching) is a large separate piece and
is not built here. This is fine for a hobby OS over a trusted local NAT; it is
not fit to protect real secrets. Also: TLS 1.3 only, one cipher suite, and
still no JavaScript/media -- so JS-heavy or app-style sites (YouTube) remain
out of reach; this makes static/text HTTPS pages readable.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
9f90361265 |
feat(gui): make the Web app a real browser -- clickable links, history, relative URLs
The Web app fetched and rendered pages but could not browse between them.
Now it does. In Reader view, anchors are parsed as the markup is stripped and
recorded as links spanning the text they enclose; those spans render in the
accent colour with an underline, and a click on one follows it.
- Link capture: html_to_text now tracks <a href> open/close, storing each
link's [start,end) span in the processed text plus its href in a per-page
string pool. Rendering overlays link spans in accent + underline; a body
click maps pixel -> line -> text offset -> containing link.
- Relative resolution: a link's href is resolved against the page's own
address (captured from the fetch's final host/port/path). Root-relative
(/path), document-relative (page.html) and absolute URLs all work; the
default port is omitted from the rebuilt URL. mailto:/javascript:/#frag
are treated as non-navigable.
- History: a back stack (depth 16) records each address before navigating; a
Back button, lit only when there is somewhere to return to, pops it.
- https:// links resolve through and are refused by the fetch layer with the
existing clear message rather than being silently dropped.
Verified on x86_64 with real synthetic clicks against a small multi-page HTTP
site: the home page rendered its two links highlighted; clicking "Go to Page
Two" navigated (URL bar updated to the resolved http://host/page2.html, host
logged GET /page2.html) and Page Two rendered with its own links; the Back
button returned to the home page (host logged GET /). Builds clean on x86_64,
aarch64 and armv8i.
Known limit: no TLS, so https:// pages are reported not shown -- plain HTTP
browsing only.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
f6e4511047 |
feat(net,gui): real internet access -- redirects, HTTPS guard, netcheck, and a live ONLINE indicator
The stack could already reach the real internet once the UDP-checksum and
scheduler fixes landed; this makes it work on real-world URLs and gives the
desktop a first-class "is the internet up?" answer.
HTTP client
- Follows 3xx redirects (Location header, absolute or relative) up to five
hops, so a bare host that 301s to a path or a canonical host resolves to
actual content. Verified: `webget google.com/` follows the 301 to
www.google.com and returns its HTTP 200 homepage.
- Refuses https:// targets -- at the initial URL and on redirect -- with a
clear message instead of speaking plaintext to port 443 and timing out.
- Split the URL parser out so both the initial request and redirect targets
go through the same path; added a case-insensitive header finder.
netcheck (CLI)
One command that walks the whole chain -- link, address, gateway ping, DNS,
and a real HTTP fetch -- and reports each PASS/FAIL, ending in ONLINE or
DEGRADED. The one-shot answer to "is the internet working?".
Network Monitor (GUI)
A live Internet: ONLINE/OFFLINE badge with the resolved IP, HTTP status and
latency. It auto-probes once on open and re-checks on the Check button, all
through the async HTTP worker so the window never blocks.
Verified against the real internet through QEMU's NAT: DNS resolved
example.com to a live Cloudflare address; `netcheck` passed all five layers
(Internet: ONLINE); the GUI badge showed "ONLINE 104.20.23.154 HTTP 200 240
ms"; redirect following and the HTTPS refusal both behaved. Builds clean on
x86_64, aarch64 and armv8i.
Known limit: no TLS, so HTTPS URLs are reported rather than fetched -- plain
HTTP only.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
dd4922767a |
feat(net,gui,sched): async HTTP client + Web browser app, and the scheduler fix that makes background work possible
The visible goal was a Web app: type a URL, see the page, fetched over the TCP stack SUB-OS built. Getting there surfaced -- and forced fixes to -- two deeper problems. Async HTTP client (net/http_client.c) tcp_connect/recv all block, so fetching from the GUI would freeze the compositor. Fetches now run on one long-lived kernel worker thread that services a single-slot mailbox; the requester posts a job and polls its state. Ownership follows the state, and the two hand-off points (worker completion, requester release) run under interrupts-off, so a window can close mid-fetch with neither leak nor use-after-free. do_fetch returns its terminal state rather than publishing it, closing a window where the requester could free the job before finalize read it. Cooperative scheduling for the idle thread (the core fix) The login prompt, the shell and the GUI compositor all run on the pid-0 idle thread, which the scheduler by design never preempts (sched_tick skips pid 0) and never requeues on a yield (weave_on clear). So it could neither be preempted to let the worker run, nor cleanly yield -- the worker was simply starved, and an early attempt to yield from it froze the shell outright. The idle thread now joins the weave rotation once hardware interrupts are live, and the network wait loops (tcp, dns, ping, the worker's idle) yield through a new net_wait() instead of halting the CPU. The compositor spends its frame-budget slack yielding too. Result: a background fetch progresses while the desktop holds 54 FPS. Web app (gui/gui_app_web.c) A text browser: URL bar, Go, and a Raw/Reader toggle. Raw shows the response verbatim; Reader strips markup (dropping <script>/<style> bodies), decodes the common entities, and word-wraps the body. The line index is cached against content/view/width so scrolling and idle repaints are free. It only ever polls the worker, so it never stalls. TCP throughput (the limit flagged last time) The 32-slot table with a 2 s TIME_WAIT linger capped sustained serving at ~16 req/s. The table is now 64 slots, a connection this end closed after serving a request lingers 250 ms rather than 2 s, and expired TIME_WAIT entries are reaped from the count path so a quiet table still drains. netstat/netmon gained served-since-boot and peak-slots counters. Also: a `webget` CLI (the async client from a shell), listen/accept introspection already present, and a globe icon for the app. Verified on x86_64: `webget` fetched an 812-byte page (HTTP 200, 10 ms) on the worker thread; the GUI Web app rendered the same page in Reader mode while the desktop held 54 FPS; an 80-request burst through the 64-slot table returned 80/80 (was 39/40 before) and netstat reported "80 served, peak 33 of 64 slots" -- a peak that would have overflowed the old table. Builds clean on x86_64, aarch64 and armv8i. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
eb92502deb |
feat(net,gui): TCP listen/accept, and a Network Monitor to watch it
Kernel: the passive-open half of TCP. tcp_listen claims a port, inbound
SYNs to it are completed by the receive path, and the finished
connections queue in a backlog until tcp_accept collects them. Accepted
connections run the same stream state machine as active opens, so
tcp_send/tcp_recv/tcp_close work on them unchanged. sys_listen and
sys_accept expose this through the BSD socket API, with sys_accept
returning a fresh descriptor and leaving the listener available for the
next caller. The built-in sshd and httpd predate this and are still
answered inline from the receive path; the role they use is now named
TCP_ROLE_SERVICE to keep that distinction explicit.
GUI: a Network Monitor app. Interface configuration and link state, a
rolling dual-line chart of receive and transmit rates sampled from the
NIC counters on a fixed 2 Hz cadence (so it reads in packets per half
second no matter how often the compositor repaints), byte and packet
totals, and the TCP engine's connection table with each connection's real
state and direction, scrollable when it outgrows the window.
Two bugs the monitor made visible, both fixed:
- Served HTTP connections were never closed. The response advertises
"Connection: close" but the engine left the connection ESTABLISHED
forever, so the 32-entry table filled up and the server stopped
answering after 32 requests. The service path now sends its FIN after
the response and lingers in TIME_WAIT until the reaper takes it. 40
sequential requests through a 32-slot table now yield 39 successes
where the 33rd onwards previously failed permanently.
- tcp_close gave up in FIN_WAIT2 after 500 ms and freed the slot, so a
peer whose own FIN arrived later got an RST instead of an ACK. It now
falls into TIME_WAIT instead, and TIME_WAIT acknowledges a first FIN
rather than only a retransmitted one. Expired TIME_WAIT entries are
also reaped from tcp_get_connections_count, so a table that sees no
further connections still empties out.
Verified on x86_64 against real peers, checked packet by packet in a
capture: a host client connected to `tcpserve 9000` in the guest and got
its reply -- SYN/SYN-ACK/ACK with a random ISN, 30-byte request, 43-byte
reply, and a clean four-way close whose final ACK is correct even when
the peer's FIN arrives 1.2 s late. Zero bad checksums throughout. The
monitor was screenshotted under live load showing connections moving
through TIME_WAIT and being reclaimed. Builds clean on x86_64, aarch64
and armv8i.
Known limit: 32 connection slots with a 2 s TIME_WAIT linger means
sustained rates much above ~16 requests/second can transiently exhaust
the table; it recovers on its own as entries expire.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
65fc5535c8 |
feat(net): active-open TCP, and fix two bugs that broke TCP on the wire
Adds the client half of TCP -- tcp_connect/tcp_send/tcp_recv/tcp_close -- and wires SOCK_STREAM sockets to it, so the kernel can originate an outbound stream rather than only answer inbound ones. Inbound segments are now matched against the connection table before being offered to the listeners; previously anything not addressed to a listening port was answered with RST, which would have rejected the SYN-ACK completing our own handshake. Transmission is stop-and-wait: one segment outstanding, retransmitted until acknowledged. Every blocking call is bounded against the timer tick and halts the CPU between checks, so a silent peer costs a timeout rather than a hang. Connections linger in TIME_WAIT so a late duplicate cannot be mistaken for traffic on a new incarnation. Verifying it against a real peer uncovered two pre-existing bugs that had made TCP unusable in both directions. Neither was visible from inside the guest, which is why the servers had looked fine: 1. The TCP and UDP checksums were computed by reading the header a uint16_t at a time, immediately after the caller stored zero into that same header's checksum field. Nothing stops the compiler reordering those word reads around that store, and at -O2 it did: the stale checksum field was folded into its own result. Every TCP segment the kernel had ever sent carried a wrong checksum and was silently dropped by the peer -- no client could complete a handshake with sshd or httpd, and it is the likely reason DHCP and DNS replies never arrived. The checksum is now summed a byte at a time through unsigned char pointers, which may alias any object and so cannot be reordered, and which also drops the alignment assumption that reading a packed header as uint16_t made -- a fault rather than a slowdown on ARM. The helper is shared by IP, TCP and UDP instead of being open-coded four times. 2. net_receive derived the datagram length from the Ethernet frame rather than from the IP header's total_length, so the padding on any frame shorter than 60 bytes was delivered as protocol payload. A bare ACK or FIN appeared to carry six bytes, which pushed the acknowledgement number out of step with the peer and turned every close into a FIN retransmission storm answered with RST. Also adds `tcpconnect` and `httpget` applets, and gives netstat the real per-connection state and direction from the engine's table. Verified on x86_64 against a real TCP stack, checked packet by packet in a capture: `httpget` fetched a 349-byte page from a server on the host -- handshake, 81-byte request, response, orderly four-way close, every sequence number exact, zero bad checksums, no retransmissions. In the other direction curl on the host now fetches a live page from the guest's httpd, which had never worked. Builds clean on x86_64, aarch64 and armv8i. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
c9dfa6a1aa |
feat(gui): Sorry -- an apology app with a live parametric heart
A new desktop app whose whole point is to say sorry, and to look like
saying it took effort. Nothing in it is a static bitmap.
The heart is the classic parametric heart curve, x = 16sin^3(t) and
y = 13cos(t) - 5cos(2t) - 2cos(3t) - cos(4t), precomputed as a 96-point
integer polygon normalised to a half-width of 1000 and scanline-filled at
whatever size the beat currently has it at. Even-odd crossing counting is
what keeps the notch between the lobes open. The beat is a two-thump
cardiac envelope -- a strong systolic beat and a softer echo -- and the
fill carries a vertical gradient, a soft specular highlight on the upper
lobe, and a six-layer glow. The kernel is built -mno-sse with no floating
point, so every curve, gradient, easing and physics step is integer-only
and needs no trigonometry at runtime.
Around it: three apology letters that type themselves out a character at
a time, and a slow drift of small hearts using the same fill routine.
Answering "I forgive you" brightens the heart and bursts the drift
outward; answering "Not yet" dims it, slows the beat, and starts an
honest count of how long it has been waiting. Neither answer is an exit.
Supporting changes, all of them general rather than app-specific:
- gui_desktop_request_animation_frame(), so an app can opt into
full-rate recompositing instead of the ~10 Hz live-content
heartbeat. It is renewed per paint, so it lapses by itself when the
app stops animating or its window closes.
- gui_button_styled() and gui_hitzone() in SUB-WT, letting an app with
its own palette keep the toolkit's click handling. gui_button_colored
is now a thin wrapper over the former.
- A heart glyph in the icon set.
The glow layers skip whatever the heart body is about to cover, which
cuts their blended-pixel cost by roughly 3.5x and pays for the extra
layers that turn contour rings into a smooth halo.
Verified in QEMU on x86_64: all three states driven by real clicks --
hover, forgiveness (brighter heart, burst, live typewriter) and waiting
(dimmed heart, slower beat, running counter). Builds clean on x86_64,
aarch64 and armv8i.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
5bd18c4733 |
feat(cpp,gui): C++ Analytics Engine + live GUI Analytics app
Kernel (C++17 freestanding):
- New Analytics Engine (kernel/cpp/cpp_analytics.cpp): templated rolling
time-series (TimeSeries<N>) sampling four live channels -- CPU load %,
memory %, kernel-heap %, network pkt/interval -- with windowed statistics
(min/max/mean/stddev) computed in pure integer math (kernel is -mno-sse, so
no FP; stddev uses a Newton integer isqrt). Demonstrates virtual dispatch
via an Observer pattern (IAnalyticsObserver + a ThresholdAlarmObserver that
counts breaches) and RAII singletons.
- Extended cpp_containers.hpp with Optional<T>, Pair<A,B>, and the kmin/kmax/
kclamp/kswap algorithms.
- Full C fallback (cpp_fallback.c) so the engine is functionally identical on
aarch64/armv8i, which don't build the .cpp path.
- Wired cpp_analytics_init() into boot [8/14]; seeds a few samples so graphs
are populated immediately.
GUI:
- New "Analytics" desktop app (gui/gui_apps.c): a 2x2 grid of live line-charts
backed by the C++ engine, each with gridlines, a soft baseline fill, and
min/avg/max(/stddev) overlays; click a panel to focus one channel full-size,
click again to return. Throttled to ~2 Hz sampling off the compositor's
repaint cadence. Registered on the desktop and in the start menu.
Userland: new `cppstat [samples]` applet dumps the engine's per-channel stats
and Observer breach counters.
Verified in QEMU (x86_64): boots clean on x86_64/aarch64/armv8i; `cppstat`
prints live stats (CPU 6%, Mem 7%, Heap 22%, computed min/avg/max/stddev,
Observer breaches); the GUI Analytics window renders all four graphs with the
Kernel Heap curve visibly climbing 22->55% as windows open, compositor steady
at ~53 FPS.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
cd840d5799 |
feat(net): real UDP transport, BSD datagram sockets, DNS resolver, DHCP client
Turn the networking stubs into a working transport/application stack on top of
the existing L2/L3 (Ethernet/ARP/IPv4/ICMP) core.
UDP (net/ipv4/udp.c)
- Port-demux table with bound receive handlers, pseudo-header checksum,
ephemeral-port allocation, limited-broadcast send (0.0.0.0 -> 255.255.255.255
for DHCP before the interface has an address), and rx/tx/drop counters.
- Wired into the IPv4 receive path (IP_PROTO_UDP dispatch in net/core/net.c).
BSD sockets (net/core/socket.c)
- Real SOCK_DGRAM sockets backed by UDP: bind installs a UDP handler that fills
a per-socket receive ring; send/sendto and recv/recvfrom move datagrams;
ephemeral auto-bind, connect() memorises the peer. Socket table + I/O stats
exposed for introspection.
DNS resolver (net/ipv4/dns.c)
- Builds and parses real A-record queries over UDP/53 (label encoding,
compression-pointer aware answer walk), cache-first with TTL, static-hosts
and dotted-quad fast paths, and a bounded timeout that degrades to fallback
instead of hanging.
DHCP client (net/ipv4/dhcp.c)
- Full DISCOVER/OFFER/REQUEST/ACK handshake over UDP broadcast, option parsing
(mask/router/dns/lease/server-id), applies the lease to the primary
interface, bounded timeouts keep the static config on no response.
Fix (net/ipv4/dns_cache.c): the cache stored IPs as 0xAABBCCDD numeric while the
rest of the stack uses network-byte-order-in-memory (ip_parse/ip_to_str), so a
resolved address came back byte-swapped (nslookup github.com -> 100.121.82.140).
Seeds and dump now use ip_parse/ip_to_str; verified 140.82.121.4.
Userland (lazybox): live ifconfig (real interface + NIC counters, loopback),
netstat with live UDP bindings and transport stats, new `sockstat`, richer
nslookup. Verified in QEMU: boot clean on x86_64/aarch64/armv8i, login as SUB,
ping/nslookup/dhclient/netstat/sockstat all run; DHCP/DNS wire replies are
blocked by the sandbox's slirp but time out cleanly and fall back as designed.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
2c2e2d536e |
perf(gui): scene-dirty compositor + cursor overlay + 60 FPS pacer + animations
Rework the compositor so it stops repainting the whole screen every frame, tripling the frame rate (17 -> 54 FPS at HD) and adding smooth animation. - Scene-dirty skipping (gui/gui_desktop.c): the full scene is recomposited only when something other than the bare pointer changed -- input, an open animation, or a ~10 Hz heartbeat for live content (clock, graphs). Idle and pointer-only frames skip the recomposite entirely. - Cursor save-under (gui/gui_cursor.c): the pointer is an overlay that stashes and restores the pixels beneath it, so moving the mouse never forces a full repaint -- pointer motion runs at the frame cap. - 60 FPS frame pacer: each iteration is timed against the monotonic clock and padded to a 16.666 ms budget with the new ktime_delay_us() (HPET-precise busy-wait), giving consistent pacing instead of a free-running spin. - Window open animation (gui/gui_wm.c): new windows grow from 60% to full size with a cubic ease-out over ~160 ms; gui_wm_update() drives it and reports while any window is still animating so the compositor keeps redrawing. - Default display mode set to 1280x720 (HD) -- the sweet spot where the software compositor sustains a near-60 FPS cursor with headroom for effects. Kernel: kernel/time/ktime.c gains ktime_delay_us(), a precise HPET-based delay (bounded PIT fallback) used by the pacer. Verified live (screenshotted): boots to 1280x720, logs in, tray reads ~54 FPS (green) while the pointer moves, no cursor ghosting, windows render cleanly. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
4ecf119377 |
feat(gui,kernel): 1080p HD desktop, polished chrome, ktime clock + live FPS
GUI polish / HD: - Default display mode raised to 1920x1080 (video=1920x1080); make run/vnc use vgamem_mb=64 and -m 512M. The growable heap absorbs the larger backbuffer, shadow and wallpaper (observed: one 16 MB growth to a 48 MB heap). - Wallpaper: three-stop vertical gradient, a soft concentric-frame edge vignette for depth, a finer faint grid, and a centred brand mark. - Window chrome: brighter/saturated titlebar gradient when focused, an accent underline on the active window, and larger/softer drop shadows. - Default session windows are placed and sized for the HD work area. - Live FPS pill in the taskbar tray (green/amber/red by rate); tray widened so FPS + CPU trace + memory badge + clock no longer overlap. Kernel: - kernel/time/ktime.c + include/kernel/ktime.h (new): a unified monotonic high-resolution clock that prefers the HPET (nanosecond) and falls back to the 100 Hz PIT tick. Wired ktime_init() into boot; drives the compositor's FPS sampling. New `ktime` LazyBox applet reports the source and uptime. Verified live (screenshotted): boots to 1920x1080, KTIME reports "source: HPET, nanosecond resolution", the polished desktop renders with the active-window accent and vignette, and the tray shows a live FPS reading. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
ef6714a004 |
fix(gui): make the Settings app actually apply changes
The Settings window rendered fine but its controls only mutated the app's local
settings_data_t -- nothing was ever wired to the running system, so toggling
options did nothing ("not working").
- Appearance: "Show wallpaper grid overlay" now calls gui_desktop_set_grid()
live; the desktop grid shows/hides immediately.
- Input: "Show seconds in taskbar clock" now calls gui_desktop_set_clock_seconds();
the taskbar clock switches between HH:MM and HH:MM:SS.
- Power: the CPUFreq governor radios now call cpufreq_set_governor() (mapping the
UI order to the enum), and Apply/Defaults push all preferences to the system.
- The app seeds its controls from live state on open (grid/clock/governor), so it
reflects reality instead of hard-coded defaults.
Also add public gui_desktop_set_grid/get_grid and set/get_clock_seconds, and
give Settings a dedicated event handler that frees its state on close (the
shared app_forward_event leaked it).
Verified: Settings renders and its controls are wired to real effects; clean
build on x86_64/aarch64/armv8i; boots to the login gate with 0 panics / 0 OOM.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
0377726615 |
feat(drivers): HPET high-res timer, LPT parallel port, CMOS NVRAM
Add three real platform device drivers (x86 hardware, ARM-stubbed): - drivers/timer/hpet.c + include/drivers/hpet.h: High Precision Event Timer. Maps the HPET block at the standard 0xFED00000, reads the femtosecond period from the capability register, enables the main counter and exposes a monotonic nanosecond time source (hpet_get_ns) far finer than the 100 Hz PIT. - drivers/char/lpt.c + include/drivers/lpt.h: IBM PC parallel port (LPT1) with the Centronics data/strobe handshake over ports 0x378/0x379/0x37A. - drivers/char/nvram.c + include/drivers/nvram.h: MC146818 CMOS NVRAM read/write over 0x70/0x71, preserving the NMI-disable bit, with checksum and hex dump. Wired all three into the [5/14] device-enumeration boot step and added LazyBox applets `hpet`, `lpt`, and `nvram`. Verified live under QEMU (screenshotted): HPET reports 100 MHz / 3 comparators / 10 ns period and its counter advances ~1.4 s of real time between two `hpet` runs; NVRAM dumps 128 bytes with a computed checksum; LPT1 detected at 0x378. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
ea937a699c |
feat(kernel,gui): NT I/O Manager (IRP-based drivers) + Registry Editor
Kernel (NT I/O subsystem): - kernel/nt/io.c + include/kernel/nt/io.h (new): DRIVER_OBJECTs with a MajorFunction dispatch table, DEVICE_OBJECTs that can be stacked (attached), and IRPs pushed down the stack via io_call_driver / completed with io_complete_request. Ships three demo drivers: \Driver\Null (write sink, EOF reads), \Driver\Zero (zero-filled reads), and \Driver\Monitor -- a filter attached above \Device\Null that counts and forwards each IRP down the stack. Wired into the [12/14] boot step. - LazyBox `iodev` lists drivers/devices with the stack and IRP counters, then runs a live demo: a WRITE IRP through the filtered Null stack and a READ from the Zero device. GUI: - gui/gui_apps.c: "Registry Editor" -- navigate the NT \Registry hive tree, click subkeys to descend and ".." to go up, with a values pane showing each value's name/type/data. Registered in the app table (start menu). Verified live in the GUI terminal (screenshotted): 3 drivers / 3 devices, the NullMonitor->Null device stack, a 16-byte WRITE sunk through the filter (status 0x0), and an 8-byte zeroed READ from \Device\Zero. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
526ad8c741 |
feat(kernel,gui): NT Configuration Registry + GUI Object Browser
Kernel (NT Configuration Manager): - kernel/nt/reg.c + include/kernel/nt/reg.h (new): a hive/key/value registry rooted at "\Registry", with typed values (REG_SZ/DWORD/QWORD/BINARY/MULTI_SZ, type codes matching Win32). reg_create_key/reg_open_key walk backslash paths; setters/getters, enumeration, and value->string rendering. reg_init() seeds \Registry\Machine (Hardware, System\CurrentControlSet\Control, Software\SUB-OS) and \Registry\User\.DEFAULT. Wired into the [12/14] boot step. - LazyBox `reg query|add|set|stats` explores and edits the registry. GUI: - gui/gui_apps.c: "Object Browser" -- a WinObj-style live tree view of the NT object namespace (\), flattening directories/events/semaphores/mutants with indentation, per-type colouring, ref/handle counts, live object/handle stats, and click-to-scroll. Registered in the app table (start menu). Verified live in the GUI terminal (screenshotted): registry reports 13 keys / 11 values; `reg query \Registry\Machine\Software\SUB-OS` lists Version, BuildArch (REG_SZ), GrowableHeap/ObjectManager (REG_DWORD) and InstallCookie (REG_QWORD) with correct types. Clean build on x86_64/aarch64/armv8i; 0 panics. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
cb7506f027 |
feat(kernel): NT-inspired Object Manager, dispatcher and IRQL
Take inspiration from the Windows NT Executive and add its most iconic
subsystem to SUB-OS: a typed, reference-counted object namespace.
- kernel/nt/ob.c + include/kernel/nt/ob.h (new):
* Object Manager (Ob): typed objects (Directory/Event/Semaphore/Mutant) in a
hierarchical named namespace rooted at "\", with NT-style deletion once
handle_count and ref_count both reach zero (unless permanent).
* Handle table (Io/Ob): NT-shaped non-zero 4-aligned HANDLEs into a 256-slot
system table; open/reference/close with proper refcount transfer.
* Dispatcher (Ke): set/reset/test events (auto- and manual-reset) and
release/wait semaphores, poll-style.
* Software IRQL: PASSIVE/APC/DISPATCH/HIGH with raise/lower semantics.
* NTSTATUS result codes and NT_SUCCESS().
* ob_init() seeds the standard namespace (\BaseNamedObjects, \Device,
\ObjectTypes, \KernelObjects) plus a boot event and an I/O semaphore.
- Wired ob_init() into the [12/14] boot step; added kernel/nt/ob.c to CORE_SRCS.
- LazyBox: `objdir [\path]` walks the object namespace tree (WinObj-style);
`ntobj` prints Ob statistics and runs a live dispatcher/handle/IRQL demo.
Verified live in the GUI terminal (screenshotted): 7 seeded objects
(5 directories, 1 event, 1 semaphore), auto-reset event signalling, handle
close reclaiming the object, and PASSIVE->DISPATCH->PASSIVE IRQL transitions.
Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
c414c20b44 |
feat(rust,gui): RLE compression codec + Rust Lab desktop app
Rust kernel expansion: - rust/src/compress/mod.rs (new): memory-safe PackBits-style run-length encoding codec (rle_compress / rle_decompress) with C-ABI shims, registered in lib.rs. C fallbacks added to rust_fallback.c so aarch64/armv8i match. - include/kernel/rust.h: FFI declarations for the codec. - LazyBox: new `rle <text>` applet that compresses, decompresses, prints the ratio and verifies the round-trip is lossless. GUI expansion: - gui/gui_apps.c: "Rust Lab" app -- a live dashboard for the Rust subsystem. Shows CRC-32C/Adler-32 of a sample, measured ChaCha20/SHA3-256/AES-128 throughput as scaled bars plus a composite score (benchmark run once at launch and cached), and a live ChaCha20 CSPRNG byte stream refreshed periodically. Per-window state freed on close. - Registered "Rust Lab" (info icon) in the desktop app table and on the desktop; desktop icon indices updated for the new entry. Verified: clean build on x86_64/aarch64/armv8i; boots through the SUB login to the desktop with the new Rust Lab icon rendering (screenshotted); checksum self-test prints, 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
e93b994469 |
feat(rust,gui): Rust checksum engine + Game of Life desktop app
Rust kernel expansion:
- rust/src/checksum/mod.rs (new): memory-safe CRC-32C (Castagnoli), Adler-32,
and FNV-1a-64 with thin C-ABI shims. Registered in lib.rs with a boot-time
self-test (crc32c("SUB-OS")=0x61e96ce9, verified against a reference impl).
- include/kernel/rust.h: FFI declarations; rust/rust_fallback.c: matching C
fallbacks so aarch64/armv8i (no native rustc target) get identical results.
- LazyBox: new `cksum <text>` applet printing all three via the Rust engine.
GUI expansion:
- gui/gui_apps.c: Conway's Game of Life -- an interactive B3/S23 cellular
automaton with Play/Pause/Step/Random/Clear toolbar, click-to-toggle cells,
a live generation/population readout, and a board that scales with the
window. The Random button seeds from the Rust ChaCha20 CSPRNG. Toolbar and
cell input are gated on the MOUSE_DOWN edge so they do not re-fire while held.
- Registered "Life" (flask icon) in the desktop app table and on the desktop.
Verified: clean build on x86_64/aarch64/armv8i; boots through the SUB login to
the desktop (screenshotted) with the checksum self-test and 0 panics/0 OOM.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
|
||
|
|
c982d6b538 |
feat(auth): Boot-time login prompt; fix(configure): arch selection via dialog
Login: - Add console_login() (security/auth.c): an interactive boot-time username / password gate rendered on the framebuffer console before any session starts. It blocks until valid credentials are entered, masks the password, scrubs it from the stack, and sets the current user. Default account is SUB / SUB, shown as a hint. Wired into the boot handoff in kernel/main.c ahead of both the GUI desktop and the emergency TTY shell. Configure: - scripts/kconfig/menuconfig.py: fix the architecture (and optimization) picker. The lxdialog front-end used --radiolist, where <Enter> confirms the ORIGINAL choice and only <Space> moves the dot -- so highlighting a new architecture and pressing <Enter> appeared to do nothing. Single-choice groups now use --menu (with --default-item), where <Enter> selects the highlighted row directly. Also stop the unconditional save-on-exit from overriding an explicit "No" at the exit confirmation. Verified: SUB/SUB logs in (injected via QEMU monitor) -> "Login successful" -> desktop starts; the desktop stays blocked until login. dialog --menu selection of aarch64 persists to .config/autoconf.h and retargets `make`. Clean build on x86_64/aarch64/armv8i. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
71ad6aca3d |
feat: Growable heap, GUI-by-default run, live sysmon, SUB/SUB default login
Kernel / memory: - mm/kmalloc.c: fix "Heap: Out of memory" under the GUI. The desktop allocates three full-screen 32-bit buffers (~11MB) which overflowed the fixed 16MB pool. The heap now starts at 32MB and grows on demand from the PMM (16MB regions), with region-safe coalescing (only merges physically adjacent blocks) so growth never corrupts across separate PMM allocations. Adds heap_get_grow_count(). Build / run: - Makefile: merge `run-gui` into `run` so `make run` boots into the graphical desktop; add `run-headless` (serial-only via QEMU_CMD), bump guest RAM to 256M, update .PHONY and help. Configure: - scripts/kconfig/menuconfig.py: gate the curses UI behind isatty() on stdin and stdout so non-interactive `make configure` stops emitting "nocbreak() returned ERR" and falls cleanly through to the non-interactive writer. GUI / userland: - gui/gui_apps.c: rebuild the System Monitor from hardcoded values into live telemetry -- real heap used/total/free with a colour-shifting bar, a scrolling heap-utilisation graph, the grow counter, and real PMM RAM figures. - lazybox `free`: report how many times the heap has grown. Auth: - Default login is now SUB / SUB (Kali-style username==password), seeded first as the primary uid-0 account and set as the logged-in user; root kept for compatibility. Hardcoded "root" defaults (whoami, su, passwd, ssh, sshd session) updated to SUB. Verified: clean build on x86_64/aarch64/armv8i; GUI boots with 0 OOM/0 panic; auth engine initialises cleanly; `make configure` fallback is clean. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
65fa4dd049 |
ci(release): Build and publish all three architectures
Rework the release workflow from a single x86_64 build into a matrix that builds x86_64 (bootable image), aarch64 and armv8i (bare-metal kernel ELFs) in parallel, then publishes one prerelease carrying every architecture's artifacts plus a combined SHA256SUMS. - x86_64 builds natively (build-essential + nasm + rustc, CROSS_COMPILE=), matching the validated local toolchain; aarch64/armv8i use the apt cross compilers (gcc-aarch64-linux-gnu, gcc-arm-linux-gnueabihf). - Artifacts are named SUB-OS-<tag>-<arch>-... and collected by a release job. - Notes refreshed for the GUI desktop and multi-arch support. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXXv0.0.1-alpha |
||
|
|
25c0519c25 |
Merge branch 'feat/gui-desktop' into main
Bring the SUB-OS Graphical Desktop Environment (SUB-WM compositor, SUB-WT widget toolkit, icon set, modal dialogs, terminal emulator and the desktop apps) onto main alongside main's userland /sbin/init and framebuffer console. Conflicts resolved: - kernel/main.c: boot into gui_start_desktop() by default (unless nogui/text/ emergency/single), then fall back through fbcon + /sbin/init + shell when the GUI session closes or a text console is requested. Splash raised by default unless a text console is asked for. Kept main's fbcon include and the weave_preempt_selftest path. - Makefile: kept main's userland init compilation rules and kernel/elf.c, kernel/exec.c in CORE_SRCS; retained the feature branch's gui/ sources. - README.md: kept main's Weave Scheduler section and adopted the feature branch's Boot Logo / Console Font / Framebuffer Console / GUI Desktop docs. Verified: full x86_64 build links cleanly (kernel.elf + SUB-OS.img). Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX |
||
|
|
0a874341c6 |
feat(sched): Preemptive Weave scheduling driven by the timer tick
Kernel threads were only ever switched cooperatively (sched_yield, task_exit); a thread that never yielded held the CPU forever. The Weave scheduler now preempts from the PIT tick, so CPU-bound threads are time-sliced. Deferred switch, not mid-handler: - sched_tick() no longer switches. It charges the running quantum and, when it is spent, only raises weave_need_resched. The switch happens at IRQ return in the new sched_preempt_on_return(), called from the x86_64 dispatcher after the PIC EOI. That keeps the tick path re-entrancy-safe (the EOI is already out, so the PIC keeps delivering) and lets the preempted thread unwind through the normal iretq on its own kernel stack. Interrupt-atomic scheduler state: - The plain weave_lock is not IRQ-safe, so a tick landing mid-mutation would deadlock. weave_lock sections now mask interrupts (arch_irq_save/restore, added to arch.h for all three arches) so the timer can never fire inside them, and weave_rotate holds them masked across the pick and the register swap so the switch is one indivisible step. Preemption-disable count: - sched_preempt_disable/enable gate the tick and the return-path switch so a preemptive switch cannot land while a plain (non-IRQ-safe) spinlock is held. printk wraps its critical section with it, closing the most common hazard; other locks are a documented follow-up. Fresh threads opt into interrupts at entry so they are preemptible from birth without changing the cooperative early-boot self-test, which still runs with interrupts masked and is unchanged (20 switches, 3/3 workers). Verified on x86_64 under QEMU: a new boot-time self-test arms preemption and two threads that NEVER yield are forced to share the CPU -- 20 involuntary switches, both advance and are woven down to the CPU-bound lanes -- then boot proceeds cleanly to ring-3 /sbin/init and the shell with zero faults. aarch64 and armv8i still build; preemption is wired into the x86_64 IRQ path only, so those stay cooperative for now (their switch asm already exists). Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_0161Jh7uCEMLYEMNPsjC1LKf |
||
|
|
d221067936 |
Merge pull request #1 from subhobhai943/claude/relaxed-newton-efpllm
feat(sched): Weave tiered scheduler with real kernel-thread context s… |
||
|
|
a14a7c79b0 |
feat(sched): Weave tiered scheduler with real kernel-thread context switching
Replace the state-relabel-only round-robin with the SUB-OS "Weave" scheduler backed by a genuine callee-saved context switch. Threads now actually run on their own kernel stacks instead of merely having their state field rewritten. What was implemented: - sub_ctx_switch(): per-arch assembly (arch/x86_64/cpu/switch.asm, arch/aarch64/cpu/switch.S, arch/armv8i/cpu/switch.S) that saves/restores the callee-saved register set (+ flags on x86_64) on each thread's own stack, plus a first-run trampoline (sub_thread_trampoline) that launches a freshly forged thread frame with entry/arg in callee-saved registers. - task_forge_frame(): builds the initial saved-context frame per arch so the very first switch into a new thread lands on the trampoline; task_t gains a pointer-sized ctx_sp so the same struct works on 64- and 32-bit. - Weave policy (kernel/sched.c): WEAVE_NLANES priority lanes, always dispatch the lowest non-empty lane round-robin; a task that yields voluntarily is woven UP a lane (interactive), one preempted after burning its quantum is woven DOWN (CPU-bound). Cooperative switching (sched_yield / task_exit) is always live; timer-driven preemption is gated behind sched_set_preempt() and left disarmed for now. - task_exit() now switches to the next runnable thread via sched_exit_current() instead of spinning/halting. - Boot-time weave_selftest() (x86_64) and sched_dump() diagnostics. How it was verified: - Builds clean for all three targets: x86_64 (CROSS_COMPILE=x86_64-linux-gnu-, RUSTC="rustc --target x86_64-unknown-none"), aarch64, armv8i. No new warnings; the new x86_64 asm carries a .note.GNU-stack section. - Booted x86_64 under QEMU (TCG): the self-test runs three cooperative kernel threads to completion on separate stacks with the expected 1->2->3 round-robin interleave, reports "20 real context switches, 3/3 workers exited", returns cleanly to the boot thread, and boot proceeds normally to ring-3 init and the shell. No fault/panic. Left unverified: - The aarch64/armv8i sub_ctx_switch frames build and link but are not yet boot-tested on their QEMU targets (tracked in docs/AUTODEV_ROADMAP.md). - Timer preemption path is implemented but disarmed; exited kernel threads currently leak their stack (reaper is next in the backlog). Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Jk6K69yGS7zYgvoWd6nJxQ |
||
|
|
2136b6fb4c |
perf(gui): Present only changed pixels and cache the wallpaper
The compositor recomposited and re-uploaded the entire screen on every pass of its loop. At the 1280x720 the desktop actually boots into, gui_gfx_present() memcpy'd 3.6 MB into the framebuffer per frame, and the background underneath it was recomputed pixel by pixel every time. Present only the damage - Keep a RAM shadow of what the framebuffer currently holds and diff the back buffer against it, pushing just the changed span of each row. Reading the shadow costs a RAM access; the framebuffer write it avoids costs far more, and the framebuffer is never read back. - Each row is narrowed to its first and last differing pixel rather than tracked as a set of runs: one memcpy per row keeps the loop tight, and a row that changed in two distant places is rare enough that bridging the gap is cheaper than the bookkeeping. - gui_gfx_invalidate() forces a full push for when something outside the compositor owns the screen, which the desktop calls on entry and on exit around the framebuffer console. Cache the wallpaper - The vertical gradient, the blended grid and the branding text never change between frames, so they are painted once into a cached buffer and blitted back per frame. The cache is keyed on resolution and the grid setting, so toggling the grid from the context menu still repaints it. No drawing code changed: the damage is derived from the frame itself, so every widget, window and app keeps rendering exactly as before. Measured in QEMU at 1280x720: an idle desktop with two windows open went from 921600 pixels per frame to 3609, about 0.4% of a full blit. A screendump of the running desktop is unchanged -- wallpaper, grid, icons, both windows, taskbar and cursor all render identically. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_0161Jh7uCEMLYEMNPsjC1LKf |
||
|
|
ecdc5be435 |
feat(exec): Run userland in ring 3 with an ELF64 loader and per-process page tables
SUB-OS had a syscall table and user GDT descriptors but nothing that could actually leave ring 0: lazybox and the shell run as kernel code, and syscall_handler() was never reachable from a user program. This adds the missing path end to end on x86_64. Address spaces (arch/x86_64/mm/vmspace.c) - The boot page tables identity-map the low 4 GB off PML4[0] and leave the rest empty, so userland is given its own PML4 slot (512 GiB) rather than holes punched in the kernel's 2 MB huge-page map. A process PML4 shares entry 0 with the kernel and privately owns entry 1. - Frames outside the identity map are refused rather than written through an unmapped pointer; lifting that needs a recursive map or a higher-half direct map, which is noted in the file. ELF loader (kernel/elf.c) - Validates ELF64/little-endian/ET_EXEC/machine, bounds-checks every program header against both the image and the user address range, and lays PT_LOAD segments into an address space. Frames arrive zeroed, so .bss is covered. Ring transition (arch/x86_64/cpu/usermode.asm) - user_enter() drops to ring 3 via iretq after scrubbing every GPR, and user_return() unwinds back to it when the process exits, so exec looks like a call that blocks until the program finishes. Syscalls - INT 0x80 installed at DPL 3 with the Linux x86_64 register convention. The process gets its own kernel stack for the trap, because TSS.rsp0 must not point at the stack user_enter() is standing on. - Every user pointer is range-checked before use. The process page tables are still live during a syscall, so without that check a program could pass a kernel address and have write(2) dump kernel text to the console. The new /sbin/init asserts both a wild pointer and a kernel pointer are rejected. - write(2) to stdout/stderr routes through the new console_write(), which reuses printk's routing so output reaches serial and the framebuffer console rather than only the VGA text buffer. Faults - A ring 3 exception now kills that process and reports CR2 instead of panicking the machine. Userland (userland/init/) - /sbin/init is a real freestanding static executable, linked at the user base and embedded in the kernel image by scripts/mkblob.py. It reports its pid, verifies .bss was zeroed and .data is writable, checks the two pointer rejections, and exits. aarch64 and armv8i keep building: the loader and exec path are portable, and those ports get honest vmspace stubs that fail cleanly rather than pretending to run a program with kernel privileges. Verified under QEMU: init loads at 0x80004000a0, reports pid 1, .bss zeroed, .data writable, both bad pointers rejected, and exits 0 back into the shell. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_0161Jh7uCEMLYEMNPsjC1LKf |
||
|
|
7929e48b4e |
fix(kconfig): Repair menuconfig help buttons and preserve pending toggles
The configurator had four defects that made buttons and selection behave
erratically in `make configure`.
lxdialog front-end:
- Pressing <Help> in a subsystem menu discarded every toggle made since the
menu was opened, because dialog reports only the focused tag and the result
was thrown away. Pass --help-status and fold the returned state back into
the config before showing help.
- <Help> always showed the generic subsystem blurb even though all 41 options
carry their own help text. Resolve the focused tag and show that item's help.
- The main menu prompt promised <Exit> but dialog rendered <Cancel>; label the
button to match.
curses fallback:
- The Help button raised AttributeError and killed the UI at top level: the
root node is the MENU_TREE list itself, and the fallback argument
`current_menu.get("help", ...)` is evaluated eagerly even when the item has
its own help.
- The '?' hotkey was nested inside the <Enter> branch where `key` can only be
a newline, so it was unreachable dead code.
- The button-bar spacing went negative on a narrow dialog and pushed the last
buttons through the right border; centre and clamp the row instead.
Front-end selection no longer swallows exceptions silently, so a crash reports
itself instead of looking like an unresponsive UI.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0161Jh7uCEMLYEMNPsjC1LKf
|
||
|
|
4d9223c8cc |
feat(video): Move the console to the framebuffer once the adapter is graphical
bochs_vbe_init switches the adapter into graphics mode at boot step [5/14], and from that point the VGA text buffer is no longer scanned out. This kernel boots to a TTY, so every message after that -- and the whole shell session -- was invisible in the emulator window and reached only the serial line. The console now moves to the framebuffer at that transition, which also makes the nano editor render correctly: it positions with tty_set_cursor() rather than escape sequences, and the TTY driver dispatches that to fbcon. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
7dd8f2219a |
feat(video): Add a framebuffer console so the TTY and nano work after graphics mode
Pressing Esc left the desktop and started the shell, but nothing appeared in the
emulator window -- the session was only visible on the host terminal. Once the
VBE adapter is switched into graphics mode the VGA text buffer at 0xB8000 stops
being scanned out, so every printk after that point reached serial and the
dmesg ring but never the display.
Disabling the DISPI interface does not bring the text console back; QEMU keeps
presenting the last framebuffer surface. So rather than clawing the adapter back
to text mode, the console is now rendered into the framebuffer:
drivers/video/fbcon.c draws the console with the shared 8x8 font and carries a
VT100 subset -- SGR colours, cursor addressing, relative moves, erase-display,
erase-line and save/restore. It presents a fixed 80x25 grid, because that is
the geometry the userland assumes (nano pads its bars with %-80s, the shell
wraps at TTY_WIDTH), with the glyph cell scaled to fill the active resolution.
The TTY driver became the console dispatcher: tty_write, tty_clear and
tty_set_cursor route to fbcon while it owns the display. That last one is what
makes nano work -- it positions with tty_set_cursor() rather than escapes, so
its full-screen repaint was landing as an append-only stream.
Also in this change:
- `video=WIDTHxHEIGHT` on the kernel command line selects the display mode,
defaulting to 1280x720 so a 16:9 host panel is filled rather than pillarboxed
when QEMU goes fullscreen. Rejects modes the heap cannot back.
- `make run-fullscreen`, plus zoom-to-fit on the windowed target, so scaling
preserves the guest aspect ratio instead of stretching it.
- QEMU targets raise vgamem_mb, since a 1280x720 32-bit surface exceeds the
default VGA memory.
- bochs_vbe_disable()/fb_set_active() let the framebuffer be marked dormant so
drawing routines no-op after a mode teardown.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
|
||
|
|
65b7a709cc |
fix(gui): Adapt the desktop to the active resolution and restore the console on exit
The launcher table is authored against an 800x600 work area, so at 1280x720 every window kept its original size and left the desktop looking sparse, while still overlapping the icon column the way it did at the design resolution. Launch geometry now scales with the work area, capped so a window cannot swallow the screen, and offset clear of the icon strip so launcher labels stay readable. The wallpaper grid was a single fixed colour, which is darker than the top of the gradient but lighter than the bottom, so the grid faded out across the lower half of the screen. It is blended now and reads the whole way down. Leaving the desktop hands the screen to the framebuffer console, and entering it takes the screen back, so Esc drops to a working TTY inside the emulator and `gui` returns to the desktop. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
2d01fd629e |
feat(video): Add a framebuffer console so the TTY and nano work after graphics mode
Pressing Esc left the desktop and started the shell, but nothing appeared in the
emulator window -- the session was only visible on the host terminal. Once the
VBE adapter is switched into graphics mode the VGA text buffer at 0xB8000 stops
being scanned out, so every printk after that point reached serial and the
dmesg ring but never the display.
Disabling the DISPI interface does not bring the text console back; QEMU keeps
presenting the last framebuffer surface. So rather than clawing the adapter back
to text mode, the console is now rendered into the framebuffer:
drivers/video/fbcon.c draws the console with the shared 8x8 font and carries a
VT100 subset -- SGR colours, cursor addressing, relative moves, erase-display,
erase-line and save/restore. It presents a fixed 80x25 grid, because that is
the geometry the userland assumes (nano pads its bars with %-80s, the shell
wraps at TTY_WIDTH), with the glyph cell scaled to fill the active resolution.
The TTY driver became the console dispatcher: tty_write, tty_clear and
tty_set_cursor route to fbcon while it owns the display. That last one is what
makes nano work -- it positions with tty_set_cursor() rather than escapes, so
its full-screen repaint was landing as an append-only stream.
Also in this change:
- `video=WIDTHxHEIGHT` on the kernel command line selects the display mode,
defaulting to 1280x720 so a 16:9 host panel is filled rather than pillarboxed
when QEMU goes fullscreen. Rejects modes the heap cannot back.
- `make run-fullscreen`, plus zoom-to-fit on the windowed target, so scaling
preserves the guest aspect ratio instead of stretching it.
- QEMU targets raise vgamem_mb, since a 1280x720 32-bit surface exceeds the
default VGA memory.
- bochs_vbe_disable()/fb_set_active() let the framebuffer be marked dormant so
drawing routines no-op after a mode teardown.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
|
||
|
|
e228886adb |
docs: Document the boot logo, splash and shared console font
Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
ba06264d12 |
feat(boot): Add SUB-OS boot logo and splash, share the console font, and lift the kernel size ceiling
Boot logo (init/bootlogo.c, init/logo_data.c, scripts/mklogo.py): The logo appears in two forms because the framebuffer does not exist for the first third of boot. An ASCII rendition goes to the text console and serial line from the first moments; once the video driver is up at step [5/14] the real bitmap takes over as a graphical splash with a progress bar tied to the actual boot stages. The asset is 4-bit palette indexed, so 160x160 pixels cost 12.5 KB instead of 100 KB, and carries a transparency mask so the mark composites onto the gradient rather than stamping a flat rectangle over it. scripts/mklogo.py regenerates init/logo_data.c from the source PNG. Boot reaches the desktop in well under a second, so the splash is held for a minimum duration and the bar sweeps to 100% during the hold; without that the logo would flash past unseen. `splashtime=<ms>` tunes it and `nosplash`, `nogui` or `text` skip it. Bootloader (boot/stage2.asm): stage2 staged the whole kernel in conventional RAM before copying it to 1 MB, which capped the kernel at roughly 576 KB before the load ran into video memory at 0xA0000. The logo pushed it over that line and the kernel stopped booting. Each 32 KB chunk now goes into one fixed low buffer and is copied straight to its final address, using unreal mode for the 32-bit reach. The ceiling is now the image itself, 1.375 MB. Console font (lib/font8x8.c): fb_draw_char was a stub that ignored its character argument and drew a filled rectangle, which is why the splash rendered its text as solid blocks. It now renders real glyphs, and the table it uses is shared: the framebuffer console, the canvas rasterizer and the desktop compositor had three divergent private copies, two of which still carried the `// \` line-continuation defect. printk console sink (kernel/printk.c): printk output can be redirected to a callback, so a caller can run a subsystem that reports via printk and capture what it printed. Serial and the dmesg ring still see everything, which keeps a captured run debuggable. Shell builtins (userland/lazybox/shell.c): The builtin chain is extracted into shell_execute_builtin(), so the kernel TTY and the desktop terminal accept the same vocabulary instead of the GUI seeing only the applet table. Callers that cannot be suspended pass allow_blocking = false to refuse the animating ones. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
eacba4f4d3 |
feat(gui): Make the desktop terminal run real commands
The GUI terminal recognised four hardcoded strings and answered everything else
with "Executed: '<cmd>'". It now dispatches to the same LazyBox applet table and
shell builtins the kernel TTY uses, so ls, free, uname, lspci, ktest, neofetch,
sort, cd and the rest all work, with cwd tracked across commands.
LazyBox reports through printk, so before running a command the terminal
installs a printk sink and streams the output into its own scrollback:
- ANSI SGR codes become per-line colours instead of being stripped.
- CP437 box-drawing and block characters fall back to ASCII, so the colour
swatch in neofetch renders as '#' rather than a row of '?'.
- 256 lines of scrollback, command history on Up/Down, PgUp/PgDn/Home/End.
- Applets that read the keyboard directly (nano, snake, sh, top) are refused
with a pointer to the TTY, since they would block the compositor.
The window's paint and event handlers moved out of gui_apps.c into
gui/gui_terminal.c, and gui_gfx.c now draws from the shared lib/font8x8.c table
rather than its own copy.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
|
||
|
|
56a378b142 |
feat(boot): Add SUB-OS boot logo and splash, share the console font, and lift the kernel size ceiling
Boot logo (init/bootlogo.c, init/logo_data.c, scripts/mklogo.py): The logo appears in two forms because the framebuffer does not exist for the first third of boot. An ASCII rendition goes to the text console and serial line from the first moments; once the video driver is up at step [5/14] the real bitmap takes over as a graphical splash with a progress bar tied to the actual boot stages. The asset is 4-bit palette indexed, so 160x160 pixels cost 12.5 KB instead of 100 KB, and carries a transparency mask so the mark composites onto the gradient rather than stamping a flat rectangle over it. scripts/mklogo.py regenerates init/logo_data.c from the source PNG. Boot reaches the desktop in well under a second, so the splash is held for a minimum duration and the bar sweeps to 100% during the hold; without that the logo would flash past unseen. `splashtime=<ms>` tunes it and `nosplash`, `nogui` or `text` skip it. Bootloader (boot/stage2.asm): stage2 staged the whole kernel in conventional RAM before copying it to 1 MB, which capped the kernel at roughly 576 KB before the load ran into video memory at 0xA0000. The logo pushed it over that line and the kernel stopped booting. Each 32 KB chunk now goes into one fixed low buffer and is copied straight to its final address, using unreal mode for the 32-bit reach. The ceiling is now the image itself, 1.375 MB. Console font (lib/font8x8.c): fb_draw_char was a stub that ignored its character argument and drew a filled rectangle, which is why the splash rendered its text as solid blocks. It now renders real glyphs, and the table it uses is shared: the framebuffer console, the canvas rasterizer and the desktop compositor had three divergent private copies, two of which still carried the `// \` line-continuation defect. printk console sink (kernel/printk.c): printk output can be redirected to a callback, so a caller can run a subsystem that reports via printk and capture what it printed. Serial and the dmesg ring still see everything, which keeps a captured run debuggable. Shell builtins (userland/lazybox/shell.c): The builtin chain is extracted into shell_execute_builtin(), so the kernel TTY and the desktop terminal accept the same vocabulary instead of the GUI seeing only the applet table. Callers that cannot be suspended pass allow_blocking = false to refuse the animating ones. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
280d7fa2bb |
build: Track header dependencies, fix default goal, and repair the font table comment
Three build-correctness fixes plus README coverage of the new kernel core. The Makefile had no header dependency tracking, so editing a header left every unrebuilt caller linked against the old layout. That is how the desktop's window paint callbacks silently landed at the wrong struct offset after gui_window_t grew: gui_apps.o was never recompiled. Compiles now emit .d files via -MMD -MP and the build pulls them in. The include has to sit at the end of the file with .DEFAULT_GOAL pinned to `all` -- a .d file's first rule would otherwise become make's default goal and turn a bare `make` into a silent no-op. drivers/video/canvas.c carried the same font table defect gui_gfx.c did: the `// \` comment on the backslash glyph continues onto the next line, swallowing the `]` entry and shifting every glyph from ']' onward by one, so all lowercase text rendered one letter off. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
1aee7c7a0d |
feat(gui): Add SUB-WT widget toolkit, icon set, modal dialogs, six apps and a reworked window manager
Turns the desktop from a fixed set of hand-drawn panels into a real
environment applications can be written against.
SUB-WT immediate-mode toolkit (gui/gui_widgets.c):
Buttons, labels, checkboxes, radios, sliders, list boxes, text fields, tab
bars, scrollbars, progress bars, sparklines and badges. An app feeds the WM
event into the toolkit and then calls widgets from its paint routine, so
each call both draws the control and reports what the user did with it --
no retained widget tree to keep in sync with window state.
Icons and dialogs:
gui_icons.c holds 14 16x16 palette-indexed glyphs stored as hex text, so the
art stays hand-editable and picks up theme changes for free; they scale by
integer factors and can be drawn as tint stencils. gui_dialog.c adds modal
info/warning/error/confirm dialogs that dim the desktop, take exclusive
input, word-wrap on spaces and report results through a callback.
Applications (gui/gui_apps_ext.c):
Settings (tabbed appearance/input/power), Task Manager (live process table
over task_find_by_pid with memory and heap gauges), Kernel Log viewer (reads
the dmesg ring, strips ANSI, colours by severity, scrolls), KTest Runner
(drives the in-kernel suites and reports 21/21 with timing), Clock & Calendar
(Zeller's congruence month grid) and a Text Editor.
Window manager (gui/gui_wm.c):
Minimize/maximize/restore buttons, a corner resize grip, edge snapping, tile
and cascade layouts, F5-F9 shortcuts, title truncation, and index-based
enumeration so the taskbar no longer assumes window ids stay dense.
Desktop shell (gui/gui_desktop.c):
Launcher icon grid, richer start menu, right-click context menu, taskbar
buttons that minimize and restore, and a live CPU trace in the tray.
Two interaction bugs fixed along the way:
- keyboard_get_key() blocks until a key arrives, so calling it every frame
froze the compositor; it is now gated on keyboard_has_key(), and stale
console input is drained before the first frame.
- When the desktop consumed a click, the WM's press-edge detector kept the
pre-press state and read the still-held button as a fresh press on the
next frame, stealing focus from whatever the click had just opened.
gui_wm_sync_button_state() keeps the two layers in step.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
|
||
|
|
ed8922c498 |
build: Track header dependencies, fix default goal, and repair the font table comment
Three build-correctness fixes plus README coverage of the new kernel core. The Makefile had no header dependency tracking, so editing a header left every unrebuilt caller linked against the old layout. That is how the desktop's window paint callbacks silently landed at the wrong struct offset after gui_window_t grew: gui_apps.o was never recompiled. Compiles now emit .d files via -MMD -MP and the build pulls them in. The include has to sit at the end of the file with .DEFAULT_GOAL pinned to `all` -- a .d file's first rule would otherwise become make's default goal and turn a bare `make` into a silent no-op. drivers/video/canvas.c carried the same font table defect gui_gfx.c did: the `// \` comment on the backslash glyph continues onto the next line, swallowing the `]` entry and shifting every glyph from ']' onward by one, so all lowercase text rendered one letter off. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP |
||
|
|
29d7726a91 | Merge branch 'main' into feat/gui-desktop | ||
|
|
f9400f6ac4 |
feat(kernel): Add RB-tree/kfifo/hashtable, wait queues, futex, tiny RCU, page cache and KTest harness
Expands the kernel-and-TTY core with the primitives the higher layers have
been missing, plus an in-kernel harness that proves they work.
Data structures (lib/):
- rbtree.c: Linux-compatible red-black tree with parent pointers, full
insert/erase rebalancing, in-order iteration and an invariant validator.
- kfifo.c: power-of-two byte ring with free-running indices, so the wrap
path costs one mask instead of a branch per byte.
- hashtable.c: separately-chained table with FNV-1a hashing, string or
u64 keys, and rehash-on-growth at a 3/4 load factor.
Kernel subsystems:
- kernel/wait.c: wait queues and one-shot completion barriers, backed by a
static sleeper pool so a blocking path never re-enters the allocator.
- kernel/futex.c: 32-bucket futex hash with value re-check, requeue, and an
fmutex_t sleeping mutex built on the uncontended-fastpath protocol.
- kernel/rcu.c: tiny RCU with reader nesting, deferred callbacks, kfree_rcu
and rcu_assign_pointer/rcu_dereference publish barriers.
- mm/page_cache.c: write-back block page cache, 4 KB pages indexed by
(device, page), CLOCK second-chance eviction and dirty write-back.
- kernel/ktest.c: KUnit-style harness with 6 built-in suites, 21 cases and
735 assertions covering every subsystem above (all passing under QEMU).
LazyBox userland:
- coreutils.c: sort, uniq, cut, tr, rev, tac, nl, seq, diff, xxd, du,
factor, sum and truncate, reading through the VFS and handling the
zero-length synthetic nodes that procfs and sysfs expose.
- ktest, rcuinfo, futexinfo, waitinfo and pagecache diagnostics applets.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01L5yKJT4Wo2cV3rfPrwY5MP
|
||
|
|
4568a9ab4e |
feat(gui): Upgrade to high-res 800x600, sharp 8x16 font, IRQ12 PS/2 mouse driver, and polished window manager
- Upgrade resolution to 800x600 @ 32bpp TrueColor with Bochs/QEMU VBE LFB - Implement full 8042 Aux PS/2 mouse controller driver on IRQ 12 (vector 44) with packet decode and bounds clamping - Add high-definition 8x16 font rasterizer with text drop shadows for sharp typography - Upgrade to smooth 16x24 anti-aliased cursor with dark slate outline and drop shadow - Increase titlebars to 24px and taskbar to 32px with modern desktop styling - Re-architect applications (SysMon, Terminal, Explorer, Calc, Paint, About) for spacious high-res display |
||
|
|
56d8b3af1a |
feat(gui): Enable direct boot to GUI Desktop with emergency kernel TTY fallback
- Integrate Bochs/QEMU VBE physical LFB mapping directly to hardware video memory (0xFD000000) - Update kernel boot sequence to directly boot into GUI Desktop by default - Fall back to Emergency Kernel TTY Mode upon GUI exit (Esc key / Exit menu item) - Support 'nogui', 'text', 'emergency', and 'single' boot arguments to boot directly into text mode - Remove frame limits so GUI runs persistently |
||
|
|
81a17aae37 | fix(makefile): Enhance run-gui with explicit std VGA and add run-vnc target for headless/remote display |