Merge pull request #135 from pitust/trunk
fwcfg: implement fw_cfg for kernel/config loading
This commit is contained in:
commit
99c42e7686
24
Makefile
24
Makefile
|
@ -231,6 +231,30 @@ echfs-test:
|
||||||
$(BINDIR)/limine-install test.hdd
|
$(BINDIR)/limine-install test.hdd
|
||||||
qemu-system-x86_64 -net none -smp 4 -hda test.hdd -debugcon stdio
|
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
|
.PHONY: ext2-test
|
||||||
ext2-test:
|
ext2-test:
|
||||||
$(MAKE) test-clean
|
$(MAKE) test-clean
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __DRIVERS__FWCFG_H__
|
||||||
|
#define __DRIVERS__FWCFG_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <lib/blib.h>
|
||||||
|
#include <lib/libc.h>
|
||||||
|
|
||||||
|
bool fwcfg_open(struct file_handle *handle, const char *name);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <lib/libc.h>
|
||||||
|
#include <lib/print.h>
|
||||||
|
#include <mm/pmm.h>
|
||||||
|
#include <lib/blib.h>
|
||||||
|
#include <sys/cpu.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "lib/uri.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <lib/config.h>
|
#include <lib/config.h>
|
||||||
|
@ -21,7 +22,8 @@ int init_config_disk(struct volume *part) {
|
||||||
|
|
||||||
if ((f = fopen(part, "/limine.cfg")) == NULL
|
if ((f = fopen(part, "/limine.cfg")) == NULL
|
||||||
&& (f = fopen(part, "/boot/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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <mm/pmm.h>
|
#include <mm/pmm.h>
|
||||||
#include <lib/print.h>
|
#include <lib/print.h>
|
||||||
#include <pxe/tftp.h>
|
#include <pxe/tftp.h>
|
||||||
|
#include <drivers/fwcfg.h>
|
||||||
#include <tinf.h>
|
#include <tinf.h>
|
||||||
|
|
||||||
// A URI takes the form of: resource://root/path
|
// 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);
|
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
|
#if bios == 1
|
||||||
static struct file_handle *uri_tftp_dispatch(char *root, char *path) {
|
static struct file_handle *uri_tftp_dispatch(char *root, char *path) {
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
|
@ -210,6 +220,10 @@ struct file_handle *uri_open(char *uri) {
|
||||||
} else if (!strcmp(resource, "tftp")) {
|
} else if (!strcmp(resource, "tftp")) {
|
||||||
ret = uri_tftp_dispatch(root, path);
|
ret = uri_tftp_dispatch(root, path);
|
||||||
#endif
|
#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 {
|
} else {
|
||||||
panic("Resource `%s` not valid.", resource);
|
panic("Resource `%s` not valid.", resource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -98,3 +98,4 @@ KERNEL_CMDLINE=Woah! Another example!
|
||||||
|
|
||||||
MODULE_PATH=odd://1:/boot/bg.bmp
|
MODULE_PATH=odd://1:/boot/bg.bmp
|
||||||
MODULE_STRING=yooooo
|
MODULE_STRING=yooooo
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue