Skip to content

Commit

Permalink
Merge pull request #428 from no92/smbios-booting
Browse files Browse the repository at this point in the history
Support passing configurations via SMBIOS
  • Loading branch information
mintsuki authored Nov 4, 2024
2 parents 2494aee + 03d62d8 commit 3b9dd04
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 8 deletions.
1 change: 1 addition & 0 deletions common/lib/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct smbios_entry_point_64 {
/// Size of the largest SMBIOS structure, in bytes, and encompasses the
/// structure’s formatted area and text strings
uint16_t max_structure_size;
uint16_t padding;
/// 64-bit physical starting address of the read-only SMBIOS Structure
/// Table.
uint64_t table_address;
Expand Down
61 changes: 61 additions & 0 deletions common/lib/config.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stddef.h>
#include <stdbool.h>
#include <lib/acpi.h>
#include <lib/config.h>
#include <lib/libc.h>
#include <lib/misc.h>
Expand Down Expand Up @@ -65,6 +66,66 @@ int init_config_disk(struct volume *part) {
return init_config(config_size);
}

struct smbios_struct_header {
uint8_t type;
uint8_t length;
uint16_t handle;
} __attribute__((packed));

static size_t smbios_struct_size(struct smbios_struct_header *hdr) {
const char *string_data = (void *)((uintptr_t)hdr + hdr->length);
size_t i = 1;
for (; string_data[i - 1] != '\0' || string_data[i] != '\0'; i++);
return hdr->length + i + 1;
}

bool init_config_smbios(void) {
struct smbios_entry_point_32 *smbios_entry_32 = NULL;
struct smbios_entry_point_64 *smbios_entry_64 = NULL;
acpi_get_smbios((void **)&smbios_entry_32, (void **)&smbios_entry_64);
if (smbios_entry_32 == NULL && smbios_entry_64 == NULL) {
return false;
}

struct smbios_struct_header *hdr = NULL;
size_t struct_count = 0;
size_t struct_max_length = 0;

if (smbios_entry_64) {
hdr = (void *)(uintptr_t) smbios_entry_64->table_address;
struct_max_length = smbios_entry_64->max_structure_size;
} else {
hdr = (void *)(uintptr_t) smbios_entry_32->table_address;
struct_count = smbios_entry_32->number_of_structures;
}

size_t structure_bytes_processed = 0;
for (size_t struct_num = 0; hdr && (!struct_count || struct_num < struct_count); struct_num++) {
if (hdr->type == 127)
return false;

if (hdr->type == 11) {
const char *string_data = (void *)((uintptr_t) hdr + hdr->length);

size_t prefix_len = sizeof("limine:config:") - 1;
if (!strncmp(string_data, "limine:config:", prefix_len)) {
size_t config_size = strlen(string_data) - prefix_len + 1;
config_addr = ext_mem_alloc(config_size);
memcpy(config_addr, &string_data[prefix_len], config_size);
return !init_config(config_size);
}
}

if (struct_max_length && structure_bytes_processed + smbios_struct_size(hdr) >= struct_max_length)
return false;

structure_bytes_processed += smbios_struct_size(hdr);
hdr = (void *)((uintptr_t) hdr + smbios_struct_size(hdr));
}

return false;
}

#define NOT_CHILD (-1)
#define DIRECT_CHILD 0
#define INDIRECT_CHILD 1
Expand Down
1 change: 1 addition & 0 deletions common/lib/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extern bool config_format_old;
extern struct menu_entry *menu_tree;

int init_config_disk(struct volume *part);
bool init_config_smbios(void);
int init_config(size_t config_size);

char *config_get_value(const char *config, size_t index, const char *key);
Expand Down
19 changes: 11 additions & 8 deletions common/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,18 +740,21 @@ noreturn void _menu(bool first_run) {
term_fallback();

if (bad_config == false) {
if (!init_config_smbios()) {

#if defined (UEFI)
if (init_config_disk(boot_volume)) {
if (init_config_disk(boot_volume)) {
#endif
volume_iterate_parts(boot_volume,
if (!init_config_disk(_PART)) {
boot_volume = _PART;
break;
}
);
volume_iterate_parts(boot_volume,
if (!init_config_disk(_PART)) {
boot_volume = _PART;
break;
}
);
#if defined (UEFI)
}
}
#endif
}
}

char *quiet_str = config_get_value(NULL, 0, "QUIET");
Expand Down

0 comments on commit 3b9dd04

Please sign in to comment.