[U-Boot] [PATCH 0/7] MIPS: bootm fixes and initial device tree support

This patch series fixes and prepares bootm to initially support the hand over of flattened device trees to the kernel.
The first patch fixes the missing initramfs relocation if bootm is used without subcommands.
Patches 3 and 4 make the legacy boot interface configurable.
Patch 5 adds mem, rd_start and rd_size to kernel command line for targets those do not use the legacy Linux env.
Patch 6 adds the required code to prepare a flattened device tree for the kernel. The final hand over to the kernel is not yet implemented. After the community agreed on the official MIPS boot interface for device trees, the corresponding code will be added.
Daniel Schwierzeck (7): MIPS: bootm: add missing initramfs relocation MIPS: bootm: remove unused or redundant header files MIPS: bootm: refactor preparation of Linux kernel command line MIPS: bootm: refactor preparation of Linux kernel environment MIPS: bootm: add mem, rd_start and rd_size to kernel command line MIPS: bootm: prepare a flattened device tree for the kernel MIPS: bootm: add bootstage reporting
arch/mips/Kconfig | 33 ++++++++++++++ arch/mips/lib/bootm.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 146 insertions(+), 8 deletions(-)

The initramfs is currently only relocated if the user calls the bootm ramdisk subcommand. If bootm should be used without subcommands, the arch-specific bootm code needs to implement the relocation.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/lib/bootm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 71bb0d2..f947fd6 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -52,6 +52,20 @@ void arch_lmb_reserve(struct lmb *lmb) lmb_reserve(lmb, sp, CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp); }
+static int boot_setup_linux(bootm_headers_t *images) +{ + int ret; + ulong rd_len; + + rd_len = images->rd_end - images->rd_start; + ret = boot_ramdisk_high(&images->lmb, images->rd_start, + rd_len, &images->initrd_start, &images->initrd_end); + if (ret) + return ret; + + return 0; +} + static void linux_cmdline_init(void) { linux_argc = 1; @@ -224,6 +238,8 @@ static void boot_jump_linux(bootm_headers_t *images) int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) { + int ret; + /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) return -1; @@ -243,6 +259,10 @@ int do_bootm_linux(int flag, int argc, char * const argv[], return 0; }
+ ret = boot_setup_linux(images); + if (ret) + return ret; + boot_cmdline_linux(images); boot_prep_linux(images); boot_jump_linux(images);

Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/lib/bootm.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index f947fd6..e0722d2 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -6,10 +6,7 @@ */
#include <common.h> -#include <command.h> #include <image.h> -#include <u-boot/zlib.h> -#include <asm/byteorder.h> #include <asm/addrspace.h>
DECLARE_GLOBAL_DATA_PTR;

Move preparation of Linux kernel command line in a separate function and mark it as legacy. Add a Kconfig option to make that legacy mode configurable.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/Kconfig | 13 +++++++++++++ arch/mips/lib/bootm.c | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4991da2..a5d5a33 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -116,6 +116,19 @@ config CPU_MIPS64_R2
endchoice
+menu "OS boot interface" + +config MIPS_BOOT_CMDLINE_LEGACY + bool "Hand over legacy command line to Linux kernel" + default y + help + Enable this option if you want U-Boot to hand over the Yamon-style + command line to the kernel. All bootargs will be prepared as argc/argv + compatible list. The argument count (argc) is stored in register $a0. + The address of the argument list (argv) is stored in register $a1. + +endmenu + config SUPPORTS_BIG_ENDIAN bool
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index e0722d2..a028a47 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -20,6 +20,12 @@ DECLARE_GLOBAL_DATA_PTR; #define mips_boot_malta 0 #endif
+#if defined(CONFIG_MIPS_BOOT_CMDLINE_LEGACY) +#define mips_boot_cmdline_legacy 1 +#else +#define mips_boot_cmdline_legacy 0 +#endif + static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -92,7 +98,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); }
-static void boot_cmdline_linux(bootm_headers_t *images) +static void linux_cmdline_legacy(bootm_headers_t *images) { const char *bootargs, *next, *quote;
@@ -130,8 +136,14 @@ static void boot_cmdline_linux(bootm_headers_t *images)
bootargs = next; } +}
- linux_cmdline_dump(); +static void boot_cmdline_linux(bootm_headers_t *images) +{ + if (mips_boot_cmdline_legacy) { + linux_cmdline_legacy(images); + linux_cmdline_dump(); + } }
static void linux_env_init(void)

Move preparation of Linux kernel environment in a separate function and mark it as legacy. Add a Kconfig option to make that legacy mode configurable.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/Kconfig | 9 +++++++++ arch/mips/lib/bootm.c | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a5d5a33..9b3ecea 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -127,6 +127,15 @@ config MIPS_BOOT_CMDLINE_LEGACY compatible list. The argument count (argc) is stored in register $a0. The address of the argument list (argv) is stored in register $a1.
+config MIPS_BOOT_ENV_LEGACY + bool "Hand over legacy environment to Linux kernel" + default y + help + Enable this option if you want U-Boot to hand over the Yamon-style + environment to the kernel. Information like memory size, initrd + address and size will be prepared as zero-terminated key/value list. + The address of the enviroment is stored in register $a2. + endmenu
config SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index a028a47..fa579b3 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -26,6 +26,12 @@ DECLARE_GLOBAL_DATA_PTR; #define mips_boot_cmdline_legacy 0 #endif
+#if defined(CONFIG_MIPS_BOOT_ENV_LEGACY) +#define mips_boot_env_legacy 1 +#else +#define mips_boot_env_legacy 0 +#endif + static int linux_argc; static char **linux_argv; static char *linux_argp; @@ -177,7 +183,7 @@ static void linux_env_set(const char *env_name, const char *env_val) } }
-static void boot_prep_linux(bootm_headers_t *images) +static void linux_env_legacy(bootm_headers_t *images) { char env_buf[12]; const char *cp; @@ -225,6 +231,12 @@ static void boot_prep_linux(bootm_headers_t *images) } }
+static void boot_prep_linux(bootm_headers_t *images) +{ + if (mips_boot_env_legacy) + linux_env_legacy(images); +} + static void boot_jump_linux(bootm_headers_t *images) { typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong);

If the user wants to boot a kernel without legacy environment, information like memory size, initrd address and size should be handed over to the kernel in the command line.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/lib/bootm.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index fa579b3..7a98f15 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -144,10 +144,36 @@ static void linux_cmdline_legacy(bootm_headers_t *images) } }
+static void linux_cmdline_append(bootm_headers_t *images) +{ + char buf[24]; + ulong mem, rd_start, rd_size; + + /* append mem */ + mem = gd->ram_size >> 20; + sprintf(buf, "mem=%luM", mem); + linux_cmdline_set(buf, strlen(buf)); + + /* append rd_start and rd_size */ + rd_start = images->initrd_start; + rd_size = images->initrd_end - images->initrd_start; + + if (rd_size) { + sprintf(buf, "rd_start=0x%08lX", rd_start); + linux_cmdline_set(buf, strlen(buf)); + sprintf(buf, "rd_size=0x%lX", rd_size); + linux_cmdline_set(buf, strlen(buf)); + } +} + static void boot_cmdline_linux(bootm_headers_t *images) { if (mips_boot_cmdline_legacy) { linux_cmdline_legacy(images); + + if (!mips_boot_env_legacy) + linux_cmdline_append(images); + linux_cmdline_dump(); } }

Add the initial code to prepare a flattened device tree for the kernel like relocating the FDT blob and fixing up the /chosen and /memory nodes.
The final hand over to the kernel is not yet implemented. After the community agreed on the MIPS boot interface for device trees, the corresponding code will be added.
Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com ---
arch/mips/Kconfig | 11 +++++++++++ arch/mips/lib/bootm.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9b3ecea..363f5ac 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -136,6 +136,17 @@ config MIPS_BOOT_ENV_LEGACY address and size will be prepared as zero-terminated key/value list. The address of the enviroment is stored in register $a2.
+config MIPS_BOOT_FDT + bool "Hand over a flattened device tree to Linux kernel (INCOMPLETE)" + default n + help + Enable this option if you want U-Boot to hand over a flattened + device tree to the kernel. + + Note: the final hand over to the kernel is not yet implemented. After + the community agreed on the MIPS boot interface for device trees, + the corresponding code will be added. + endmenu
config SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 7a98f15..426f68a 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -7,6 +7,7 @@
#include <common.h> #include <image.h> +#include <fdt_support.h> #include <asm/addrspace.h>
DECLARE_GLOBAL_DATA_PTR; @@ -72,9 +73,39 @@ static int boot_setup_linux(bootm_headers_t *images) if (ret) return ret;
+#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + if (images->ft_len) { + boot_fdt_add_mem_rsv_regions(&images->lmb, images->ft_addr); + + ret = boot_relocate_fdt(&images->lmb, &images->ft_addr, + &images->ft_len); + if (ret) + return ret; + } +#endif + return 0; }
+static void boot_setup_fdt(bootm_headers_t *images) +{ +#if defined(CONFIG_MIPS_BOOT_FDT) && defined(CONFIG_OF_LIBFDT) + u64 mem_start = 0; + u64 mem_size = gd->ram_size; + + debug("## setup FDT\n"); + + fdt_chosen(images->ft_addr, 1); + fdt_fixup_memory_banks(images->ft_addr, &mem_start, &mem_size, 1); + fdt_fixup_ethernet(images->ft_addr); + fdt_initrd(images->ft_addr, images->initrd_start, images->initrd_end, 1); + +#if defined(CONFIG_OF_BOARD_SETUP) + ft_board_setup(images->ft_addr, gd->bd); +#endif +#endif +} + static void linux_cmdline_init(void) { linux_argc = 1; @@ -168,7 +199,7 @@ static void linux_cmdline_append(bootm_headers_t *images)
static void boot_cmdline_linux(bootm_headers_t *images) { - if (mips_boot_cmdline_legacy) { + if (mips_boot_cmdline_legacy && !images->ft_len) { linux_cmdline_legacy(images);
if (!mips_boot_env_legacy) @@ -259,8 +290,11 @@ static void linux_env_legacy(bootm_headers_t *images)
static void boot_prep_linux(bootm_headers_t *images) { - if (mips_boot_env_legacy) + if (mips_boot_env_legacy && !images->ft_len) linux_env_legacy(images); + + if (images->ft_len) + boot_setup_fdt(images); }
static void boot_jump_linux(bootm_headers_t *images)

Signed-off-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com
---
arch/mips/lib/bootm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 426f68a..d9d8396 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -310,8 +310,12 @@ static void boot_jump_linux(bootm_headers_t *images) if (mips_boot_malta) linux_extra = gd->ram_size;
- /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); +#ifdef CONFIG_BOOTSTAGE_FDT + bootstage_fdt_add_report(); +#endif +#ifdef CONFIG_BOOTSTAGE_REPORT + bootstage_report(); +#endif
kernel(linux_argc, (ulong)linux_argv, (ulong)linux_env, linux_extra); }
participants (1)
-
Daniel Schwierzeck