Files
Limine/common/lib/guid.c
sanana 196e07ab05 bli: Implement initial Boot Loader Interface support
This patch makes Limine advertise its branding and the ESP partition GUID to
systemd over the Boot Loader Interface specification. There's more to the Boot
Loader Interface than these variables, but this acts as an initial
implementation. See #473.

BLI variables are initialised for all protocols, not just Linux. While currently
only systemd makes use of it, this allows future Limine protocol kernels (or
their userspace) to discover the ESP.
2025-03-15 16:23:43 +03:00

96 lines
2.6 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <lib/guid.h>
#include <lib/misc.h>
bool is_valid_guid(const char *s) {
for (size_t i = 0; ; i++) {
switch (i) {
case 8:
case 13:
case 18:
case 23:
if (s[i] != '-')
return false;
break;
case 36:
return s[i] == 0;
default:
if (digit_to_int(s[i]) == -1)
return false;
break;
}
}
}
static void guid_convert_le_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0;
for (int i = len - 1; i >= 0; i--) {
int val = digit_to_int(s[i]);
i % 2 ? (dest[p] = val) : (dest[p++] |= val << 4);
}
}
static void guid_convert_be_cluster(uint8_t *dest, const char *s, int len) {
size_t p = 0;
for (int i = 0; i < len; i++) {
int val = digit_to_int(s[i]);
i % 2 ? (dest[p++] |= val) : (dest[p] = val << 4);
}
}
bool string_to_guid_be(struct guid *guid, const char *s) {
if (!is_valid_guid(s))
return false;
guid_convert_be_cluster((uint8_t *)guid + 0, s + 0, 8);
guid_convert_be_cluster((uint8_t *)guid + 4, s + 9, 4);
guid_convert_be_cluster((uint8_t *)guid + 6, s + 14, 4);
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
return true;
}
bool string_to_guid_mixed(struct guid *guid, const char *s) {
if (!is_valid_guid(s))
return false;
guid_convert_le_cluster((uint8_t *)guid + 0, s + 0, 8);
guid_convert_le_cluster((uint8_t *)guid + 4, s + 9, 4);
guid_convert_le_cluster((uint8_t *)guid + 6, s + 14, 4);
guid_convert_be_cluster((uint8_t *)guid + 8, s + 19, 4);
guid_convert_be_cluster((uint8_t *)guid + 10, s + 24, 12);
return true;
}
static void uint_to_hex(uint32_t num, char *dest, int len) {
const char digits[] = "0123456789abcdef";
for (int i = 0; i < len; i++) {
dest[i] = digits[(num >> ((len - 1 - i) * 4)) & 0xf];
}
}
void guid_to_string(const struct guid *guid, char *s) {
uint_to_hex(guid->a, s, 8);
s[8] = '-';
uint_to_hex(guid->b, s + 9, 4);
s[13] = '-';
uint_to_hex(guid->c, s + 14, 4);
s[18] = '-';
uint_to_hex(guid->d[0], s + 19, 2);
uint_to_hex(guid->d[1], s + 21, 2);
s[23] = '-';
uint_to_hex(guid->d[2], s + 24, 2);
uint_to_hex(guid->d[3], s + 26, 2);
uint_to_hex(guid->d[4], s + 28, 2);
uint_to_hex(guid->d[5], s + 30, 2);
uint_to_hex(guid->d[6], s + 32, 2);
uint_to_hex(guid->d[7], s + 34, 2);
s[36] = 0;
}