term: Introduce quiet mode
diff --git a/CONFIG.md b/CONFIG.md
index acc5df0e..a9dd8fca 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -82,6 +82,7 @@ Some keys take *URIs* as values; these are described in the next section.
* `EDITOR_HIGHLIGHTING` - If set to `no`, syntax highlighting in the editor will be disabled. Defaults to `yes`.
* `EDITOR_VALIDATION` - If set to `no`, the editor will not alert you about invalid keys / syntax errors. Defaults to `yes`.
* `VERBOSE` - If set to `yes`, print additional information during boot. Defaults to not verbose.
+* `QUIET` - If set to `yes`, enable quiet mode, where all screen output except panics and important warnings is suppressed.
* `RANDOMISE_MEMORY` - If set to `yes`, randomise the contents of RAM at bootup in order to find bugs related to non zeroed memory or for security reasons. This option will slow down boot time significantly.
* `RANDOMIZE_MEMORY` - Alias of `RANDOMISE_MEMORY`.
diff --git a/stage23/entry.s2.c b/stage23/entry.s2.c
index 65921f54..e41dbaa3 100644
--- a/stage23/entry.s2.c
+++ b/stage23/entry.s2.c
@@ -44,6 +44,7 @@ static bool stage3_init(struct volume *part) {
stage3_found = true;
if (stage3->size != (size_t)limine_sys_size) {
+ term_textmode();
print("limine.sys size incorrect.\n");
return false;
}
@@ -55,6 +56,7 @@ static bool stage3_init(struct volume *part) {
fclose(stage3);
if (memcmp(build_id_s2 + 16, build_id_s3 + 16, 20) != 0) {
+ term_textmode();
print("limine.sys build ID mismatch.\n");
return false;
}
@@ -76,11 +78,11 @@ void entry(uint8_t boot_drive, int boot_from) {
if (!a20_enable())
panic("Could not enable A20 line");
+ term_notready();
+
init_e820();
init_memmap();
- term_textmode();
-
init_idt();
disk_create_index();
@@ -98,14 +100,17 @@ void entry(uint8_t boot_drive, int boot_from) {
}
);
- if (!stage3_found)
+ if (!stage3_found) {
+ term_textmode();
print("\n"
"!! Stage 3 file not found!\n"
"!! Have you copied limine.sys to the root or /boot directories of\n"
"!! one of the partitions on the boot device?\n\n");
+ }
- if (!stage3_loaded)
+ if (!stage3_loaded) {
panic("Failed to load stage 3.");
+ }
__attribute__((noreturn))
void (*stage3)(int boot_from) = (void *)stage3_addr;
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index 3854d0da..ef07aff8 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -63,6 +63,8 @@ void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
print("WARNING: Failed to disable watchdog timer!\n");
}
+ term_notready();
+
init_memmap();
disk_create_index();
@@ -136,6 +138,9 @@ void stage3_common(void) {
}
);
+ char *quiet_str = config_get_value(NULL, 0, "QUIET");
+ quiet = quiet_str != NULL && strcmp(quiet_str, "yes") == 0;
+
char *verbose_str = config_get_value(NULL, 0, "VERBOSE");
verbose = verbose_str != NULL && strcmp(verbose_str, "yes") == 0;
diff --git a/stage23/lib/blib.h b/stage23/lib/blib.h
index 4e8a4704..6df048fd 100644
--- a/stage23/lib/blib.h
+++ b/stage23/lib/blib.h
@@ -32,7 +32,7 @@ extern struct volume *boot_volume;
extern bool stage3_loaded;
#endif
-extern bool verbose;
+extern bool verbose, quiet;
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
diff --git a/stage23/lib/blib.s2.c b/stage23/lib/blib.s2.c
index a2a73c43..3158b2a0 100644
--- a/stage23/lib/blib.s2.c
+++ b/stage23/lib/blib.s2.c
@@ -4,6 +4,7 @@
#include <lib/print.h>
bool verbose = true;
+bool quiet = false;
uint8_t bcd_to_int(uint8_t val) {
return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;
diff --git a/stage23/lib/panic.s2.c b/stage23/lib/panic.s2.c
index d444523d..812072f7 100644
--- a/stage23/lib/panic.s2.c
+++ b/stage23/lib/panic.s2.c
@@ -15,6 +15,8 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
va_start(args, fmt);
+ quiet = false;
+
if (term_backend == NOT_READY) {
#if bios == 1
term_textmode();
diff --git a/stage23/lib/term.c b/stage23/lib/term.c
index fe114858..be394736 100644
--- a/stage23/lib/term.c
+++ b/stage23/lib/term.c
@@ -14,11 +14,15 @@ void term_deinit(void) {
gterm_deinit();
}
- term_backend = NOT_READY;
+ term_notready();
}
void term_vbe(size_t width, size_t height) {
- term_backend = NOT_READY;
+ term_notready();
+
+ if (quiet) {
+ return;
+ }
if (!gterm_init(&term_rows, &term_cols, width, height)) {
#if bios == 1
diff --git a/stage23/lib/term.h b/stage23/lib/term.h
index 0734cc35..6c284fa5 100644
--- a/stage23/lib/term.h
+++ b/stage23/lib/term.h
@@ -48,6 +48,7 @@ void term_reinit(void);
void term_deinit(void);
void term_vbe(size_t width, size_t height);
void term_textmode(void);
+void term_notready(void);
void term_putchar(uint8_t c);
void term_write(uint64_t buf, uint64_t count);
@@ -95,12 +96,10 @@ extern void (*term_callback)(uint64_t, uint64_t, uint64_t, uint64_t);
extern bool term_autoflush;
inline void reset_term(void) {
- if (term_backend != NOT_READY) {
- term_autoflush = true;
- enable_cursor();
- clear(true);
- term_double_buffer_flush();
- }
+ term_autoflush = true;
+ enable_cursor();
+ clear(true);
+ term_double_buffer_flush();
}
#endif
diff --git a/stage23/lib/term.s2.c b/stage23/lib/term.s2.c
index 34db61b0..c81dae38 100644
--- a/stage23/lib/term.s2.c
+++ b/stage23/lib/term.s2.c
@@ -16,6 +16,66 @@ int term_backend = NOT_READY;
size_t term_rows, term_cols;
bool term_runtime = false;
+static void notready_raw_putchar(uint8_t c) {
+ (void)c;
+}
+static void notready_clear(bool move) {
+ (void)move;
+}
+static void notready_void(void) {}
+static void notready_set_cursor_pos(size_t x, size_t y) {
+ (void)x; (void)y;
+}
+static void notready_get_cursor_pos(size_t *x, size_t *y) {
+ *x = 0;
+ *y = 0;
+}
+static void notready_size_t(size_t n) {
+ (void)n;
+}
+static bool notready_disable(void) {
+ return false;
+}
+static void notready_move_character(size_t a, size_t b, size_t c, size_t d) {
+ (void)a; (void)b; (void)c; (void)d;
+}
+static uint64_t notready_context_size(void) {
+ return 0;
+}
+static void notready_uint64_t(uint64_t n) {
+ (void)n;
+}
+
+void term_notready(void) {
+ term_backend = NOT_READY;
+
+ raw_putchar = notready_raw_putchar;
+ clear = notready_clear;
+ enable_cursor = notready_void;
+ disable_cursor = notready_disable;
+ set_cursor_pos = notready_set_cursor_pos;
+ get_cursor_pos = notready_get_cursor_pos;
+ set_text_fg = notready_size_t;
+ set_text_bg = notready_size_t;
+ set_text_fg_bright = notready_size_t;
+ set_text_bg_bright = notready_size_t;
+ set_text_fg_default = notready_void;
+ set_text_bg_default = notready_void;
+ scroll_disable = notready_disable;
+ scroll_enable = notready_void;
+ term_move_character = notready_move_character;
+ term_scroll = notready_void;
+ term_swap_palette = notready_void;
+ term_double_buffer_flush = notready_void;
+ term_context_size = notready_context_size;
+ term_context_save = notready_uint64_t;
+ term_context_restore = notready_uint64_t;
+ term_full_refresh = notready_void;
+
+ term_rows = 100;
+ term_cols = 100;
+}
+
void (*raw_putchar)(uint8_t c);
void (*clear)(bool move);
void (*enable_cursor)(void);
@@ -90,11 +150,16 @@ void term_reinit(void) {
g_select = 0;
charsets[0] = CHARSET_DEFAULT;
charsets[1] = CHARSET_DEC_SPECIAL;
+ term_autoflush = true;
}
#if bios == 1
void term_textmode(void) {
- term_backend = NOT_READY;
+ term_notready();
+
+ if (quiet) {
+ return;
+ }
init_vga_textmode(&term_rows, &term_cols, true);
diff --git a/stage23/protos/stivale2.c b/stage23/protos/stivale2.c
index c89b0ef6..5116dcba 100644
--- a/stage23/protos/stivale2.c
+++ b/stage23/protos/stivale2.c
@@ -456,6 +456,8 @@ failed_to_load_header_section:
struct stivale2_header_tag_terminal *terminal_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_TERMINAL_ID);
if (bits == 64 && terminal_hdr_tag != NULL) {
+ quiet = false;
+
if (bios &&
((avtag == NULL && hdrtag == NULL) || (avtag != NULL && preference == 1))) {
term_textmode();
