menu: Move protocol logic from entry.s3.c to menu.c
This commit is contained in:
parent
d0e0248f9c
commit
f50bbcd9a2
2
Makefile
2
Makefile
|
@ -397,7 +397,7 @@ full-hybrid-test:
|
||||||
sudo cp -rv test/* test_image/boot/
|
sudo cp -rv test/* test_image/boot/
|
||||||
xorriso -as mkisofs -b boot/limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine-eltorito-efi.bin -efi-boot-part --efi-boot-image --protective-msdos-label test_image/ -o test.iso
|
xorriso -as mkisofs -b boot/limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot boot/limine-eltorito-efi.bin -efi-boot-part --efi-boot-image --protective-msdos-label test_image/ -o test.iso
|
||||||
$(BINDIR)/limine-install test.iso
|
$(BINDIR)/limine-install test.iso
|
||||||
qemu-system-x86_64 -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
||||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -hda test.iso -debugcon stdio
|
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-x64/OVMF.fd -net none -smp 4 -hda test.iso -debugcon stdio
|
||||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-ia32/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-ia32/OVMF.fd -net none -smp 4 -cdrom test.iso -debugcon stdio
|
||||||
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-ia32/OVMF.fd -net none -smp 4 -hda test.iso -debugcon stdio
|
qemu-system-x86_64 -m 512M -M q35 -bios ovmf-ia32/OVMF.fd -net none -smp 4 -hda test.iso -debugcon stdio
|
||||||
|
|
|
@ -13,12 +13,6 @@
|
||||||
#include <fs/file.h>
|
#include <fs/file.h>
|
||||||
#include <lib/elf.h>
|
#include <lib/elf.h>
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <protos/stivale.h>
|
|
||||||
#include <protos/stivale2.h>
|
|
||||||
#include <protos/linux.h>
|
|
||||||
#include <protos/chainload.h>
|
|
||||||
#include <protos/multiboot1.h>
|
|
||||||
#include <protos/multiboot2.h>
|
|
||||||
#include <menu.h>
|
#include <menu.h>
|
||||||
#include <pxe/pxe.h>
|
#include <pxe/pxe.h>
|
||||||
#include <pxe/tftp.h>
|
#include <pxe/tftp.h>
|
||||||
|
@ -163,53 +157,5 @@ void stage3_common(void) {
|
||||||
print("Boot partition: %d\n", boot_volume->partition);
|
print("Boot partition: %d\n", boot_volume->partition);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool disable_timeout = false;
|
menu(true);
|
||||||
|
|
||||||
menu_again:;
|
|
||||||
char *cmdline;
|
|
||||||
char *config = menu(&cmdline, disable_timeout);
|
|
||||||
|
|
||||||
char *proto = config_get_value(config, 0, "PROTOCOL");
|
|
||||||
if (proto == NULL) {
|
|
||||||
printv("PROTOCOL not specified, using autodetection...\n");
|
|
||||||
autodetect:
|
|
||||||
stivale2_load(config, cmdline);
|
|
||||||
stivale_load(config, cmdline);
|
|
||||||
multiboot2_load(config, cmdline);
|
|
||||||
multiboot1_load(config, cmdline);
|
|
||||||
linux_load(config, cmdline);
|
|
||||||
panic("Kernel protocol autodetection failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale")) {
|
|
||||||
ret = stivale_load(config, cmdline);
|
|
||||||
} else if (!strcmp(proto, "stivale2")) {
|
|
||||||
ret = stivale2_load(config, cmdline);
|
|
||||||
} else if (!strcmp(proto, "linux")) {
|
|
||||||
ret = linux_load(config, cmdline);
|
|
||||||
} else if (!strcmp(proto, "multiboot1") || !strcmp(proto, "multiboot")) {
|
|
||||||
ret = multiboot1_load(config, cmdline);
|
|
||||||
} else if (!strcmp(proto, "multiboot2")) {
|
|
||||||
ret = multiboot2_load(config, cmdline);
|
|
||||||
} else if (!strcmp(proto, "chainload")) {
|
|
||||||
chainload(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
print("WARNING: Unsupported protocol specified: %s.\n", proto);
|
|
||||||
} else {
|
|
||||||
print("WARNING: Incorrect protocol specified for kernel.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print(" Press A to attempt autodetection or any other key to return to menu.\n");
|
|
||||||
|
|
||||||
int c = getchar();
|
|
||||||
if (c == 'a' || c == 'A') {
|
|
||||||
goto autodetect;
|
|
||||||
} else {
|
|
||||||
disable_timeout = true;
|
|
||||||
goto menu_again;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
110
stage23/menu.c
110
stage23/menu.c
|
@ -13,6 +13,12 @@
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <drivers/vbe.h>
|
#include <drivers/vbe.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
|
#include <protos/stivale.h>
|
||||||
|
#include <protos/stivale2.h>
|
||||||
|
#include <protos/linux.h>
|
||||||
|
#include <protos/chainload.h>
|
||||||
|
#include <protos/multiboot1.h>
|
||||||
|
#include <protos/multiboot2.h>
|
||||||
|
|
||||||
static char *menu_branding = NULL;
|
static char *menu_branding = NULL;
|
||||||
static char *menu_branding_colour = NULL;
|
static char *menu_branding_colour = NULL;
|
||||||
|
@ -518,7 +524,47 @@ static size_t print_tree(const char *shift, size_t level, size_t base_index, siz
|
||||||
return max_entries;
|
return max_entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *menu(char **cmdline, bool disable_timeout) {
|
#if defined (__x86_64__)
|
||||||
|
__attribute__((used))
|
||||||
|
static uintptr_t stack_at_first_entry = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((noreturn, naked))
|
||||||
|
void menu(__attribute__((unused)) bool timeout_enabled) {
|
||||||
|
#if defined (__i386__)
|
||||||
|
asm volatile (
|
||||||
|
"call 1f\n\t"
|
||||||
|
"1:\n\t"
|
||||||
|
"pop %eax\n\t"
|
||||||
|
"add $(2f - 1b), %eax\n\t"
|
||||||
|
"cmpl $0, (%eax)\n\t"
|
||||||
|
"jne 1f\n\t"
|
||||||
|
"mov %esp, (%eax)\n\t"
|
||||||
|
"jmp _menu\n\t"
|
||||||
|
"1:\n\t"
|
||||||
|
"mov 4(%esp), %edi\n\t"
|
||||||
|
"mov (%eax), %esp\n\t"
|
||||||
|
"push %edi\n\t"
|
||||||
|
"call _menu\n\t"
|
||||||
|
"2:\n\t"
|
||||||
|
".long 0"
|
||||||
|
);
|
||||||
|
#elif defined (__x86_64__)
|
||||||
|
asm volatile (
|
||||||
|
"xor %eax, %eax\n\t"
|
||||||
|
"cmp %rax, stack_at_first_entry(%rip)\n\t"
|
||||||
|
"jne 1f\n\t"
|
||||||
|
"mov %rsp, stack_at_first_entry(%rip)\n\t"
|
||||||
|
"jmp _menu\n\t"
|
||||||
|
"1:\n\t"
|
||||||
|
"mov stack_at_first_entry(%rip), %rsp\n\t"
|
||||||
|
"jmp _menu"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((noreturn, used))
|
||||||
|
static void _menu(bool timeout_enabled) {
|
||||||
menu_branding = config_get_value(NULL, 0, "MENU_BRANDING");
|
menu_branding = config_get_value(NULL, 0, "MENU_BRANDING");
|
||||||
if (menu_branding == NULL)
|
if (menu_branding == NULL)
|
||||||
menu_branding = "Limine " LIMINE_VERSION;
|
menu_branding = "Limine " LIMINE_VERSION;
|
||||||
|
@ -549,7 +595,7 @@ char *menu(char **cmdline, bool disable_timeout) {
|
||||||
timeout = strtoui(timeout_config, NULL, 10);
|
timeout = strtoui(timeout_config, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disable_timeout) {
|
if (!timeout_enabled) {
|
||||||
skip_timeout = true;
|
skip_timeout = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,6 +749,8 @@ refresh:
|
||||||
|
|
||||||
term_double_buffer_flush();
|
term_double_buffer_flush();
|
||||||
|
|
||||||
|
char *cmdline = NULL;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = getchar();
|
c = getchar();
|
||||||
timeout_aborted:
|
timeout_aborted:
|
||||||
|
@ -724,12 +772,12 @@ timeout_aborted:
|
||||||
selected_menu_entry->expanded = !selected_menu_entry->expanded;
|
selected_menu_entry->expanded = !selected_menu_entry->expanded;
|
||||||
goto refresh;
|
goto refresh;
|
||||||
}
|
}
|
||||||
*cmdline = config_get_value(selected_menu_entry->body, 0, "KERNEL_CMDLINE");
|
cmdline = config_get_value(selected_menu_entry->body, 0, "KERNEL_CMDLINE");
|
||||||
if (!*cmdline) {
|
if (!cmdline) {
|
||||||
*cmdline = config_get_value(selected_menu_entry->body, 0, "CMDLINE");
|
cmdline = config_get_value(selected_menu_entry->body, 0, "CMDLINE");
|
||||||
}
|
}
|
||||||
if (!*cmdline) {
|
if (!cmdline) {
|
||||||
*cmdline = "";
|
cmdline = "";
|
||||||
}
|
}
|
||||||
if (term_backend == NOT_READY) {
|
if (term_backend == NOT_READY) {
|
||||||
#if bios == 1
|
#if bios == 1
|
||||||
|
@ -740,7 +788,7 @@ timeout_aborted:
|
||||||
} else {
|
} else {
|
||||||
reset_term();
|
reset_term();
|
||||||
}
|
}
|
||||||
return selected_menu_entry->body;
|
goto post_menu;
|
||||||
case 'e': {
|
case 'e': {
|
||||||
if (editor_enabled) {
|
if (editor_enabled) {
|
||||||
if (selected_menu_entry->sub != NULL)
|
if (selected_menu_entry->sub != NULL)
|
||||||
|
@ -761,4 +809,50 @@ timeout_aborted:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post_menu:
|
||||||
|
char *config = selected_menu_entry->body;
|
||||||
|
|
||||||
|
char *proto = config_get_value(config, 0, "PROTOCOL");
|
||||||
|
if (proto == NULL) {
|
||||||
|
printv("PROTOCOL not specified, using autodetection...\n");
|
||||||
|
autodetect:
|
||||||
|
stivale2_load(config, cmdline);
|
||||||
|
stivale_load(config, cmdline);
|
||||||
|
multiboot2_load(config, cmdline);
|
||||||
|
multiboot1_load(config, cmdline);
|
||||||
|
linux_load(config, cmdline);
|
||||||
|
panic("Kernel protocol autodetection failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale")) {
|
||||||
|
ret = stivale_load(config, cmdline);
|
||||||
|
} else if (!strcmp(proto, "stivale2")) {
|
||||||
|
ret = stivale2_load(config, cmdline);
|
||||||
|
} else if (!strcmp(proto, "linux")) {
|
||||||
|
ret = linux_load(config, cmdline);
|
||||||
|
} else if (!strcmp(proto, "multiboot1") || !strcmp(proto, "multiboot")) {
|
||||||
|
ret = multiboot1_load(config, cmdline);
|
||||||
|
} else if (!strcmp(proto, "multiboot2")) {
|
||||||
|
ret = multiboot2_load(config, cmdline);
|
||||||
|
} else if (!strcmp(proto, "chainload")) {
|
||||||
|
chainload(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
print("WARNING: Unsupported protocol specified: %s.\n", proto);
|
||||||
|
} else {
|
||||||
|
print("WARNING: Incorrect protocol specified for kernel.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print(" Press A to attempt autodetection or any other key to return to menu.\n");
|
||||||
|
|
||||||
|
c = getchar();
|
||||||
|
if (c == 'a' || c == 'A') {
|
||||||
|
goto autodetect;
|
||||||
|
} else {
|
||||||
|
menu(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
char *menu(char **cmdline_ret, bool disable_timeout);
|
__attribute__((noreturn))
|
||||||
|
void menu(bool timeout_enabled);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue