All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Warren <swarren@wwwdotorg.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 1/2] Pass through start.elf bootargs on Raspberry Pi
Date: Tue, 1 Dec 2015 21:14:59 -0700	[thread overview]
Message-ID: <565E7043.6030103@wwwdotorg.org> (raw)
In-Reply-To: <CAEhB=BudnB_Vjpvv7dv4k-M-2aSu-uutzP=xZGLJdMzAKZ48rA@mail.gmail.com>

On 11/29/2015 11:40 AM, Marco Schuster wrote:
> On Raspberry Pi, the primary bootloader start.elf uses the options in
> config.txt, as well as options hidden in the firmware itself, to tell
> the Linux kernel e.g. framebuffer sizes, memory regions, MAC addresses
> and more.

Was this patch sent using "git send-email"? I assume not, since it is
corrupted due to wrapping.

I suspect ./scripts/checkpatch.pl also wasn't run, since it would
complain about over-long lines, and multiple other formatting errors.

> Normally, u-boot would not be able to pass through these options to
> the Linux kernel. This patch adds pass-through support via an
> additional env variable "bootargs_orig" which is loaded with the
> original cmdline obtained from ATAG or the FDT.
> 
> In addition, this allows the user to configure DT overlays the "Pi
> way" by enabling them in config.txt, as this patch passes through the
> full FDT if it has been passed one by u-boot.
> 
> Note that, as stated in the comment block, for FDT passthrough to
> work, the u-boot.img must be run through a perl script by the
> Raspberry Pi Foundation, which appends a trailer to the image telling
> start.elf to supply a FDT instead of an ATAG struct.

This feature sounds fine. However, it should be optional. It likely only
makes sense when booting a downstream Pi Foundation kernel, and not when
booting an upstream/mainline kernel with matching DT using the
standardized DT bindings. As such, I think this feature should be
optional (e.g. perhaps en-/dis-abled by an environment variable at
run-time) so that the user gets to choose whether to use the feature.

> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index 6451d1d..d8d0fbb 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -259,6 +259,72 @@ int misc_init_r(void)
>  #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
>         set_board_info();
>  #endif
> +
> +       /*
> +        * The RPi start.elf passes important system configuration
> +        * like memory sizes and LED GPIO assignments to the kernel
> +        * via kernel command line.
> +        *
> +        * Therefore we have to parse the passed ATAG or FDT to get the

s/have to/may/

> +        * commandline and pass it through to script-land via the env
> +        * variable "bootargs_orig" so it can be passed on.
> +        *
> +        * By default, start.elf assumes a non-DT capable kernel and
> +        * passes the commandline via ATAG; this requires u-boot to
> +        * load the FDT from /boot and pass it on. This works if no
> +        * overlays have been passed through, but once overlays are in
> +        * the mix, stuff gets complicated to do in u-boot.

Ideally, DT overlays would be either implemented in U-Boot, or deferred
until the kernel boots and user-space can load overlays. I suspect the
latter is more inline with the usage model expected by
upstream/mainline, although I haven't checked to see.

> +        *
> +        * To force start.elf to pass a processed, ready-to-go DT,
> +        * you have to use the mkknlimg tool on the u-boot image:
> +        * ./mkknlimg --dtok u-boot.bin /boot/u-boot.bin
> +        *
> +        * mkknlimg can be obtained from
> https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo
> +        *
> +        * User scripts can check for successful bootargs retrieval
> +        * in the env variable pi_bootmode, which is either fdt, atag
> +        * or unknown in case of an error.
> +        *
> +        * The location 0x100 is hard-coded in start.elf, and it is
> +        * the same as in the default bootscripts, so you only have
> +        * to omit the fatload command loading the raw FDT to get
> +        * going.

"omit the fatload command" from where?

Personally I've been using extlinux.conf on my Pi for a while, so there
is no "fatload" anywhere that I'm aware of.

> +        */
> +
> +       void* ptr = (char*) 0x100;
> +       struct tag_header* atag_ptr = ptr;
> +       setenv("pi_bootmode","unknown");
> +
> +       if(atag_ptr->tag != ATAG_CORE) {
> +               if(atag_ptr->size == be32_to_cpu(FDT_MAGIC)) {
> +                       set_working_fdt_addr((ulong) ptr);

Doesn't that set the address of the DT that U-Boot uses to configure
itself, not the DT that U-Boot will pass to the kernel? The two are
certainly separate concepts. This code should set $fdt_addr/$fdt_addr_r
if the DT is detected, so that scripts can affect whether this DT is used.

> +                       int nodeoffset = fdt_path_offset(working_fdt,
> "/chosen");
> +                       int len;
> +                       const void* nodep = fdt_getprop(working_fdt,
> nodeoffset, "bootargs", &len);
> +                       if(len==0) {
> +                               printf("WARNING: Could not determine
> bootargs from FDT!\n");
> +                       } else {
> +                               printf("Set bootargs_orig from FDT\n");

debug() seems more appropriate than printf(), except for errors.

> +                               setenv("bootargs_orig", (char*) nodep);
> +                               setenv("pi_bootmode","fdt");
> +                       }
> +               } else {
> +                       printf("Warning: start.elf did not pass ATAG
> or FDT parameters\n");
> +               }
> +       } else {
> +               while(atag_ptr->tag != ATAG_NONE) {
> +                       printf("at %p, have %x (len
> %x)\n",atag_ptr,atag_ptr->tag, atag_ptr->size);
> +                       if(atag_ptr->tag == ATAG_CMDLINE) {
> +                               char* old_cmdline = ptr + 8;
> +                               printf("Set bootargs_orig from ATAG\n");
> +                               setenv("bootargs_orig", old_cmdline);
> +                               setenv("pi_bootmode", "atag");
> +                       }
> +                       ptr = ptr + (atag_ptr->size * 4);
> +                       atag_ptr=ptr;
> +               }
> +       }
> +
>         return 0;
>  }

  reply	other threads:[~2015-12-02  4:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-29 18:40 [U-Boot] [PATCH 1/2] Pass through start.elf bootargs on Raspberry Pi Marco Schuster
2015-12-02  4:14 ` Stephen Warren [this message]
2015-12-02 14:49 ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=565E7043.6030103@wwwdotorg.org \
    --to=swarren@wwwdotorg.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.