@@ -26,6 +26,7 @@ enum bls_token_t {
TOK_TITLE = 0,
TOK_VERSION,
TOK_LINUX,
+ TOK_FIT,
TOK_OPTIONS,
TOK_INITRD,
TOK_DEVICETREE,
@@ -42,6 +43,7 @@ static const char *const bls_token_names[] = {
[TOK_TITLE] = "title",
[TOK_VERSION] = "version",
[TOK_LINUX] = "linux",
+ [TOK_FIT] = "fit",
[TOK_OPTIONS] = "options",
[TOK_INITRD] = "initrd",
[TOK_DEVICETREE] = "devicetree",
@@ -224,6 +226,10 @@ int bls_parse_entry(const char *buf, size_t size, struct bls_entry *entry)
/* Point into buffer */
entry->kernel = value;
break;
+ case TOK_FIT:
+ /* Point into buffer */
+ entry->fit = value;
+ break;
case TOK_OPTIONS:
/* Multiple times - allocate and concatenate */
if (bls_append_str(&entry->options, value))
@@ -267,10 +273,10 @@ int bls_parse_entry(const char *buf, size_t size, struct bls_entry *entry)
/*
* Validate required fields: BLS spec requires at least one of
- * 'linux' or 'efi'. We only support 'linux' for Type #1 entries.
+ * 'linux' or 'efi'. We also accept 'fit' for FIT images.
*/
- if (!entry->kernel) {
- log_err("BLS entry missing required 'linux' field\n");
+ if (!entry->kernel && !entry->fit) {
+ log_err("BLS entry missing required 'linux' or 'fit' field\n");
return -EINVAL;
}
@@ -202,7 +202,12 @@ static int bls_entry_init(struct bls_entry *entry, struct bootflow *bflow,
}
/* Register discovered images (not yet loaded, addr=0) */
- if (entry->kernel) {
+ if (entry->fit) {
+ if (!bootflow_img_add(bflow, entry->fit,
+ (enum bootflow_img_t)IH_TYPE_KERNEL,
+ 0, 0))
+ return log_msg_ret("imf", -ENOMEM);
+ } else if (entry->kernel) {
if (!bootflow_img_add(bflow, entry->kernel,
(enum bootflow_img_t)IH_TYPE_KERNEL,
0, 0))
@@ -24,8 +24,9 @@
*
* @title: Human-readable name (points into buffer)
* @version: OS version string (points into buffer)
- * @kernel: Kernel path or FIT image - required (points into buffer)
+ * @kernel: Kernel path - required unless @fit is set (points into buffer)
* Can include FIT config syntax: path#config
+ * @fit: FIT image path - required unless @kernel is set (points into buffer)
* @options: Kernel command line - ALLOCATED, must be freed
* Multiple options lines are concatenated with spaces
* @initrds: List of initrd paths (alist of char * pointing into buffer)
@@ -41,6 +42,7 @@ struct bls_entry {
char *title;
char *version;
char *kernel;
+ char *fit;
char *options; /* Allocated */
struct alist initrds; /* list of char * into buffer */
char *devicetree;
@@ -70,7 +72,8 @@ struct bls_entry {
* Supported fields:
* title - Human-readable name
* version - OS version string
- * linux - Kernel path (required)
+ * linux - Kernel path (required unless 'fit' is present)
+ * fit - FIT image path (required unless 'linux' is present)
* options - Kernel command line (allocated, can appear multiple times)
* initrd - Initramfs path (can appear multiple times)
* devicetree - Device tree blob path
@@ -137,6 +137,30 @@ static int bls_test_parse_unknown_field(struct unit_test_state *uts)
}
UNIT_TEST(bls_test_parse_unknown_field, 0, bootstd);
+/* Test FIT-only entry (no linux field) */
+static int bls_test_parse_fit(struct unit_test_state *uts)
+{
+ struct bls_entry entry;
+ char buf[] =
+ "title FIT Test\n"
+ "version 1.0\n"
+ "fit /boot/image.fit\n"
+ "options root=/dev/sda\n"
+ "initrd /initrd.img\n";
+
+ ut_assertok(bls_parse_entry(buf, sizeof(buf) - 1, &entry));
+ ut_asserteq_str("FIT Test", entry.title);
+ ut_assertnull(entry.kernel);
+ ut_asserteq_str("/boot/image.fit", entry.fit);
+ ut_asserteq_str("root=/dev/sda", entry.options);
+ ut_asserteq(1, entry.initrds.count);
+
+ bls_entry_uninit(&entry);
+
+ return 0;
+}
+UNIT_TEST(bls_test_parse_fit, 0, bootstd);
+
/* Test all supported fields */
static int bls_test_parse_all_fields(struct unit_test_state *uts)
{