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
This commit is contained in:
subhobhai943andClaude Opus 5 committed 2026-08-25 01:37:20 +05:30
1 parent 280d7fa2bb
commit ba06264d12
15 files changed
+1711 -153

No files matched your search

+22
View File
@@ -87,6 +87,7 @@
#include <init/init.h>
#include <init/service.h>
#include <init/version.h>
#include <init/bootlogo.h>
#include <userland/lazybox.h>
#include <userland/sh.h>
#include <userland/shell.h>
@@ -128,8 +129,17 @@ static void subos_modular_core_boot(void) {
tsc_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
// The framebuffer exists from here on. This kernel boots to a text console,
// so the graphical splash is opt-in via `splash` on the command line --
// raising it by default would hide the very console we are about to use.
// The ASCII logo printed at the top of boot covers the default case.
if (init_has_param("splash") && !init_has_param("nosplash")) {
boot_logo_splash_begin();
}
// Network Subsystem, NetFilter, HTTPD & SSH Server
printk(KERN_INFO "[6/14] Initializing Network Stack, NetFilter, HTTPD & SSHD... ");
boot_logo_splash_progress(40, "Bringing up the network stack");
filter_init();
httpd_init();
sshd_init();
@@ -166,6 +176,7 @@ static void subos_modular_core_boot(void) {
// Crypto, Certificates, LSM Security, Authentication, Namespaces, Rust, SUB-Lang & C++ Subsystems
printk(KERN_INFO "[8/14] Initializing Rust, C++ Core, SUB-Lang Engine, Keyring & Auth... ");
boot_logo_splash_progress(55, "Starting Rust, C++ and SUB-Lang engines");
rust_kernel_init();
cpp_kernel_init();
sub_kernel_init();
@@ -178,6 +189,7 @@ static void subos_modular_core_boot(void) {
// Concurrency Primitives: Wait Queues, Futexes & Tiny RCU
printk(KERN_INFO "[9/14] Initializing Wait Queues, Futex Hash & Tiny RCU... ");
boot_logo_splash_progress(65, "Initializing concurrency primitives");
wait_subsystem_init();
futex_init();
rcu_init();
@@ -196,6 +208,7 @@ static void subos_modular_core_boot(void) {
// Virtual File System & Multi-Filesystem Support
printk(KERN_INFO "[11/14] Mounting Virtual File System (VFS, devfs, procfs, sysfs)... ");
boot_logo_splash_progress(78, "Mounting the virtual file system");
vfs_init();
sysfs_init();
kobject_subsystem_init();
@@ -206,6 +219,7 @@ static void subos_modular_core_boot(void) {
// Kernel Core: Signals, Modules, Syscalls, Tracing, Syslog, Metrics, Crond & Systemd
printk(KERN_INFO "[12/14] Initializing Syslog, Metrics, Cron, Tracing, BPF & Services... ");
boot_logo_splash_progress(88, "Starting kernel services");
signal_init();
workqueue_init();
syscall_init();
@@ -220,6 +234,7 @@ static void subos_modular_core_boot(void) {
// Preemptive Multi-Tasking & Userland
printk(KERN_INFO "[13/14] Initializing Preemptive Task Scheduler & LazyBox... ");
boot_logo_splash_progress(95, "Starting the scheduler and userland");
sched_init();
lazybox_init();
ktest_init();
@@ -231,6 +246,9 @@ static void subos_modular_core_boot(void) {
arch_enable_interrupts();
printk(ANSI_BRIGHT_GREEN "ACTIVE\n" ANSI_RESET);
// Return the screen to the console before handing over to the shell.
boot_logo_splash_end();
// Launch Shell
shell_run();
@@ -245,6 +263,8 @@ void kernel_main(void* memory_map, uint64_t memory_map_count) {
serial_init();
printk_init();
boot_logo_print_text();
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit [%s] Modular Monolithic Kernel %s\n" ANSI_RESET, arch_get_name(), kernel_get_version());
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
@@ -276,6 +296,8 @@ void kernel_main_aarch64(void) {
arch_early_init();
printk_init();
boot_logo_print_text();
printk(ANSI_BRIGHT_CYAN "=================================================================\n" ANSI_RESET);
printk(ANSI_BRIGHT_CYAN " SUB-OS 64-Bit [%s] Modular Monolithic Kernel %s\n" ANSI_RESET, arch_get_name(), kernel_get_version());
printk(ANSI_BRIGHT_CYAN "=================================================================\n\n" ANSI_RESET);
+28 -2
View File
@@ -12,6 +12,26 @@ static size_t dmesg_head = 0;
static size_t dmesg_total = 0;
static spinlock_t printk_lock = SPINLOCK_INIT;
// Console redirection state. `sink_active` guards against a sink that calls
// printk itself, which would otherwise recurse until the stack ran out.
static printk_sink_fn_t sink_fn = NULL;
static void* sink_ctx = NULL;
static bool sink_active = false;
void printk_set_sink(printk_sink_fn_t fn, void* ctx) {
sink_fn = fn;
sink_ctx = ctx;
}
void printk_clear_sink(void) {
sink_fn = NULL;
sink_ctx = NULL;
}
bool printk_has_sink(void) {
return sink_fn != NULL;
}
void printk_init(void) {
memset(dmesg_buffer, 0, sizeof(dmesg_buffer));
dmesg_head = 0;
@@ -42,8 +62,14 @@ int vprintk(const char* fmt, va_list args) {
len -= 2;
}
// 1. Output to active TTY console
tty_write(display_ptr, (size_t)len);
// 1. Output to the active TTY console, or to the installed sink instead.
if (sink_fn && !sink_active) {
sink_active = true;
sink_fn(display_ptr, (size_t)len, sink_ctx);
sink_active = false;
} else if (!sink_fn) {
tty_write(display_ptr, (size_t)len);
}
// 2. Output to serial console (COM1 on x86, PL011 on ARM/AArch64)
#if defined(__aarch64__) || defined(__arm__) || defined(__armv8i__)