config: Move config code to stage 3
This commit is contained in:
parent
60742ea6a5
commit
1e7ba95230
@ -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..
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -3,14 +3,10 @@
|
||||
#include <stdint.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/config.h>
|
||||
#include <lib/term.h>
|
||||
#include <lib/libc.h>
|
||||
#include <sys/cpu.h>
|
||||
|
||||
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]);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user