:: commit 168716a2518e9d6a39b0842d7d1282101503b187

mintsuki <mintsuki@protonmail.com> — 2020-11-09 11:31

parents: 495b1570db

misc: Add config file options for specifying the resolution in a granular way. Other misc bug fixes. Fixes #45

diff --git a/CONFIG.md b/CONFIG.md
index c86909b2..88f182e4 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -25,6 +25,7 @@ Some keys take *URIs* as values; these are described in the next section.
 * `TIMEOUT` - Specifies the timeout in seconds before the first *entry* is automatically booted.
 * `DEFAULT_ENTRY` - 0-based entry index of the entry which will be automatically selected at startup. If unspecified, it is `0`.
 * `GRAPHICS` - If set to `yes`, do use graphical VESA framebuffer for the boot menu, else use text mode.
+* `MENU_RESOLUTION` - Specify screen resolution to be used by the Limine menu in the form `<width>x<height>`. This will *only* affect the menu, not any booted OS. If not specified, Limine will pick a resolution automatically. If the resolution is not available, Limine will pick another one automatically. Ignored if `GRAPHICS` is not `yes`.
 * `THEME_COLOURS` - Specifies the colour palette used by the terminal (AARRGGBB). It is a `;` separated array of 8 colours: black, red, green, brown, blue, magenta, cyan, and gray, respectively. Ignored if `GRAPHICS` is not `yes`.
 * `THEME_COLORS` - Alias of `THEME_COLOURS`.
 * `THEME_MARGIN` - Set the amount of margin around the terminal. Ignored if `GRAPHICS` is not `yes`.
@@ -52,6 +53,7 @@ Some keys take *URIs* as values; these are described in the next section.
   modules.
   The entries will be matched in order. E.g.: the 1st module path entry will be matched
   to the 1st module string entry that appear, and so on.
+  * `RESOLUTION` - The resolution to be used should the kernel request a graphical framebuffer. This setting takes the form of `<width>x<height>x<bpp>` and *overrides* any resolution requested by the kernel, or automatic resolution requests. If the resolution is not available, Limine will pick another one automatically.
 * Chainload protocol:
   * `DRIVE` - The 1-based BIOS drive to chainload.
   * `PARTITION` - The 1-based BIOS partition to chainload, if omitted, chainload drive.
diff --git a/limine-pxe.bin b/limine-pxe.bin
index 32deb39f..2cec51e0 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index 0a799537..8298c90f 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/drivers/vbe.c b/stage2/drivers/vbe.c
index fd7bf411..7142e76c 100644
--- a/stage2/drivers/vbe.c
+++ b/stage2/drivers/vbe.c
@@ -7,6 +7,7 @@
 #include <lib/real.h>
 #include <lib/print.h>
 #include <lib/image.h>
+#include <lib/config.h>
 #include <mm/pmm.h>
 #include <mm/mtrr.h>
 
@@ -317,7 +318,17 @@ void vbe_putchar(char c) {
 }
 
 bool vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
-    init_vbe(&fbinfo, 0, 0, 0);
+    char buf[32];
+
+    int req_width = 0, req_height = 0, req_bpp = 0;
+
+    if (config_get_value(buf, 0, 32, "MENU_RESOLUTION"))
+        parse_resolution(&req_width, &req_height, &req_bpp, buf);
+
+    // We force bpp to 32
+    req_bpp = 32;
+
+    init_vbe(&fbinfo, req_width, req_height, req_bpp);
 
     // Ensure this is xRGB8888, we only support that for the menu
     if (fbinfo.red_mask_size    != 8
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index dd4ea30f..3112bf4f 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -7,6 +7,32 @@
 
 uint8_t boot_drive;
 
+bool parse_resolution(int *width, int *height, int *bpp, const char *buf) {
+    int res[3] = {0};
+
+    const char *first = buf;
+    for (int i = 0; i < 3; i++) {
+        const char *last;
+        int x = strtoui(first, &last, 10);
+        if (first == last)
+            break;
+        res[i] = x;
+        if (*last == 0)
+            break;
+        first = last + 1;
+    }
+
+    if (res[0] == 0 || res[1] == 0)
+        return false;
+
+    if (res[2] == 0)
+        res[2] = 32;
+
+    *width = res[0], *height = res[1], *bpp = res[2];
+
+    return true;
+}
+
 // This integer sqrt implementation has been adapted from:
 // https://stackoverflow.com/questions/1100090/looking-for-an-efficient-integer-square-root-algorithm-for-arm-thumb2
 uint64_t sqrt(uint64_t a_nInput) {
@@ -53,10 +79,10 @@ __attribute__((noreturn)) void panic(const char *fmt, ...) {
 }
 
 int digit_to_int(char c) {
-    if (c >= 'a' && c <= 'z') {
+    if (c >= 'a' && c <= 'f') {
         return (c - 'a') + 10;
     }
-    if (c >= 'A' && c <= 'Z') {
+    if (c >= 'A' && c <= 'F') {
         return (c - 'A') + 10;
     }
     if (c >= '0' && c <= '9'){
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index b3c75ac2..24fdd866 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -7,6 +7,8 @@
 
 extern uint8_t boot_drive;
 
+bool parse_resolution(int *width, int *height, int *bpp, const char *buf);
+
 uint64_t sqrt(uint64_t a_nInput);
 
 int digit_to_int(char c);
diff --git a/stage2/menu.c b/stage2/menu.c
index 849e12a2..cc31c4bb 100644
--- a/stage2/menu.c
+++ b/stage2/menu.c
@@ -58,10 +58,12 @@ char *menu(void) {
             for (int i = 0; i < 8; i++) {
                 const char *last;
                 uint32_t col = strtoui(first, &last, 16);
-                if (first == last || *last == 0)
+                if (first == last)
                     break;
-                first = last + 1;
                 colourscheme[i] = col;
+                if (*last == 0)
+                    break;
+                first = last + 1;
             }
         }
 
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 6bc579f5..694b9911 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -166,18 +166,19 @@ void stivale_load(char *cmdline) {
     stivale_struct.epoch = time();
     print("stivale: Current epoch: %U\n", stivale_struct.epoch);
 
-    stivale_struct.framebuffer_width  = stivale_hdr.framebuffer_width;
-    stivale_struct.framebuffer_height = stivale_hdr.framebuffer_height;
-    stivale_struct.framebuffer_bpp    = stivale_hdr.framebuffer_bpp;
-
     term_deinit();
 
     if (stivale_hdr.flags & (1 << 0)) {
+        int req_width  = stivale_hdr.framebuffer_width;
+        int req_height = stivale_hdr.framebuffer_height;
+        int req_bpp    = stivale_hdr.framebuffer_bpp;
+
+        if (config_get_value(buf, 0, 128, "RESOLUTION"))
+            parse_resolution(&req_width, &req_height, &req_bpp, buf);
+
         struct vbe_framebuffer_info fbinfo;
-        init_vbe(&fbinfo,
-                 stivale_struct.framebuffer_width,
-                 stivale_struct.framebuffer_height,
-                 stivale_struct.framebuffer_bpp);
+        init_vbe(&fbinfo, req_width, req_height, req_bpp);
+
         stivale_struct.framebuffer_addr   = (uint64_t)fbinfo.framebuffer_addr;
         stivale_struct.framebuffer_width  = fbinfo.framebuffer_width;
         stivale_struct.framebuffer_height = fbinfo.framebuffer_height;
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 5ed09637..f76c9bc2 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -256,15 +256,20 @@ void stivale2_load(char *cmdline) {
     term_deinit();
 
     if (hdrtag != NULL) {
+        int req_width  = hdrtag->framebuffer_width;
+        int req_height = hdrtag->framebuffer_height;
+        int req_bpp    = hdrtag->framebuffer_bpp;
+
+        if (config_get_value(buf, 0, 128, "RESOLUTION"))
+            parse_resolution(&req_width, &req_height, &req_bpp, buf);
+
         struct vbe_framebuffer_info fbinfo;
-        if (init_vbe(&fbinfo,
-                     hdrtag->framebuffer_width,
-                     hdrtag->framebuffer_height,
-                     hdrtag->framebuffer_bpp)) {
+        if (init_vbe(&fbinfo, req_width, req_height, req_bpp)) {
             struct stivale2_struct_tag_framebuffer *tag = conv_mem_alloc(sizeof(struct stivale2_struct_tag_framebuffer));
             tag->tag.identifier = STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID;
 
             tag->memory_model       = STIVALE2_FBUF_MMODEL_RGB;
+            tag->framebuffer_addr   = fbinfo.framebuffer_addr;
             tag->framebuffer_width  = fbinfo.framebuffer_width;
             tag->framebuffer_height = fbinfo.framebuffer_height;
             tag->framebuffer_bpp    = fbinfo.framebuffer_bpp;
diff --git a/test/limine.cfg b/test/limine.cfg
index acdd4a61..6d03271b 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -1,6 +1,7 @@
 DEFAULT_ENTRY=0
 TIMEOUT=3
 GRAPHICS=yes
+MENU_RESOLUTION=1024x768
 E9_OUTPUT=yes
 
 THEME_COLOURS=80000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
@@ -17,5 +18,6 @@ KERNEL_CMDLINE=Hi! This is an example!
 :Stivale2 Test
 
 PROTOCOL=stivale2
+RESOLUTION=640x480x16
 KERNEL_PATH=bios://:1/boot/test.elf
 KERNEL_CMDLINE=Woah! Another example!
tab: 248 wrap: offon