Skip to content

Commit

Permalink
x86: Support loading kernel setup from a FIT
Browse files Browse the repository at this point in the history
Add a new setup@ section to the FIT which can be used to provide a setup
binary for booting Linux on x86. This makes it possible to boot x86 from
a FIT.

Signed-off-by: Simon Glass <[email protected]>
  • Loading branch information
sjg20 committed Oct 22, 2014
1 parent 3811977 commit 90268b8
Show file tree
Hide file tree
Showing 9 changed files with 399 additions and 2 deletions.
23 changes: 21 additions & 2 deletions common/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <common.h>
#include <bootstage.h>
#include <bzlib.h>
#include <errno.h>
#include <fdt_support.h>
#include <lmb.h>
#include <malloc.h>
Expand Down Expand Up @@ -83,6 +84,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
{
const void *os_hdr;
bool ep_found = false;
int ret;

/* get kernel image header, start address and length */
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
Expand All @@ -102,6 +104,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,

images.os.end = image_get_image_end(os_hdr);
images.os.load = image_get_load(os_hdr);
images.os.arch = image_get_arch(os_hdr);
break;
#endif
#if defined(CONFIG_FIT)
Expand Down Expand Up @@ -129,6 +132,13 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
return 1;
}

if (fit_image_get_arch(images.fit_hdr_os,
images.fit_noffset_os,
&images.os.arch)) {
puts("Can't get image ARCH!\n");
return 1;
}

images.os.end = fit_get_end(images.fit_hdr_os);

if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
Expand Down Expand Up @@ -156,8 +166,17 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc,
return 1;
}

/* find kernel entry point */
if (images.legacy_hdr_valid) {
/* If we have a valid setup.bin, we will use that for entry (x86) */
if (images.os.arch == IH_ARCH_I386) {
ulong len;

ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len);
if (ret < 0 && ret != -ENOENT) {
puts("Could not find a valid setup.bin for x86\n");
return 1;
}
/* Kernel entry point is the setup.bin */
} else if (images.legacy_hdr_valid) {
images.ep = image_get_ep(&images.legacy_hdr_os_copy);
#if defined(CONFIG_FIT)
} else if (images.fit_uname_os) {
Expand Down
1 change: 1 addition & 0 deletions common/cmd_bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <bootm.h>
#include <command.h>
#include <environment.h>
#include <errno.h>
#include <image.h>
#include <lmb.h>
#include <malloc.h>
Expand Down
22 changes: 22 additions & 0 deletions common/image-fit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,8 @@ static const char *fit_get_image_type_property(int type)
return FIT_KERNEL_PROP;
case IH_TYPE_RAMDISK:
return FIT_RAMDISK_PROP;
case IH_TYPE_X86_SETUP:
return FIT_SETUP_PROP;
}

return "unknown";
Expand Down Expand Up @@ -1693,3 +1695,23 @@ int fit_image_load(bootm_headers_t *images, ulong addr,

return noffset;
}

int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
ulong *setup_start, ulong *setup_len)
{
int noffset;
ulong addr;
ulong len;
int ret;

addr = map_to_sysmem(images->fit_hdr_os);
noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
if (noffset < 0)
return noffset;

ret = fit_image_load(images, addr, NULL, NULL, arch,
IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
FIT_LOAD_REQUIRED, setup_start, &len);

return ret;
}
11 changes: 11 additions & 0 deletions common/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",},
{ IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",},
{ IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
{ IH_TYPE_X86_SETUP, "x86_setup", "x86 setup.bin", },
{ -1, "", "", },
};

Expand Down Expand Up @@ -1136,6 +1137,16 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
}
#endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */

int boot_get_setup(bootm_headers_t *images, uint8_t arch,
ulong *setup_start, ulong *setup_len)
{
#if defined(CONFIG_FIT)
return boot_get_setup_fit(images, arch, setup_start, setup_len);
#else
return -ENOENT;
#endif
}

#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
/**
* boot_get_cmdline - allocate and initialize kernel cmdline
Expand Down
50 changes: 50 additions & 0 deletions doc/uImage.FIT/kernel.its
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,53 @@
};
};
};



For x86 a setup node is also required: see x86-fit-boot.txt.

/dts-v1/;

/ {
description = "Simple image with single Linux kernel on x86";
#address-cells = <1>;

images {
kernel@1 {
description = "Vanilla Linux kernel";
data = /incbin/("./image.bin.lzo");
type = "kernel";
arch = "x86";
os = "linux";
compression = "lzo";
load = <0x01000000>;
entry = <0x00000000>;
hash@2 {
algo = "sha1";
};
};

setup@1 {
description = "Linux setup.bin";
data = /incbin/("./setup.bin");
type = "x86_setup";
arch = "x86";
os = "linux";
compression = "none";
load = <0x00090000>;
entry = <0x00090000>;
hash@2 {
algo = "sha1";
};
};
};

configurations {
default = "config@1";
config@1 {
description = "Boot Linux kernel";
kernel = "kernel@1";
setup = "setup@1";
};
};
};
2 changes: 2 additions & 0 deletions doc/uImage.FIT/source_file_format.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ o config@1
node of a "ramdisk" type).
- fdt : Unit name of the corresponding fdt blob (component image node of a
"fdt type").
- setup : Unit name of the corresponding setup binary (used for booting
an x86 kernel). This contains the setup.bin file built by the kernel.

The FDT blob is required to properly boot FDT based kernel, so the minimal
configuration for 2.6 FDT kernel is (kernel, fdt) pair.
Expand Down
Loading

0 comments on commit 90268b8

Please sign in to comment.