From 47bb8ce3fa1340f97c25a406204f66c592a72dfb Mon Sep 17 00:00:00 2001 From: pitust Date: Fri, 26 Nov 2021 12:09:09 +0000 Subject: [PATCH 1/2] fwcfg: implement the fw_cfg interface --- Makefile | 24 +++++++++ stage23/drivers/fwcfg.h | 10 ++++ stage23/drivers/fwcfg.s2.c | 100 +++++++++++++++++++++++++++++++++++++ stage23/lib/config.c | 4 +- stage23/lib/uri.c | 14 ++++++ test/limine-fwcfg.cfg | 28 +++++++++++ test/limine.cfg | 1 + 7 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 stage23/drivers/fwcfg.h create mode 100644 stage23/drivers/fwcfg.s2.c create mode 100644 test/limine-fwcfg.cfg diff --git a/Makefile b/Makefile index 5d7f71a5..fef2da17 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,30 @@ echfs-test: $(BINDIR)/limine-install test.hdd qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio +.PHONY: fwcfg-common fwcfg-test fwcfg-simple-test +fwcfg-common: + $(MAKE) test-clean + $(MAKE) limine-bios + $(MAKE) limine-install + $(MAKE) -C test + rm -rf test_image/ + mkdir -p test_image/boot + cp -rv $(BINDIR)/* test_image/boot/ + xorriso -as mkisofs -b boot/limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table test_image/ -o test.iso + +fwcfg-simple-test: + $(MAKE) fwcfg-common + qemu-system-x86_64 -net none -smp 4 -cdrom test.iso -debugcon stdio \ + -fw_cfg opt/org.limine-bootloader.background,file=test/bg.bmp \ + -fw_cfg opt/org.limine-bootloader.kernel,file=test/test.elf + +fwcfg-test: + $(MAKE) fwcfg-common + qemu-system-x86_64 -net none -smp 4 -cdrom test.iso -debugcon stdio \ + -fw_cfg opt/org.limine-bootloader.config,file=test/limine-fwcfg.cfg \ + -fw_cfg opt/org.limine-bootloader.background,file=test/bg.bmp \ + -fw_cfg opt/org.limine-bootloader.kernel,file=test/test.elf + .PHONY: ext2-test ext2-test: $(MAKE) test-clean diff --git a/stage23/drivers/fwcfg.h b/stage23/drivers/fwcfg.h new file mode 100644 index 00000000..c6048e11 --- /dev/null +++ b/stage23/drivers/fwcfg.h @@ -0,0 +1,10 @@ +#ifndef __DRIVERS__FWCFG_H__ +#define __DRIVERS__FWCFG_H__ + +#include +#include +#include + +bool fwcfg_open(struct file_handle *handle, const char *name); + +#endif diff --git a/stage23/drivers/fwcfg.s2.c b/stage23/drivers/fwcfg.s2.c new file mode 100644 index 00000000..1c23e114 --- /dev/null +++ b/stage23/drivers/fwcfg.s2.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + +struct dma_descr { + uint32_t control; + uint32_t length; + uint64_t address; +}; + +struct fw_cfg_file { + uint32_t size; + uint16_t select; + uint16_t reserved; + char name[56]; +}; +struct fw_cfg_files { + uint32_t count; + struct fw_cfg_file f[]; +}; + +static uint16_t bswap16(uint16_t value) { + uint8_t* value_ptr = (uint8_t*)&value; + return value_ptr[0]<<8|value_ptr[1]; +} + +static uint32_t bswap32(uint32_t value) { + uint8_t* value_ptr = (uint8_t*)&value; + return value_ptr[0]<<24|value_ptr[1]<<16|value_ptr[2]<<8|value_ptr[3]; +} + +static void fwcfg_disp_read(uint16_t sel, uint32_t outsz, uint8_t* outbuf) { + outw(0x510, sel); + for (uint32_t i = 0;i < outsz;i++) outbuf[i] = inb(0x511); +} + +static struct fw_cfg_files* filebuf = NULL; +static const char* simple_mode_config = + "TIMEOUT=0\n" + ":simple mode config\n" + "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; + +static const char* simple_mode_bg_config = + "TIMEOUT=0\n" + "GRAPHICS=yes\n" + "THEME_BACKGROUND=50000000\n" + "BACKGROUND_PATH=fwcfg:///opt/org.limine-bootloader.background\n" + "BACKGROUND_STYLE=stretched\n" + ":simple mode config\n" + "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; + +static bool simple_mode = false; + +bool fwcfg_open(struct file_handle *handle, const char *name) { + char sig[5] = { 0 }; + fwcfg_disp_read(/* signature */ 0x0000, 4, (uint8_t*)sig); + if (strcmp(sig, "QEMU")) return false; + + uint32_t count; + fwcfg_disp_read(0x0019, 4, (uint8_t*)&count); + count = bswap32(count); + + if (!filebuf) { + filebuf = (struct fw_cfg_files*)ext_mem_alloc(count * 64 + 4); + fwcfg_disp_read(0x0019, count * 64 + 4, (uint8_t*)filebuf); + } + + bool has_kernel = false, has_background = false; + for (uint32_t i = 0;i < count;i++) { + if (!strncmp(filebuf->f[i].name, name, 56)) { + uint16_t sel = bswap16(filebuf->f[i].select); + handle->size = bswap32(filebuf->f[i].size); + handle->is_memfile = true; + uint8_t* buf = (uint8_t*)(handle->fd = ext_mem_alloc(handle->size)); + fwcfg_disp_read(sel, handle->size, buf); + return true; + } + if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.background", 56)) { + has_background = true; + } + if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.kernel", 56)) { + has_kernel = true; + } + } + + if (has_kernel && !strcmp(name, "opt/org.limine-bootloader.config")) { + const char* conf = has_background ? simple_mode_bg_config : simple_mode_config; + handle->size = strlen(conf); + handle->is_memfile = true; + char* buf = (char*)(handle->fd = ext_mem_alloc(handle->size + 1)); + strcpy(buf, conf); + simple_mode = true; + return true; + } + + return false; +} diff --git a/stage23/lib/config.c b/stage23/lib/config.c index 130bac71..1e8a8717 100644 --- a/stage23/lib/config.c +++ b/stage23/lib/config.c @@ -1,3 +1,4 @@ +#include "lib/uri.h" #include #include #include @@ -21,7 +22,8 @@ int init_config_disk(struct volume *part) { if ((f = fopen(part, "/limine.cfg")) == NULL && (f = fopen(part, "/boot/limine.cfg")) == NULL - && (f = fopen(part, "/EFI/BOOT/limine.cfg")) == NULL) { + && (f = fopen(part, "/EFI/BOOT/limine.cfg")) == NULL + && (f = uri_open("fwcfg:///opt/org.limine-bootloader.config")) == NULL) { return -1; } diff --git a/stage23/lib/uri.c b/stage23/lib/uri.c index da172831..c6d4dba5 100644 --- a/stage23/lib/uri.c +++ b/stage23/lib/uri.c @@ -8,6 +8,7 @@ #include #include #include +#include #include // A URI takes the form of: resource://root/path @@ -132,6 +133,15 @@ static struct file_handle *uri_guid_dispatch(char *guid_str, char *path) { return fopen(volume, path); } +static struct file_handle *uri_fwcfg_dispatch(char *path) { + struct file_handle *ret = ext_mem_alloc(sizeof(struct file_handle)); + if (!fwcfg_open(ret, path)) { + return NULL; + } + + return ret; +} + #if bios == 1 static struct file_handle *uri_tftp_dispatch(char *root, char *path) { uint32_t ip; @@ -210,6 +220,10 @@ struct file_handle *uri_open(char *uri) { } else if (!strcmp(resource, "tftp")) { ret = uri_tftp_dispatch(root, path); #endif + // note: fwcfg MUST be the last on the list due to fwcfg simple mode. + } else if (!strcmp(resource, "fwcfg")) { + if (*root != 0) panic("no root supported in an fwcfg:// uri!"); + ret = uri_fwcfg_dispatch(path); } else { panic("Resource `%s` not valid.", resource); } diff --git a/test/limine-fwcfg.cfg b/test/limine-fwcfg.cfg new file mode 100644 index 00000000..4711e1db --- /dev/null +++ b/test/limine-fwcfg.cfg @@ -0,0 +1,28 @@ +DEFAULT_ENTRY=1 +TIMEOUT=3 +GRAPHICS=yes +VERBOSE=yes + +THEME_BACKGROUND=50000000 + +BACKGROUND_PATH=fwcfg:///opt/org.limine-bootloader.background +BACKGROUND_STYLE=stretched +BACKDROP_COLOUR=008080 + +:fwcfg:// test + +COMMENT=Test of the stivale2 boot protocol. + +# Let's use autodetection +#PROTOCOL=stivale2 +RESOLUTION=800x600 +KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel +KERNEL_CMDLINE=Woah! Another example! + +MODULE_PATH=fwcfg:///opt/org.limine-bootloader.background +MODULE_STRING=yooooo + +# Test that the module string provided to the kernel will be +# the module path since a module string is not specified. +# (cc CONFIG.md stivale2.`MODULE_STRING` section) +MODULE_PATH=fwcfg:///opt/org.limine-bootloader.background diff --git a/test/limine.cfg b/test/limine.cfg index 23ae6778..3b456885 100644 --- a/test/limine.cfg +++ b/test/limine.cfg @@ -98,3 +98,4 @@ KERNEL_CMDLINE=Woah! Another example! MODULE_PATH=odd://1:/boot/bg.bmp MODULE_STRING=yooooo + From ea615eb9c80227b589ba100603b24b63d52aadce Mon Sep 17 00:00:00 2001 From: pitust Date: Sat, 27 Nov 2021 11:01:47 +0000 Subject: [PATCH 2/2] fix my tabs --- stage23/drivers/fwcfg.s2.c | 122 ++++++++++++++++++------------------- stage23/lib/config.c | 2 +- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/stage23/drivers/fwcfg.s2.c b/stage23/drivers/fwcfg.s2.c index 1c23e114..b20c7fa5 100644 --- a/stage23/drivers/fwcfg.s2.c +++ b/stage23/drivers/fwcfg.s2.c @@ -12,10 +12,10 @@ struct dma_descr { }; struct fw_cfg_file { - uint32_t size; - uint16_t select; - uint16_t reserved; - char name[56]; + uint32_t size; + uint16_t select; + uint16_t reserved; + char name[56]; }; struct fw_cfg_files { uint32_t count; @@ -23,78 +23,78 @@ struct fw_cfg_files { }; static uint16_t bswap16(uint16_t value) { - uint8_t* value_ptr = (uint8_t*)&value; - return value_ptr[0]<<8|value_ptr[1]; + uint8_t* value_ptr = (uint8_t*)&value; + return value_ptr[0]<<8|value_ptr[1]; } static uint32_t bswap32(uint32_t value) { - uint8_t* value_ptr = (uint8_t*)&value; - return value_ptr[0]<<24|value_ptr[1]<<16|value_ptr[2]<<8|value_ptr[3]; + uint8_t* value_ptr = (uint8_t*)&value; + return value_ptr[0]<<24|value_ptr[1]<<16|value_ptr[2]<<8|value_ptr[3]; } static void fwcfg_disp_read(uint16_t sel, uint32_t outsz, uint8_t* outbuf) { - outw(0x510, sel); - for (uint32_t i = 0;i < outsz;i++) outbuf[i] = inb(0x511); + outw(0x510, sel); + for (uint32_t i = 0;i < outsz;i++) outbuf[i] = inb(0x511); } static struct fw_cfg_files* filebuf = NULL; static const char* simple_mode_config = - "TIMEOUT=0\n" - ":simple mode config\n" - "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; + "TIMEOUT=0\n" + ":simple mode config\n" + "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; static const char* simple_mode_bg_config = - "TIMEOUT=0\n" - "GRAPHICS=yes\n" - "THEME_BACKGROUND=50000000\n" - "BACKGROUND_PATH=fwcfg:///opt/org.limine-bootloader.background\n" - "BACKGROUND_STYLE=stretched\n" - ":simple mode config\n" - "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; + "TIMEOUT=0\n" + "GRAPHICS=yes\n" + "THEME_BACKGROUND=50000000\n" + "BACKGROUND_PATH=fwcfg:///opt/org.limine-bootloader.background\n" + "BACKGROUND_STYLE=stretched\n" + ":simple mode config\n" + "KERNEL_PATH=fwcfg:///opt/org.limine-bootloader.kernel"; static bool simple_mode = false; -bool fwcfg_open(struct file_handle *handle, const char *name) { - char sig[5] = { 0 }; - fwcfg_disp_read(/* signature */ 0x0000, 4, (uint8_t*)sig); - if (strcmp(sig, "QEMU")) return false; - - uint32_t count; - fwcfg_disp_read(0x0019, 4, (uint8_t*)&count); - count = bswap32(count); - - if (!filebuf) { - filebuf = (struct fw_cfg_files*)ext_mem_alloc(count * 64 + 4); - fwcfg_disp_read(0x0019, count * 64 + 4, (uint8_t*)filebuf); - } +bool fwcfg_open(struct file_handle *handle, const char *name) { + char sig[5] = { 0 }; + fwcfg_disp_read(/* signature */ 0x0000, 4, (uint8_t*)sig); + if (strcmp(sig, "QEMU")) return false; + + uint32_t count; + fwcfg_disp_read(0x0019, 4, (uint8_t*)&count); + count = bswap32(count); + + if (!filebuf) { + filebuf = (struct fw_cfg_files*)ext_mem_alloc(count * 64 + 4); + fwcfg_disp_read(0x0019, count * 64 + 4, (uint8_t*)filebuf); + } - bool has_kernel = false, has_background = false; - for (uint32_t i = 0;i < count;i++) { - if (!strncmp(filebuf->f[i].name, name, 56)) { - uint16_t sel = bswap16(filebuf->f[i].select); - handle->size = bswap32(filebuf->f[i].size); - handle->is_memfile = true; - uint8_t* buf = (uint8_t*)(handle->fd = ext_mem_alloc(handle->size)); - fwcfg_disp_read(sel, handle->size, buf); - return true; - } - if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.background", 56)) { - has_background = true; - } - if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.kernel", 56)) { - has_kernel = true; - } - } - - if (has_kernel && !strcmp(name, "opt/org.limine-bootloader.config")) { - const char* conf = has_background ? simple_mode_bg_config : simple_mode_config; - handle->size = strlen(conf); - handle->is_memfile = true; - char* buf = (char*)(handle->fd = ext_mem_alloc(handle->size + 1)); - strcpy(buf, conf); - simple_mode = true; - return true; - } + bool has_kernel = false, has_background = false; + for (uint32_t i = 0;i < count;i++) { + if (!strncmp(filebuf->f[i].name, name, 56)) { + uint16_t sel = bswap16(filebuf->f[i].select); + handle->size = bswap32(filebuf->f[i].size); + handle->is_memfile = true; + uint8_t* buf = (uint8_t*)(handle->fd = ext_mem_alloc(handle->size)); + fwcfg_disp_read(sel, handle->size, buf); + return true; + } + if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.background", 56)) { + has_background = true; + } + if (!strncmp(filebuf->f[i].name, "opt/org.limine-bootloader.kernel", 56)) { + has_kernel = true; + } + } + + if (has_kernel && !strcmp(name, "opt/org.limine-bootloader.config")) { + const char* conf = has_background ? simple_mode_bg_config : simple_mode_config; + handle->size = strlen(conf); + handle->is_memfile = true; + char* buf = (char*)(handle->fd = ext_mem_alloc(handle->size + 1)); + strcpy(buf, conf); + simple_mode = true; + return true; + } - return false; + return false; } diff --git a/stage23/lib/config.c b/stage23/lib/config.c index 1e8a8717..9be23996 100644 --- a/stage23/lib/config.c +++ b/stage23/lib/config.c @@ -23,7 +23,7 @@ int init_config_disk(struct volume *part) { if ((f = fopen(part, "/limine.cfg")) == NULL && (f = fopen(part, "/boot/limine.cfg")) == NULL && (f = fopen(part, "/EFI/BOOT/limine.cfg")) == NULL - && (f = uri_open("fwcfg:///opt/org.limine-bootloader.config")) == NULL) { + && (f = uri_open("fwcfg:///opt/org.limine-bootloader.config")) == NULL) { return -1; }