Repository navigation
Expand file tree
/
Copy pathbootargs.cc
More file actions
110 lines (95 loc) · 3.25 KB
/
Copy pathbootargs.cc
File metadata and controls
110 lines (95 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <cxx/string.h>
#include <stdint.h>
#include "loader.h"
using loader::gLoaderData;
constexpr int MAX_PARAM_LEN = 64;
//===----------------------------------------------------------------------===//
// Parsed command handler
//===----------------------------------------------------------------------===//
static void cmd_handler(const char *key, const char *value) {
libkernel::log(LL::DEBUG, "Parsing k/v pair: ['%s'] = '%s'\r\n", key, value);
if (cxx::strcmp(key, "init") == 0) {
cxx::strncpy(gLoaderData.init_image, value, loader::MaxInitImageNameLength);
} else if (cxx::strcmp(key, "logmask") == 0) {
int val = cxx::atoi(value);
if (val != (uint8_t)val) {
libkernel::log(LL::VERBOSE_WARNING, "Invalid value '%s' for key '%s'\r\n", value, key);
} else {
gLoaderData.kernel_log_mask = (uint8_t)val;
}
} else {
libkernel::log(LL::VERBOSE_WARNING, "Skipping unknown key: '%s'\r\n", key);
}
}
//===----------------------------------------------------------------------===//
// Helper function to parse a key-value pair
//===----------------------------------------------------------------------===//
static void parse_kv_pair(const char *param) {
char key[MAX_PARAM_LEN + 1]{0};
char value[MAX_PARAM_LEN + 1]{0};
// Find the equals sign
const auto eq_pos = cxx::strchr(param, '=');
if (!eq_pos) {
// Handle parameters without values (treat as boolean flags)
cxx::strncpy(key, param, MAX_PARAM_LEN);
cmd_handler(key, "1");
return;
}
// Calculate lengths
auto key_len = eq_pos - param;
auto value_len = cxx::strlen(eq_pos + 1);
// Enforce size limits
if (key_len > MAX_PARAM_LEN) {
key_len = MAX_PARAM_LEN;
}
if (value_len > MAX_PARAM_LEN) {
value_len = MAX_PARAM_LEN;
}
// Copy the key and value
cxx::strncpy(key, param, key_len);
key[key_len] = '\0';
cxx::strncpy(value, eq_pos + 1, value_len);
value[value_len] = '\0';
// Call the handler
cmd_handler(key, value);
}
//===----------------------------------------------------------------------===//
// Main parsing code
//===----------------------------------------------------------------------===//
void loader::parse_bootargs(char const *args) {
if (!args) return;
// 1. Buffer for the current parameter (k, v) pair
char param_buf[MAX_PARAM_LEN * 2 + 2] = {0};
size_t i = 0;
bool in_param = false;
while (*args) {
// 2a. End of current parameter
// 2b. Add character to current parameter
if (i >= sizeof(param_buf) - 1) {
libkernel::log(LL::VERBOSE_WARNING, "Parsing partially failed -- buffer overrun.\r\n");
return;
}
if (*args == ' ' || *args == '\t') {
if (in_param) {
param_buf[i] = '\0';
if (i > 0) {
parse_kv_pair(param_buf);
}
i = 0;
in_param = false;
}
} else {
if (i < sizeof(param_buf) - 1) {
param_buf[i++] = *args;
}
in_param = true;
}
args++;
}
// 3. Handle the last parameter if it exists
if (in_param && i > 0) {
param_buf[i] = '\0';
parse_kv_pair(param_buf);
}
libkernel::log(LL::DEBUG, "Bootargs parsing complete.\r\n");
}