Preprocessor+Linker Voodoo for boot param decl
This commit is contained in:
parent
5b228625f6
commit
0d06d97edb
5 changed files with 34 additions and 62 deletions
|
|
@ -1,7 +1,24 @@
|
|||
#ifndef KARLOS_BOOTPARAM_H
|
||||
#define KARLOS_BOOTPARAM_H
|
||||
|
||||
void bootparam_reset_values(void);
|
||||
#define BOOTPARAM_(name_, symbol) const struct bootparam_spec _bootparam_spec_ ## symbol __attribute__((section(".rodata.bootparam"))) = { name_, &symbol };
|
||||
|
||||
#define BOOTPARAM_STRING(name_, symbol) BOOTPARAM_("S" name_, symbol)
|
||||
#define BOOTPARAM_BOOL( name_, symbol) BOOTPARAM_("B" name_, symbol)
|
||||
#define BOOTPARAM_INT( name_, symbol) BOOTPARAM_("I" name_, symbol)
|
||||
|
||||
#define BOOTPARAM_TYPE_STRING 'S'
|
||||
#define BOOTPARAM_TYPE_BOOL 'B'
|
||||
#define BOOTPARAM_TYPE_INT 'I'
|
||||
|
||||
// HACK: GCC seems to align global variables to multiples of 16.
|
||||
// Since we want to iterate over the .rodata.bootparam section,
|
||||
// the size of this struct needs to be a multiple of 16.
|
||||
struct bootparam_spec {
|
||||
const char *name; // First byte encodes type
|
||||
void *var;
|
||||
};
|
||||
|
||||
void bootparam_parse_config(char *text);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ SECTIONS
|
|||
KEEP(*(.text.boot)) *(.text .text.*) /* code */
|
||||
} : text
|
||||
.data : {
|
||||
_bootparam_start = .;
|
||||
*(.rodata.bootparam)
|
||||
_bootparam_end = .;
|
||||
*(.rodata .rodata.*) /* data */
|
||||
*(.data .data.*)
|
||||
} : text
|
||||
|
|
|
|||
|
|
@ -1,41 +1,14 @@
|
|||
#include <std.h>
|
||||
#include <bootparam.h>
|
||||
|
||||
enum bootparam_type {
|
||||
BOOTPARAM_TYPE_INT,
|
||||
BOOTPARAM_TYPE_BOOL,
|
||||
BOOTPARAM_TYPE_STRING,
|
||||
};
|
||||
const char *_bootparam_bb_kernel;
|
||||
const char *_bootparam_bb_screen;
|
||||
|
||||
union bootparam_value {
|
||||
int64_t i;
|
||||
bool b;
|
||||
const char *s;
|
||||
};
|
||||
BOOTPARAM_STRING("kernel", _bootparam_bb_kernel);
|
||||
BOOTPARAM_STRING("screen", _bootparam_bb_screen);
|
||||
|
||||
struct bootparam_spec {
|
||||
enum bootparam_type type;
|
||||
union bootparam_value defval;
|
||||
const char *name;
|
||||
void *var;
|
||||
};
|
||||
|
||||
extern bool ram_enable_logging;
|
||||
|
||||
const struct bootparam_spec bootparam_specs[] = {
|
||||
{
|
||||
.name = "screen",
|
||||
.type = BOOTPARAM_TYPE_STRING,
|
||||
.defval = { .s = "800x600" },
|
||||
.var = NULL,
|
||||
},
|
||||
{
|
||||
.name = "ram.enable_logging",
|
||||
.type = BOOTPARAM_TYPE_BOOL,
|
||||
.defval = { .b = false },
|
||||
.var = &ram_enable_logging,
|
||||
},
|
||||
};
|
||||
extern const struct bootparam_spec _bootparam_start[];
|
||||
extern const struct bootparam_spec _bootparam_end[];
|
||||
|
||||
static bool
|
||||
is_space_char(char c)
|
||||
|
|
@ -55,9 +28,8 @@ parse_bootparam_value(unsigned lineno, char *key, char *val)
|
|||
(void)lineno;
|
||||
|
||||
const struct bootparam_spec *spec = NULL;
|
||||
for (unsigned i = 0; i < sizeof(bootparam_specs) / sizeof(bootparam_specs[0]); i++) {
|
||||
const struct bootparam_spec *s = &bootparam_specs[i];
|
||||
if (streq(key, s->name)) {
|
||||
for (const struct bootparam_spec *s = _bootparam_start; s < _bootparam_end; s++) {
|
||||
if (streq(key, s->name+1)) {
|
||||
spec = s;
|
||||
break;
|
||||
}
|
||||
|
|
@ -72,7 +44,7 @@ parse_bootparam_value(unsigned lineno, char *key, char *val)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (spec->type) {
|
||||
switch (spec->name[0]) {
|
||||
case BOOTPARAM_TYPE_STRING:
|
||||
*(const char **)spec->var = val;
|
||||
break;
|
||||
|
|
@ -219,25 +191,3 @@ bootparam_parse_config(char *text)
|
|||
lineno++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bootparam_reset_values(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(bootparam_specs) / sizeof (bootparam_specs[0]); i++) {
|
||||
const struct bootparam_spec *s = &bootparam_specs[i];
|
||||
if (!s->var) {
|
||||
continue;
|
||||
}
|
||||
switch (s->type) {
|
||||
case BOOTPARAM_TYPE_STRING:
|
||||
*(const char **)s->var = s->defval.s;
|
||||
break;
|
||||
case BOOTPARAM_TYPE_BOOL:
|
||||
*(bool *)s->var = s->defval.b;
|
||||
break;
|
||||
case BOOTPARAM_TYPE_INT:
|
||||
*(int64_t *)s->var = s->defval.i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ void _start() {
|
|||
__get_cpuid(0x1, &info[0], &info[1], &info[2], &info[3]);
|
||||
unsigned procid = info[1] >> 24;
|
||||
if (procid == bootboot.bspid) {
|
||||
bootparam_reset_values();
|
||||
bootparam_parse_config(environment);
|
||||
cpu_init_bsp();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "ram.h"
|
||||
#include "bootboot.h"
|
||||
#include "mem_range.h"
|
||||
#include "bootparam.h"
|
||||
|
||||
extern BOOTBOOT bootboot;
|
||||
|
||||
|
|
@ -30,7 +31,9 @@ bool ram_initialized = false;
|
|||
#define CHECK_INIT do { } while (0)
|
||||
#endif
|
||||
|
||||
bool ram_enable_logging;
|
||||
bool ram_enable_logging = false;
|
||||
|
||||
BOOTPARAM_BOOL("ram.enable_logging", ram_enable_logging);
|
||||
|
||||
|
||||
size_t frame_size_to_num_bytes(enum frame_size size) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue