From 1e7ba9523046150091fc462a897c26ecdd9c7af7 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 26 Feb 2021 01:30:27 +0100 Subject: [PATCH] config: Move config code to stage 3 --- stage23/Makefile | 5 +++ stage23/lib/blib.c | 2 +- stage23/lib/blib.h | 2 +- stage23/lib/config.c | 9 +++++ stage23/lib/print.c | 40 ++++++++------------ stage23/main.c | 88 ++++++++++++++++++++++++-------------------- 6 files changed, 80 insertions(+), 66 deletions(-) diff --git a/stage23/Makefile b/stage23/Makefile index 9f102cb0..60d4f932 100644 --- a/stage23/Makefile +++ b/stage23/Makefile @@ -4,6 +4,9 @@ OBJCOPY = i386-elf-objcopy OBJDUMP = i386-elf-objdump READELF = i386-elf-readelf +COM_OUTPUT = false +E9_OUTPUT = false + BUILD_ID := $(shell dd if=/dev/urandom count=8 bs=1 | od -An -t x8 | sed 's/^ /0x/') LIMINE_VERSION := $(shell git describe --exact-match --tags `git log -n1 --pretty='%h'` || git log -n1 --pretty='%h') WERROR = -Werror @@ -26,6 +29,8 @@ INTERNAL_CFLAGS = \ -MMD \ -DBUILD_ID=$(BUILD_ID) \ -DLIMINE_VERSION='"$(LIMINE_VERSION)"' \ + -DCOM_OUTPUT=$(COM_OUTPUT) \ + -DE9_OUTPUT=$(E9_OUTPUT) \ -I. \ -I.. diff --git a/stage23/lib/blib.c b/stage23/lib/blib.c index 71325ec9..be43c562 100644 --- a/stage23/lib/blib.c +++ b/stage23/lib/blib.c @@ -22,7 +22,7 @@ extern symbol stage3_addr; extern symbol limine_sys_size; __attribute__((noreturn)) -void (*stage3)(void) = (void *)stage3_addr; +void (*stage3)(int boot_from) = (void *)stage3_addr; bool stage3_init(struct volume *part) { struct file_handle stage3; diff --git a/stage23/lib/blib.h b/stage23/lib/blib.h index 54586682..f38e84de 100644 --- a/stage23/lib/blib.h +++ b/stage23/lib/blib.h @@ -49,7 +49,7 @@ typedef char symbol[]; #define stage3_text __attribute__((section(".stage3_text"))) #define stage3_data __attribute__((section(".stage3_data"))) -__attribute__((noreturn)) extern void (*stage3)(void); +__attribute__((noreturn)) extern void (*stage3)(int boot_from); bool stage3_init(struct volume *part); #endif diff --git a/stage23/lib/config.c b/stage23/lib/config.c index c9c7fa9b..5c53c4db 100644 --- a/stage23/lib/config.c +++ b/stage23/lib/config.c @@ -16,6 +16,7 @@ bool config_ready = false; static char *config_addr; +stage3_text int init_config_disk(struct volume *part) { struct file_handle f; @@ -34,6 +35,7 @@ int init_config_disk(struct volume *part) { return init_config(config_size); } +stage3_text int init_config_pxe(void) { struct tftp_file_handle cfg; if (tftp_open(&cfg, 0, 69, "limine.cfg") @@ -52,6 +54,7 @@ int init_config_pxe(void) { #define DIRECT_CHILD 0 #define INDIRECT_CHILD 1 +stage3_text static int is_child(char *buf, size_t limit, size_t current_depth, size_t index) { if (!config_get_entry_name(buf, index, limit)) @@ -66,6 +69,7 @@ static int is_child(char *buf, size_t limit, return DIRECT_CHILD; } +stage3_text static bool is_directory(char *buf, size_t limit, size_t current_depth, size_t index) { switch (is_child(buf, limit, current_depth + 1, index + 1)) { @@ -79,6 +83,7 @@ static bool is_directory(char *buf, size_t limit, } } +stage3_text static struct menu_entry *create_menu_tree(struct menu_entry *parent, size_t current_depth, size_t index) { struct menu_entry *root = NULL, *prev = NULL; @@ -126,6 +131,7 @@ static struct menu_entry *create_menu_tree(struct menu_entry *parent, struct menu_entry *menu_tree = NULL; +stage3_text int init_config(size_t config_size) { // remove windows carriage returns, if any for (size_t i = 0; i < config_size; i++) { @@ -143,6 +149,7 @@ int init_config(size_t config_size) { return 0; } +stage3_text bool config_get_entry_name(char *ret, size_t index, size_t limit) { char *p = config_addr; @@ -170,6 +177,7 @@ bool config_get_entry_name(char *ret, size_t index, size_t limit) { return true; } +stage3_text char *config_get_entry(size_t *size, size_t index) { char *ret; char *p = config_addr; @@ -205,6 +213,7 @@ cont: return ret; } +stage3_text char *config_get_value(const char *config, size_t index, const char *key) { if (!key) return NULL; diff --git a/stage23/lib/print.c b/stage23/lib/print.c index fa6db87e..05c8cd45 100644 --- a/stage23/lib/print.c +++ b/stage23/lib/print.c @@ -3,14 +3,10 @@ #include #include #include -#include #include #include #include -static int e9_output = -1; -static int com1_output = -1; - static const char *base_digits = "0123456789abcdef"; #define PRINT_BUF_MAX 512 @@ -119,26 +115,19 @@ void print(const char *fmt, ...) { static char print_buf[PRINT_BUF_MAX]; void vprint(const char *fmt, va_list args) { - if (config_ready && e9_output == -1) { - char *e9_output_config = config_get_value(NULL, 0, "E9_OUTPUT"); - e9_output = e9_output_config != NULL && - !strcmp(e9_output_config, "yes"); - } - if (config_ready && com1_output == -1) { - char *com1_output_config = config_get_value(NULL, 0, "COM1_OUTPUT"); - com1_output = com1_output_config != NULL && - !strcmp(com1_output_config, "yes"); + static bool com_initialised = false; - if (com1_output == 1) { - // Init com1 - outb(0x3F8 + 1, 0x00); - outb(0x3F8 + 3, 0x80); - outb(0x3F8 + 0, 0x01); - outb(0x3F8 + 1, 0x00); - outb(0x3F8 + 3, 0x03); - outb(0x3F8 + 2, 0xC7); - outb(0x3F8 + 4, 0x0B); - } + if (COM_OUTPUT && !com_initialised) { + // Init com1 + outb(0x3F8 + 1, 0x00); + outb(0x3F8 + 3, 0x80); + outb(0x3F8 + 0, 0x01); + outb(0x3F8 + 1, 0x00); + outb(0x3F8 + 3, 0x03); + outb(0x3F8 + 2, 0xC7); + outb(0x3F8 + 4, 0x0B); + + com_initialised = true; } size_t print_buf_i = 0; @@ -198,9 +187,10 @@ out: term_write(print_buf, print_buf_i); for (size_t i = 0; i < print_buf_i; i++) { - if (e9_output == 1) + if (E9_OUTPUT) { outb(0xe9, print_buf[i]); - if (com1_output == 1) { + } + if (COM_OUTPUT) { if (print_buf[i] == '\n') outb(0x3f8, '\r'); outb(0x3f8, print_buf[i]); diff --git a/stage23/main.c b/stage23/main.c index 5f9c4d22..97c8ceba 100644 --- a/stage23/main.c +++ b/stage23/main.c @@ -48,53 +48,63 @@ void entry(uint8_t _boot_drive, int boot_from) { volume_create_index(); switch (boot_from) { - case BOOT_FROM_HDD: - case BOOT_FROM_CD: { - print("Boot drive: %x\n", boot_drive); - struct volume boot_volume; - volume_get_by_coord(&boot_volume, boot_drive, -1); - struct volume part = boot_volume; - bool stage3_loaded = false, config_loaded = false; - for (int i = 0; ; i++) { - if (!stage3_loaded && stage3_init(&part)) { - stage3_loaded = true; - print("Stage 3 found and loaded.\n"); - } - if (!config_loaded && !init_config_disk(&part)) { - config_loaded = true; - print("Config file found and loaded.\n"); - boot_partition = i - 1; - } - int ret = part_get(&part, &boot_volume, i); - switch (ret) { - case INVALID_TABLE: - case END_OF_TABLE: - goto break2; + case BOOT_FROM_HDD: + case BOOT_FROM_CD: { + struct volume boot_volume; + volume_get_by_coord(&boot_volume, boot_drive, -1); + struct volume part = boot_volume; + for (int i = 0; ; i++) { + if (stage3_init(&part)) { + print("Stage 3 found and loaded.\n"); + break; + } + int ret = part_get(&part, &boot_volume, i); + switch (ret) { + case INVALID_TABLE: + case END_OF_TABLE: + panic("Stage 3 not found."); + } } + break; } -break2: - if (!stage3_loaded) - panic("Stage 3 not loaded."); - if (!config_loaded) - panic("Config file not found."); - break; } - case BOOT_FROM_PXE: - pxe_init(); - if (init_config_pxe()) { - panic("Failed to load config file"); - } - print("Config loaded via PXE\n"); - break; - } - - stage3(); + stage3(boot_from); } __attribute__((noreturn)) __attribute__((section(".stage3_entry"))) -void stage3_entry(void) { +void stage3_entry(int boot_from) { + switch (boot_from) { + case BOOT_FROM_HDD: + case BOOT_FROM_CD: { + struct volume boot_volume; + volume_get_by_coord(&boot_volume, boot_drive, -1); + struct volume part = boot_volume; + for (int i = 0; ; i++) { + if (!init_config_disk(&part)) { + print("Config file found and loaded.\n"); + boot_partition = i - 1; + break; + } + int ret = part_get(&part, &boot_volume, i); + switch (ret) { + case INVALID_TABLE: + case END_OF_TABLE: + panic("Config file not found."); + } + } + break; + case BOOT_FROM_PXE: + pxe_init(); + if (init_config_pxe()) { + panic("Failed to load config file"); + } + print("Config loaded via PXE\n"); + break; + } + } + char *cmdline; char *config = menu(&cmdline);