Skip to content

Commit b9f62db

Browse files
committed
lk2nd: boot: Make sure to boot the default label in the extlinux.conf
1 parent 816945d commit b9f62db

File tree

1 file changed

+102
-11
lines changed

1 file changed

+102
-11
lines changed

lk2nd/boot/extlinux.c

Lines changed: 102 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "boot.h"
2121

2222
struct label {
23+
const char *name;
2324
const char *kernel;
2425
const char *initramfs;
2526
const char *dtb;
@@ -29,6 +30,8 @@ struct label {
2930
};
3031

3132
enum token {
33+
CMD_LABEL,
34+
CMD_DEFAULT,
3235
CMD_KERNEL,
3336
CMD_APPEND,
3437
CMD_INITRD,
@@ -42,6 +45,8 @@ static const struct {
4245
char *command;
4346
enum token token;
4447
} token_map[] = {
48+
{"label", CMD_LABEL},
49+
{"default", CMD_DEFAULT},
4550
{"kernel", CMD_KERNEL},
4651
{"linux", CMD_KERNEL},
4752
{"fdtdir", CMD_FDTDIR},
@@ -169,6 +174,25 @@ static int parse_command(char **data, size_t *size, char **command, char **value
169174
return 0;
170175
}
171176

177+
/**
178+
* count_lines() - Count the amount of lines in the string.
179+
*/
180+
static int count_lines(char *data, size_t size)
181+
{
182+
int acc = 0;
183+
size_t i;
184+
185+
for (i = 0; i < size; ++i) {
186+
if (data[i] == '\n')
187+
acc++;
188+
189+
if (data[i] == '\0')
190+
break;
191+
}
192+
193+
return acc;
194+
}
195+
172196
/**
173197
* parse_conf() - Extract default label from extlinux.conf
174198
* @data: File contents
@@ -189,44 +213,109 @@ static int parse_conf(char *data, size_t size, struct label *label)
189213
char *command = NULL, *value = NULL;
190214
char *overlay, *saveptr;
191215
int cnt = 0;
192-
216+
struct {
217+
enum token cmd;
218+
char *val;
219+
} *commands;
220+
int commands_count;
221+
struct label *labels;
222+
struct label *default_label = NULL;
223+
const char *default_name = "";
224+
int labels_count = 0;
225+
int label_idx;
226+
int i;
227+
228+
commands_count = count_lines(data, size);
229+
commands = calloc(commands_count, sizeof(*commands));
230+
231+
i = 0;
193232
while (parse_command(&data, &size, &command, &value) == 0) {
194-
switch (cmd_to_tok(command)) {
233+
if (i >= commands_count) {
234+
dprintf(INFO, "Failed to parse the extlinux.conf\n");
235+
free(commands);
236+
return -1;
237+
}
238+
239+
commands[i].cmd = cmd_to_tok(command);
240+
commands[i].val = value;
241+
i++;
242+
}
243+
244+
commands_count = i;
245+
246+
i = 0;
247+
for (i = 0; i < commands_count; ++i) {
248+
if (commands[i].cmd == CMD_LABEL)
249+
labels_count++;
250+
}
251+
252+
if (labels_count == 0) {
253+
dprintf(INFO, "No labels in the extlinux.conf\n");
254+
free(commands);
255+
return -1;
256+
}
257+
258+
labels = calloc(labels_count, sizeof(*labels));
259+
260+
label_idx = -1;
261+
for (i = 0; i < commands_count; ++i) {
262+
if (commands[i].cmd == CMD_DEFAULT) {
263+
default_name = commands[i].val;
264+
} else if (commands[i].cmd == CMD_LABEL) {
265+
label_idx++;
266+
labels[label_idx].name = commands[i].val;
267+
} else if (label_idx >= 0 && label_idx < labels_count) {
268+
switch (commands[i].cmd) {
195269
case CMD_KERNEL:
196-
label->kernel = value;
270+
labels[label_idx].kernel = commands[i].val;
197271
break;
198272
case CMD_INITRD:
199-
label->initramfs = value;
273+
labels[label_idx].initramfs = commands[i].val;
200274
break;
201275
case CMD_APPEND:
202-
label->cmdline = value;
276+
labels[label_idx].cmdline = commands[i].val;
203277
break;
204278
case CMD_FDT:
205-
label->dtb = value;
279+
labels[label_idx].dtb = commands[i].val;
206280
break;
207281
case CMD_FDTDIR:
208-
label->dtbdir = value;
282+
labels[label_idx].dtbdir = commands[i].val;
209283
break;
210284
case CMD_FDTOVERLAY:
211-
for (char *c = value; *c; c++)
285+
for (char *c = commands[i].val; *c; c++)
212286
if (*c == ' ')
213287
cnt++;
214288

215289
cnt += 2;
216290

217-
label->dtboverlays = calloc(cnt, sizeof(*label->dtboverlays));
291+
labels[label_idx].dtboverlays = calloc(cnt, sizeof(*labels[label_idx].dtboverlays));
218292
cnt = 0;
219-
for (overlay = strtok_r(value, " ", &saveptr); overlay;
293+
for (overlay = strtok_r(commands[i].val, " ", &saveptr); overlay;
220294
overlay = strtok_r(NULL, " ", &saveptr)) {
221-
label->dtboverlays[cnt] = overlay;
295+
labels[label_idx].dtboverlays[cnt] = overlay;
222296
cnt++;
223297
}
224298
break;
225299
default:
226300
break;
301+
}
227302
}
228303
}
229304

305+
default_label = &labels[0];
306+
307+
for (i = 0; i < labels_count; ++i) {
308+
if (!strcmp(default_name, labels[i].name)) {
309+
default_label = &labels[i];
310+
break;
311+
}
312+
}
313+
314+
memcpy(label, default_label, sizeof(*label));
315+
316+
free(labels);
317+
free(commands);
318+
230319
return 0;
231320
}
232321

@@ -419,6 +508,8 @@ static void lk2nd_boot_label(struct label *label)
419508
void *kernel_scratch;
420509
int ret, i = 0;
421510

511+
dprintf(INFO, "Trying to boot '%s'\n", label->name);
512+
422513
ret = fs_load_file(label->kernel, scratch, scratch_size);
423514
if (ret < 0) {
424515
dprintf(INFO, "Failed to load the kernel: %d\n", ret);

0 commit comments

Comments
 (0)