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!
