summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2023-01-24 14:04:14 -0500
committerTom Rini <[email protected]>2023-01-24 14:04:14 -0500
commit4e1ab2065e21e48a3087144ab826f12cfb797a65 (patch)
tree1dc9e793258c5a4a1be4d5e6d554f7f1a82450f3 /cmd
parentdd31cd58b02729807934cb699b164b1f8736620f (diff)
parent3891c68ef50eda38d78c95ecd03aed030aa6bb53 (diff)
Merge branch '2023-01-24-bootstd-allow-migration-from-distro_bootcmd-script'
To quote the author: So far, standard boot does not replicate all the of the functionality of the distro_bootcmd scripts. In particular it lacks some bootdevs and some of the bootmeths are incomplete. Also there is currently no internal mechanism to enumerate buses in order to discover bootdevs, e.g. with USB. This series addresses these shortcomings: - Adds the concept of a 'bootdev hunter' to enumerate buses, etc. in an effort to find bootdevs of a certain priority - Adds bootdevs for SCSI, IDE, NVMe, virtio, SPI flash - Handles PXE and DHCP properly - Supports reading the device tree with EFI and reading scripts from the network It also tidies up label processing, so it is possible to use: bootflow scan mmc2 to scan just one MMC device (with BOOTSTD_FULL). As before this implementation still relies on CONFIG_CMDLINE being enabled, mostly for the network stack. Further work would be required to disentangle that. Quite a few tests are added but there are some gaps: - SPI flash bootdev - EFI FDT loading Note that SATA works via SCSI (CONFIG_SCSI_AHCI) and does not use driver model. Only pogo_v4 seems to be affected. Probably all thats is needed is to call bootdev_setup_sibling_blk() in the Marvell SATA driver. Also, while it would be possible to init MMC in a bootdev hunter, there is no point since U-Boot always inits MMC on startup, if present. With this series it should be possible to migrate boards to standard boot by removing the inclusion of config_distro_bootcmd.h and instead adding a suitable value for boot_targets to the environment, e.g.: boot_targets=mmc1 mmc0 nvme scsi usb pxe dhcp spi Thus it is possible to boot automatically without scripts and boards can use a text-based environment instead of the config.h files. To demonstrate this, rockpro64-rk3399 is migrated to standard boot in this series. Full migration could probably be automated using a script, similar in concept to moveconfig: - obtain the board environment via 'make u-boot-initial-env' - get the value of "boot_targets" - drop config_distro_bootcmd.h from the config.h file - rebuild again to get the environment without distro scripts - write the environment (adding boot_targets) to board.env - remove CONFIG_EXTRA_ENV_SETTINGS from the config.h file
Diffstat (limited to 'cmd')
-rw-r--r--cmd/bootdev.c42
-rw-r--r--cmd/bootflow.c97
-rw-r--r--cmd/dm.c10
-rw-r--r--cmd/extension_board.c43
-rw-r--r--cmd/net.c35
-rw-r--r--cmd/vbe.c7
6 files changed, 167 insertions, 67 deletions
diff --git a/cmd/bootdev.c b/cmd/bootdev.c
index ecd797c0503..5b1efaaee87 100644
--- a/cmd/bootdev.c
+++ b/cmd/bootdev.c
@@ -57,7 +57,7 @@ static int do_bootdev_select(struct cmd_tbl *cmdtp, int flag, int argc,
std->cur_bootdev = NULL;
return 0;
}
- if (bootdev_find_by_any(argv[1], &dev))
+ if (bootdev_find_by_any(argv[1], &dev, NULL))
return CMD_RET_FAILURE;
std->cur_bootdev = dev;
@@ -107,14 +107,48 @@ static int do_bootdev_info(struct cmd_tbl *cmdtp, int flag, int argc,
return 0;
}
+static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct bootstd_priv *priv;
+ const char *spec = NULL;
+ bool list = false;
+ int ret = 0;
+
+ if (argc >= 2) {
+ if (!strcmp(argv[1], "-l"))
+ list = true;
+ else
+ spec = argv[1];
+ }
+
+ ret = bootstd_get_priv(&priv);
+ if (ret)
+ return ret;
+ if (list) {
+ bootdev_list_hunters(priv);
+ } else {
+ ret = bootdev_hunt(spec, true);
+ if (ret) {
+ printf("Failed (err=%dE)\n", ret);
+
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_SYS_LONGHELP
static char bootdev_help_text[] =
- "list [-p] - list all available bootdevs (-p to probe)\n"
- "bootdev select <bd> - select a bootdev by name | label | seq\n"
- "bootdev info [-p] - show information about a bootdev (-p to probe)";
+ "list [-p] - list all available bootdevs (-p to probe)\n"
+ "bootdev hunt [-l|<spec>] - use hunt drivers to find bootdevs\n"
+ "bootdev select <bd> - select a bootdev by name | label | seq\n"
+ "bootdev info [-p] - show information about a bootdev (-p to probe)";
#endif
U_BOOT_CMD_WITH_SUBCMDS(bootdev, "Boot devices", bootdev_help_text,
U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootdev_list),
+ U_BOOT_SUBCMD_MKENT(hunt, 2, 1, do_bootdev_hunt),
U_BOOT_SUBCMD_MKENT(select, 2, 1, do_bootdev_select),
U_BOOT_SUBCMD_MKENT(info, 2, 1, do_bootdev_info));
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 2b6ed26fdcb..692bc6d117f 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -93,11 +93,12 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
{
struct bootstd_priv *std;
struct bootflow_iter iter;
- struct udevice *dev;
+ struct udevice *dev = NULL;
struct bootflow bflow;
bool all = false, boot = false, errors = false, no_global = false;
- bool list = false;
+ bool list = false, no_hunter = false;
int num_valid = 0;
+ const char *label = NULL;
bool has_args;
int ret, i;
int flags;
@@ -105,7 +106,6 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
ret = bootstd_get_priv(&std);
if (ret)
return CMD_RET_FAILURE;
- dev = std->cur_bootdev;
has_args = argc > 1 && *argv[1] == '-';
if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL)) {
@@ -115,15 +115,14 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
errors = strchr(argv[1], 'e');
no_global = strchr(argv[1], 'G');
list = strchr(argv[1], 'l');
+ no_hunter = strchr(argv[1], 'H');
argc--;
argv++;
}
- if (argc > 1) {
- const char *label = argv[1];
-
- if (bootdev_find_by_any(label, &dev))
- return CMD_RET_FAILURE;
- }
+ if (argc > 1)
+ label = argv[1];
+ if (!label)
+ dev = std->cur_bootdev;
} else {
if (has_args) {
printf("Flags not supported: enable CONFIG_BOOTFLOW_FULL\n");
@@ -141,58 +140,42 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc,
flags |= BOOTFLOWF_ALL;
if (no_global)
flags |= BOOTFLOWF_SKIP_GLOBAL;
+ if (!no_hunter)
+ flags |= BOOTFLOWF_HUNT;
/*
* If we have a device, just scan for bootflows attached to that device
*/
- if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL) && dev) {
- if (list) {
- printf("Scanning for bootflows in bootdev '%s'\n",
- dev->name);
- show_header();
- }
+ if (list) {
+ printf("Scanning for bootflows ");
+ if (dev)
+ printf("in bootdev '%s'\n", dev->name);
+ else if (label)
+ printf("with label '%s'\n", label);
+ else
+ printf("in all bootdevs\n");
+ show_header();
+ }
+ if (dev)
bootdev_clear_bootflows(dev);
- for (i = 0,
- ret = bootflow_scan_bootdev(dev, &iter, flags, &bflow);
- i < 1000 && ret != -ENODEV;
- i++, ret = bootflow_scan_next(&iter, &bflow)) {
- bflow.err = ret;
- if (!ret)
- num_valid++;
- ret = bootdev_add_bootflow(&bflow);
- if (ret) {
- printf("Out of memory\n");
- return CMD_RET_FAILURE;
- }
- if (list)
- show_bootflow(i, &bflow, errors);
- if (boot && !bflow.err)
- bootflow_run_boot(&iter, &bflow);
- }
- } else {
- if (list) {
- printf("Scanning for bootflows in all bootdevs\n");
- show_header();
- }
+ else
bootstd_clear_glob();
-
- for (i = 0,
- ret = bootflow_scan_first(&iter, flags, &bflow);
- i < 1000 && ret != -ENODEV;
- i++, ret = bootflow_scan_next(&iter, &bflow)) {
- bflow.err = ret;
- if (!ret)
- num_valid++;
- ret = bootdev_add_bootflow(&bflow);
- if (ret) {
- printf("Out of memory\n");
- return CMD_RET_FAILURE;
- }
- if (list)
- show_bootflow(i, &bflow, errors);
- if (boot && !bflow.err)
- bootflow_run_boot(&iter, &bflow);
+ for (i = 0,
+ ret = bootflow_scan_first(dev, label, &iter, flags, &bflow);
+ i < 1000 && ret != -ENODEV;
+ i++, ret = bootflow_scan_next(&iter, &bflow)) {
+ bflow.err = ret;
+ if (!ret)
+ num_valid++;
+ ret = bootdev_add_bootflow(&bflow);
+ if (ret) {
+ printf("Out of memory\n");
+ return CMD_RET_FAILURE;
}
+ if (list)
+ show_bootflow(i, &bflow, errors);
+ if (boot && !bflow.err)
+ bootflow_run_boot(&iter, &bflow);
}
bootflow_iter_uninit(&iter);
if (list)
@@ -344,6 +327,12 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc,
printf("Logo size: %x (%d bytes)\n", bflow->logo_size,
bflow->logo_size);
}
+ printf("FDT: %s\n", bflow->fdt_fname);
+ if (bflow->fdt_fname) {
+ printf("FDT size: %x (%d bytes)\n", bflow->fdt_size,
+ bflow->fdt_size);
+ printf("FDT addr: %lx\n", bflow->fdt_addr);
+ }
printf("Error: %d\n", bflow->err);
if (dump && bflow->buf) {
/* Set some sort of maximum on the size */
diff --git a/cmd/dm.c b/cmd/dm.c
index 218be85795d..979cd36061e 100644
--- a/cmd/dm.c
+++ b/cmd/dm.c
@@ -59,7 +59,11 @@ static int do_dm_dump_static_driver_info(struct cmd_tbl *cmdtp, int flag,
static int do_dm_dump_tree(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- dm_dump_tree();
+ bool sort;
+
+ sort = argc > 1 && !strcmp(argv[1], "-s");
+
+ dm_dump_tree(sort);
return 0;
}
@@ -87,7 +91,7 @@ static char dm_help_text[] =
"dm drivers Dump list of drivers with uclass and instances\n"
DM_MEM_HELP
"dm static Dump list of drivers with static platform data\n"
- "dm tree Dump tree of driver model devices ('*' = activated)\n"
+ "dm tree [-s] Dump tree of driver model devices (-s=sort)\n"
"dm uclass Dump list of instances for each uclass"
;
#endif
@@ -98,5 +102,5 @@ U_BOOT_CMD_WITH_SUBCMDS(dm, "Driver model low level access", dm_help_text,
U_BOOT_SUBCMD_MKENT(drivers, 1, 1, do_dm_dump_drivers),
DM_MEM
U_BOOT_SUBCMD_MKENT(static, 1, 1, do_dm_dump_static_driver_info),
- U_BOOT_SUBCMD_MKENT(tree, 1, 1, do_dm_dump_tree),
+ U_BOOT_SUBCMD_MKENT(tree, 2, 1, do_dm_dump_tree),
U_BOOT_SUBCMD_MKENT(uclass, 1, 1, do_dm_dump_uclass));
diff --git a/cmd/extension_board.c b/cmd/extension_board.c
index f94abd612d5..2b672d888c6 100644
--- a/cmd/extension_board.c
+++ b/cmd/extension_board.c
@@ -5,7 +5,9 @@
*/
#include <common.h>
+#include <bootdev.h>
#include <command.h>
+#include <dm.h>
#include <malloc.h>
#include <extension_board.h>
#include <mapmem.h>
@@ -80,8 +82,7 @@ static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_SUCCESS;
}
-static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
+static int extension_scan(bool show)
{
struct extension *extension, *next;
int extension_num;
@@ -91,12 +92,23 @@ static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
free(extension);
}
extension_num = extension_board_scan(&extension_list);
+ if (show && extension_num >= 0)
+ printf("Found %d extension board(s).\n", extension_num);
+
+ /* either the number of extensions, or -ve for error */
+ return extension_num;
+}
+
+
+static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ int extension_num;
+ extension_num = extension_scan(true);
if (extension_num < 0)
return CMD_RET_FAILURE;
- printf("Found %d extension board(s).\n", extension_num);
-
return CMD_RET_SUCCESS;
}
@@ -166,3 +178,26 @@ U_BOOT_CMD(extension, 3, 1, do_extensionops,
"extension list - lists available extension(s) board(s)\n"
"extension apply <extension number|all> - applies DT overlays corresponding to extension boards\n"
);
+
+static int extension_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+ int ret;
+
+ ret = env_set_hex("extension_overlay_addr",
+ env_get_hex("fdtoverlay_addr_r", 0));
+ if (ret)
+ return log_msg_ret("env", ret);
+
+ ret = extension_scan(show);
+ if (ret < 0)
+ return log_msg_ret("ext", ret);
+
+ return 0;
+}
+
+/* extensions should have a uclass - for now we use UCLASS_SIMPLE_BUS uclass */
+BOOTDEV_HUNTER(extension_bootdev_hunter) = {
+ .prio = BOOTDEVP_1_PRE_SCAN,
+ .uclass = UCLASS_SIMPLE_BUS,
+ .hunt = extension_bootdev_hunt,
+};
diff --git a/cmd/net.c b/cmd/net.c
index dd50930a362..4227321871c 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -4,6 +4,8 @@
* Wolfgang Denk, DENX Software Engineering, [email protected].
*/
+#define LOG_CATEGORY UCLASS_ETH
+
/*
* Boot support
*/
@@ -13,6 +15,7 @@
#include <dm.h>
#include <env.h>
#include <image.h>
+#include <log.h>
#include <net.h>
#include <net6.h>
#include <net/udp.h>
@@ -120,6 +123,38 @@ U_BOOT_CMD(
"boot image via network using DHCP/TFTP protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]"
);
+
+int dhcp_run(ulong addr, const char *fname, bool autoload)
+{
+ char *dhcp_argv[] = {"dhcp", NULL, (char *)fname, NULL};
+ struct cmd_tbl cmdtp = {}; /* dummy */
+ char file_addr[17];
+ int old_autoload;
+ int ret, result;
+
+ log_debug("addr=%lx, fname=%s, autoload=%d\n", addr, fname, autoload);
+ old_autoload = env_get_yesno("autoload");
+ ret = env_set("autoload", autoload ? "y" : "n");
+ if (ret)
+ return log_msg_ret("en1", -EINVAL);
+
+ if (autoload) {
+ sprintf(file_addr, "%lx", addr);
+ dhcp_argv[1] = file_addr;
+ }
+
+ result = do_dhcp(&cmdtp, 0, !autoload ? 1 : fname ? 3 : 2, dhcp_argv);
+
+ ret = env_set("autoload", old_autoload == -1 ? NULL :
+ old_autoload ? "y" : "n");
+ if (ret)
+ return log_msg_ret("en2", -EINVAL);
+
+ if (result)
+ return log_msg_ret("res", -ENOENT);
+
+ return 0;
+}
#endif
#if defined(CONFIG_CMD_NFS)
diff --git a/cmd/vbe.c b/cmd/vbe.c
index befaf07c64d..600690394eb 100644
--- a/cmd/vbe.c
+++ b/cmd/vbe.c
@@ -79,10 +79,13 @@ static int do_vbe_info(struct cmd_tbl *cmdtp, int flag, int argc,
static int do_vbe_state(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
- struct vbe_handoff *handoff;
+ struct vbe_handoff *handoff = NULL;
int i;
- handoff = bloblist_find(BLOBLISTT_VBE, sizeof(struct vbe_handoff));
+ if (IS_ENABLED(CONFIG_BLOBLIST)) {
+ handoff = bloblist_find(BLOBLISTT_VBE,
+ sizeof(struct vbe_handoff));
+ }
if (!handoff) {
printf("No VBE state\n");
return CMD_RET_FAILURE;