Compare commits
11 Commits
cherry-479
...
std
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77146a1a0b | ||
|
|
39c0d81749 | ||
|
|
db6c671cbb | ||
|
|
9fd2c2ec0d | ||
|
|
2e86338708 | ||
|
|
f51ba0874d | ||
|
|
05b4aabcd6 | ||
|
|
6a92f0bb7a | ||
|
|
bbfd79236c | ||
|
|
98368a8f49 | ||
|
|
f4ed8a3aad |
@@ -210,6 +210,7 @@ N: aspeed
|
||||
ARM BROADCOM BCM283X / BCM27XX
|
||||
M: Matthias Brugger <mbrugger@suse.com>
|
||||
M: Peter Robinson <pbrobinson@gmail.com>
|
||||
M: Simon Glass <sjg@chromium.org>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/bcm283*
|
||||
F: arch/arm/mach-bcm283x/
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
mmc6 = "/mmc6";
|
||||
mmc7 = "/mmc7";
|
||||
mmc8 = "/mmc8";
|
||||
mmc9 = "/mmc9";
|
||||
pci0 = &pci0;
|
||||
pci1 = &pci1;
|
||||
pci2 = &pci2;
|
||||
@@ -1153,6 +1154,13 @@
|
||||
filename = "mmc8.img";
|
||||
};
|
||||
|
||||
/* This is used for extlinux localboot */
|
||||
mmc9 {
|
||||
status = "disabled";
|
||||
compatible = "sandbox,mmc";
|
||||
filename = "mmc9.img";
|
||||
};
|
||||
|
||||
pch {
|
||||
compatible = "sandbox,pch";
|
||||
};
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* (C) Copyright 2012-2016 Stephen Warren
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY LOGC_BOARD
|
||||
|
||||
#include <config.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
@@ -325,19 +327,10 @@ static void set_fdtfile(void)
|
||||
env_set("fdtfile", fdtfile);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the firmware provided a valid FDT at boot time, let's expose it in
|
||||
* ${fdt_addr} so it may be passed unmodified to the kernel.
|
||||
*/
|
||||
/* Allow U-Boot to use its control FDT with extlinux if one is not provided */
|
||||
static void set_fdt_addr(void)
|
||||
{
|
||||
if (env_get("fdt_addr"))
|
||||
return;
|
||||
|
||||
if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC)
|
||||
return;
|
||||
|
||||
env_set_hex("fdt_addr", fw_dtb_pointer);
|
||||
env_set_hex("fdt_addr", (ulong)gd->fdt_blob);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -571,7 +564,10 @@ int ft_board_setup(void *blob, struct bd_info *bd)
|
||||
{
|
||||
int node;
|
||||
|
||||
update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
|
||||
if (blob == gd->fdt_blob)
|
||||
log_debug("Same FDT: nothing to do\n");
|
||||
else
|
||||
update_fdt_from_fw(blob, (void *)gd->fdt_blob);
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
|
||||
if (node < 0)
|
||||
|
||||
@@ -48,30 +48,33 @@ dfu_alt_info+=zImage fat 0 1
|
||||
*
|
||||
* scriptaddr and pxefile_addr_r can be pretty much anywhere that doesn't
|
||||
* conflict with something else. Reserving 1M for each of them at
|
||||
* 0x02400000-0x02500000 and 0x02500000-0x02600000 should be plenty.
|
||||
* 0x05400000-0x05500000 and 0x05500000-0x05600000 should be plenty.
|
||||
*
|
||||
* On ARM, both the DTB and any possible initrd must be loaded such that they
|
||||
* fit inside the lowmem mapping in Linux. In practice, this usually means not
|
||||
* more than ~700M away from the start of the kernel image but this number can
|
||||
* be larger OR smaller depending on e.g. the 'vmalloc=xxxM' command line
|
||||
* parameter given to the kernel. So reserving memory from low to high
|
||||
* satisfies this constraint again. Reserving 1M at 0x02600000-0x02700000 for
|
||||
* the DTB leaves rest of the free RAM to the initrd starting at 0x02700000.
|
||||
* Even with the smallest possible CPU-GPU memory split of the CPU getting
|
||||
* only 64M, the remaining 25M starting at 0x02700000 should allow quite
|
||||
* large initrds before they start colliding with U-Boot.
|
||||
* satisfies this constraint again. Reserving 1M at 0x05600000-0x05700000 for
|
||||
* the DTB leaves rest of the free RAM to the initrd starting at 0x05700000.
|
||||
* This means that the board must have at least 128MB of RAM available to
|
||||
* U-Boot, more if the initrd is large.
|
||||
*
|
||||
* For compressed kernels, the maximum size is just under 32MB, with an area for
|
||||
* decompression at 0x02000000 with space for 52MB, which is plenty for current
|
||||
* kernels.
|
||||
*
|
||||
* limit bootm_size to 512MB so that all boot images stay within the bottom
|
||||
* 512MB of memory
|
||||
*/
|
||||
#ifdef CONFIG_ARM64
|
||||
fdt_high=ffffffffffffffff
|
||||
initrd_high=ffffffffffffffff
|
||||
#else
|
||||
fdt_high=ffffffff
|
||||
initrd_high=ffffffff
|
||||
#endif
|
||||
bootm_size=0x20000000
|
||||
|
||||
kernel_addr_r=0x00080000
|
||||
scriptaddr=0x02400000
|
||||
pxefile_addr_r=0x02500000
|
||||
fdt_addr_r=0x02600000
|
||||
ramdisk_addr_r=0x02700000
|
||||
kernel_comp_addr_r=0x02000000
|
||||
kernel_comp_size=0x03400000
|
||||
scriptaddr=0x05400000
|
||||
pxefile_addr_r=0x05500000
|
||||
fdt_addr_r=0x05600000
|
||||
ramdisk_addr_r=0x05700000
|
||||
|
||||
boot_targets=mmc usb pxe dhcp
|
||||
|
||||
@@ -556,6 +556,15 @@ config BOOTMETH_EXTLINUX_PXE
|
||||
|
||||
This provides a way to try out standard boot on an existing boot flow.
|
||||
|
||||
config BOOTMETH_EXTLINUX_LOCALBOOT
|
||||
bool "Boot method for extlinux localboot"
|
||||
depends on BOOTMETH_EXTLINUX
|
||||
default y
|
||||
help
|
||||
Enables standard boot support for the extlinux 'localboot' feature.
|
||||
This attempts to find a kernel and initrd on the disk and boot it,
|
||||
in the case where there is no "localcmd" in the environment.
|
||||
|
||||
config BOOTMETH_EFILOADER
|
||||
bool "Bootdev support for EFI boot"
|
||||
depends on EFI_BINARY_EXEC
|
||||
|
||||
@@ -640,6 +640,25 @@ static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate_localboot() - Try to come up with a localboot definition
|
||||
*
|
||||
* Adds a default kernel and initrd filename for use with localboot
|
||||
*
|
||||
* @label: Label to process
|
||||
* Return 0 if OK, -ENOMEM if out of memory
|
||||
*/
|
||||
static int generate_localboot(struct pxe_label *label)
|
||||
{
|
||||
label->kernel = strdup("/vmlinuz");
|
||||
label->kernel_label = strdup(label->kernel);
|
||||
label->initrd = strdup("/initrd.img");
|
||||
if (!label->kernel || !label->kernel_label || !label->initrd)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* label_boot() - Boot according to the contents of a pxe_label
|
||||
*
|
||||
@@ -677,9 +696,17 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
||||
label->attempted = 1;
|
||||
|
||||
if (label->localboot) {
|
||||
if (label->localboot_val >= 0)
|
||||
label_localboot(label);
|
||||
return 0;
|
||||
if (label->localboot_val >= 0) {
|
||||
ret = label_localboot(label);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BOOTMETH_EXTLINUX_LOCALBOOT) &&
|
||||
ret == -ENOENT)
|
||||
ret = generate_localboot(label);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!label->kernel) {
|
||||
@@ -799,7 +826,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
||||
}
|
||||
unmap_sysmem(buf);
|
||||
}
|
||||
if (ctx->bflow)
|
||||
if (ctx->bflow && conf_fdt)
|
||||
ctx->bflow->fdt_addr = hextoul(conf_fdt, NULL);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && ctx->no_boot) {
|
||||
@@ -819,7 +846,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
|
||||
ctx->initrd_addr_str, ctx->initrd_filesize,
|
||||
ctx->initrd_str);
|
||||
}
|
||||
if (!ctx->kernel_addr || !ctx->conf_fdt ||
|
||||
if (!ctx->kernel_addr || (conf_fdt && !ctx->conf_fdt) ||
|
||||
(initrd_addr_str && (!ctx->initrd_addr_str ||
|
||||
!ctx->initrd_filesize || !ctx->initrd_str))) {
|
||||
printf("malloc fail (saving label)\n");
|
||||
@@ -863,6 +890,7 @@ enum token_type {
|
||||
T_BACKGROUND,
|
||||
T_KASLRSEED,
|
||||
T_FALLBACK,
|
||||
T_SAY,
|
||||
T_INVALID
|
||||
};
|
||||
|
||||
@@ -897,6 +925,7 @@ static const struct token keywords[] = {
|
||||
{"background", T_BACKGROUND,},
|
||||
{"kaslrseed", T_KASLRSEED,},
|
||||
{"fallback", T_FALLBACK,},
|
||||
{"say", T_SAY,},
|
||||
{NULL, T_INVALID}
|
||||
};
|
||||
|
||||
@@ -1361,6 +1390,17 @@ static int parse_label(char **c, struct pxe_menu *cfg)
|
||||
case T_EOL:
|
||||
break;
|
||||
|
||||
case T_SAY: {
|
||||
char *p = strchr(s, '\n');
|
||||
|
||||
if (p) {
|
||||
printf("%.*s\n", (int)(p - *c) - 1, *c + 1);
|
||||
|
||||
*c = p;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/*
|
||||
* put the token back! we don't want it - it's the end
|
||||
|
||||
@@ -354,6 +354,7 @@ CONFIG_WDT_FTWDT010=y
|
||||
CONFIG_FS_CBFS=y
|
||||
CONFIG_FS_CRAMFS=y
|
||||
CONFIG_ADDR_MAP=y
|
||||
CONFIG_PANIC_HANG=y
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
CONFIG_MBEDTLS_LIB=y
|
||||
CONFIG_ECDSA=y
|
||||
|
||||
@@ -540,12 +540,15 @@ BOOTSTD_TEST(bootflow_cmd_boot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
|
||||
static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
||||
bool bind_cros_android, const char ***old_orderp)
|
||||
{
|
||||
static const char *order[] = {"mmc2", "mmc1", NULL, NULL};
|
||||
static const char **order;
|
||||
struct udevice *dev, *bootstd;
|
||||
struct bootstd_priv *std;
|
||||
const char **old_order;
|
||||
ofnode root, node;
|
||||
|
||||
order = calloc(sizeof(void *), 4);
|
||||
order[0] = "mmc2";
|
||||
order[1] = "mmc1";
|
||||
order[2] = mmc_dev;
|
||||
|
||||
/* Enable the requested mmc node since we need a second bootflow */
|
||||
@@ -605,6 +608,7 @@ static int scan_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
||||
/* Restore the order used by the device tree */
|
||||
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||
std = dev_get_priv(bootstd);
|
||||
free(std->bootdev_order);
|
||||
std->bootdev_order = old_order;
|
||||
|
||||
return 0;
|
||||
@@ -635,6 +639,7 @@ static int scan_mmc_android_bootdev(struct unit_test_state *uts, const char *mmc
|
||||
/* Restore the order used by the device tree */
|
||||
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||
std = dev_get_priv(bootstd);
|
||||
free(std->bootdev_order);
|
||||
std->bootdev_order = old_order;
|
||||
|
||||
return 0;
|
||||
@@ -726,6 +731,7 @@ static int bootflow_scan_menu(struct unit_test_state *uts)
|
||||
|
||||
std->bootdev_order = new_order; /* Blue Monday */
|
||||
ut_assertok(run_command("bootflow scan -lm", 0));
|
||||
free(std->bootdev_order);
|
||||
std->bootdev_order = old_order;
|
||||
|
||||
ut_assertnull(std->cur_bootflow);
|
||||
@@ -1504,3 +1510,51 @@ static int bootflow_scan_extlinux(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(bootflow_scan_extlinux, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
|
||||
|
||||
/* Check automatically generating a extlinux 'localboot' */
|
||||
static int bootflow_extlinux_localboot(struct unit_test_state *uts)
|
||||
{
|
||||
const struct bootflow_img *img;
|
||||
struct bootstd_priv *std;
|
||||
const char **old_order;
|
||||
struct bootflow *bflow;
|
||||
|
||||
ut_assertok(prep_mmc_bootdev(uts, "mmc9", false, &old_order));
|
||||
|
||||
ut_assertok(run_command("bootflow scan", 0));
|
||||
ut_assert_console_end();
|
||||
|
||||
/* Restore the order used by the device tree */
|
||||
ut_assertok(bootstd_get_priv(&std));
|
||||
free(std->bootdev_order);
|
||||
std->bootdev_order = old_order;
|
||||
|
||||
/* boot the second bootflow */
|
||||
ut_asserteq(2, std->bootflows.count);
|
||||
bflow = alist_getw(&std->bootflows, 1, struct bootflow);
|
||||
std->cur_bootflow = bflow;
|
||||
|
||||
/* read all the images, but don't actually boot */
|
||||
ut_assertok(bootflow_read_all(bflow));
|
||||
ut_assert_nextline("Doing local boot...");
|
||||
ut_assert_nextline("1:\tlocal");
|
||||
ut_assert_nextline("missing environment variable: localcmd");
|
||||
ut_assert_nextline("Retrieving file: /vmlinuz");
|
||||
ut_assert_nextline("Retrieving file: /initrd.img");
|
||||
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(3, bflow->images.count);
|
||||
|
||||
/* check the two localboot images */
|
||||
img = alist_get(&bflow->images, 1, struct bootflow_img);
|
||||
ut_asserteq(IH_TYPE_KERNEL, img->type);
|
||||
ut_asserteq(0x1000000, img->addr); /* kernel_addr_r */
|
||||
|
||||
img = alist_get(&bflow->images, 2, struct bootflow_img);
|
||||
ut_asserteq(IH_TYPE_RAMDISK, img->type);
|
||||
ut_asserteq(0x2000000, img->addr); /* ramdisk_addr_r */
|
||||
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(bootflow_extlinux_localboot, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
|
||||
|
||||
@@ -57,6 +57,43 @@ def setup_image(cons, devnum, part_type, img_size=20, second_part=False,
|
||||
stdin=spec.encode('utf-8'))
|
||||
return fname, mnt
|
||||
|
||||
def setup_extlinux_image(cons, mmc_dev, vmlinux, initrd, dtbdir, script):
|
||||
"""Create a 20MB disk image with a single FAT partition"""
|
||||
fname, mnt = setup_image(cons, mmc_dev, 0xc, second_part=True)
|
||||
|
||||
ext = os.path.join(mnt, 'extlinux')
|
||||
mkdir_cond(ext)
|
||||
|
||||
conf = os.path.join(ext, 'extlinux.conf')
|
||||
with open(conf, 'w', encoding='ascii') as fd:
|
||||
print(script, file=fd)
|
||||
|
||||
inf = os.path.join(cons.config.persistent_data_dir, 'inf')
|
||||
with open(inf, 'wb') as fd:
|
||||
fd.write(gzip.compress(b'vmlinux'))
|
||||
mkimage = cons.config.build_dir + '/tools/mkimage'
|
||||
u_boot_utils.run_and_log(
|
||||
cons, f'{mkimage} -f auto -d {inf} {os.path.join(mnt, vmlinux)}')
|
||||
|
||||
with open(os.path.join(mnt, initrd), 'w', encoding='ascii') as fd:
|
||||
print('initrd', file=fd)
|
||||
|
||||
if dtbdir:
|
||||
mkdir_cond(os.path.join(mnt, dtbdir))
|
||||
|
||||
dtb_file = os.path.join(mnt, f'{dtbdir}/sandbox.dtb')
|
||||
u_boot_utils.run_and_log(
|
||||
cons, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
|
||||
|
||||
fsfile = 'vfat18M.img'
|
||||
u_boot_utils.run_and_log(cons, f'fallocate -l 18M {fsfile}')
|
||||
u_boot_utils.run_and_log(cons, f'mkfs.vfat {fsfile}')
|
||||
u_boot_utils.run_and_log(cons, ['sh', '-c', f'mcopy -i {fsfile} {mnt}/* ::/'])
|
||||
u_boot_utils.run_and_log(cons, f'dd if={fsfile} of={fname} bs=1M seek=1')
|
||||
u_boot_utils.run_and_log(cons, f'rm -rf {mnt}')
|
||||
u_boot_utils.run_and_log(cons, f'rm -f {fsfile}')
|
||||
|
||||
|
||||
def setup_bootmenu_image(cons):
|
||||
"""Create a 20MB disk image with a single ext4 partition
|
||||
|
||||
@@ -197,36 +234,8 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl)
|
||||
append ro root=UUID=9732b35b-4cd5-458b-9b91-80f7047e0b8a rhgb quiet LANG=en_US.UTF-8 cma=192MB cma=256MB
|
||||
fdtdir /%s/
|
||||
initrd /%s''' % (vmlinux, dtbdir, initrd)
|
||||
ext = os.path.join(mnt, 'extlinux')
|
||||
mkdir_cond(ext)
|
||||
|
||||
conf = os.path.join(ext, 'extlinux.conf')
|
||||
with open(conf, 'w', encoding='ascii') as fd:
|
||||
print(script, file=fd)
|
||||
|
||||
inf = os.path.join(cons.config.persistent_data_dir, 'inf')
|
||||
with open(inf, 'wb') as fd:
|
||||
fd.write(gzip.compress(b'vmlinux'))
|
||||
mkimage = cons.config.build_dir + '/tools/mkimage'
|
||||
u_boot_utils.run_and_log(
|
||||
cons, f'{mkimage} -f auto -d {inf} {os.path.join(mnt, vmlinux)}')
|
||||
|
||||
with open(os.path.join(mnt, initrd), 'w', encoding='ascii') as fd:
|
||||
print('initrd', file=fd)
|
||||
|
||||
mkdir_cond(os.path.join(mnt, dtbdir))
|
||||
|
||||
dtb_file = os.path.join(mnt, f'{dtbdir}/sandbox.dtb')
|
||||
u_boot_utils.run_and_log(
|
||||
cons, f'dtc -o {dtb_file}', stdin=b'/dts-v1/; / {};')
|
||||
|
||||
fsfile = 'vfat18M.img'
|
||||
u_boot_utils.run_and_log(cons, f'fallocate -l 18M {fsfile}')
|
||||
u_boot_utils.run_and_log(cons, f'mkfs.vfat {fsfile}')
|
||||
u_boot_utils.run_and_log(cons, ['sh', '-c', f'mcopy -i {fsfile} {mnt}/* ::/'])
|
||||
u_boot_utils.run_and_log(cons, f'dd if={fsfile} of={fname} bs=1M seek=1')
|
||||
u_boot_utils.run_and_log(cons, f'rm -rf {mnt}')
|
||||
u_boot_utils.run_and_log(cons, f'rm -f {fsfile}')
|
||||
setup_extlinux_image(cons, mmc_dev, vmlinux, initrd, dtbdir, script)
|
||||
|
||||
def setup_cros_image(cons):
|
||||
"""Create a 20MB disk image with ChromiumOS partitions"""
|
||||
@@ -566,6 +575,23 @@ def setup_efi_image(cons):
|
||||
u_boot_utils.run_and_log(cons, f'rm -rf {mnt}')
|
||||
u_boot_utils.run_and_log(cons, f'rm -f {fsfile}')
|
||||
|
||||
|
||||
def setup_localboot_image(cons):
|
||||
"""Create a 20MB disk image with a single FAT partition"""
|
||||
mmc_dev = 9
|
||||
fname, mnt = setup_image(cons, mmc_dev, 0xc, second_part=True)
|
||||
|
||||
script = '''DEFAULT local
|
||||
|
||||
LABEL local
|
||||
SAY Doing local boot...
|
||||
LOCALBOOT 0
|
||||
'''
|
||||
vmlinux = 'vmlinuz'
|
||||
initrd = 'initrd.img'
|
||||
setup_extlinux_image(cons, mmc_dev, vmlinux, initrd, None, script)
|
||||
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_bootflow')
|
||||
@pytest.mark.buildconfigspec('sandbox')
|
||||
def test_ut_dm_init_bootstd(u_boot_console):
|
||||
@@ -577,6 +603,7 @@ def test_ut_dm_init_bootstd(u_boot_console):
|
||||
setup_cros_image(u_boot_console)
|
||||
setup_android_image(u_boot_console)
|
||||
setup_efi_image(u_boot_console)
|
||||
setup_localboot_image(u_boot_console)
|
||||
|
||||
# Restart so that the new mmc1.img is picked up
|
||||
u_boot_console.restart_uboot()
|
||||
|
||||
Reference in New Issue
Block a user