[U-Boot] [PATCH 2/2] arm64: booti: allow to place kernel image anywhere in physical memory

Masahiro Yamada yamada.masahiro at socionext.com
Tue Feb 28 17:03:58 UTC 2017


Hi Tom,

2017-02-27 7:41 GMT+09:00 Tom Rini <trini at konsulko.com>:
> On Thu, Feb 23, 2017 at 10:31:17AM -0500, Tom Rini wrote:
>> On Thu, Feb 23, 2017 at 06:17:38PM +0900, Masahiro Yamada wrote:
>> > Hi Tom,
>> >
>> >
>> > 2017-02-23 1:19 GMT+09:00 Tom Rini <trini at konsulko.com>:
>> > > On Wed, Feb 22, 2017 at 11:34:26AM +0900, Masahiro Yamada wrote:
>> > >
>> > >> At first, the ARM64 Linux booting requirement recommended that the
>> > >> kernel image be placed text_offset bytes from 2MB aligned base near
>> > >> the start of usable system RAM because memory below that base address
>> > >> was unusable at that time.
>> > >>
>> > >> This requirement was relaxed by Linux commit a7f8de168ace ("arm64:
>> > >> allow kernel Image to be loaded anywhere in physical memory").
>> > >> Since then, the bit 3 of the flags field indicates the tolerance
>> > >> of the kernel physical placement.  If this bit is set, the 2MB
>> > >> aligned base may be anywhere in physical memory.  For details, see
>> > >> Documentation/arm64/booting.txt of Linux.
>> > >>
>> > >> The booti command should be also relaxed to not expect the kernel
>> > >> image at the start of the system RAM.  Even when booting older
>> > >> kernel versions, it still makes sense to have some space below the
>> > >> kernel.  For example, some firmware may sit at the start of the
>> > >> system RAM.
>> > >>
>> > >> After all, the most flexible way for booting the kernel is to respect
>> > >> the original images->ep instead of gd->bd->bi_dram[0].start.  If
>> > >> image->ep (which is the address given to the booti command) already
>> > >> meets the address requirement, just use it.  If not, relocate the
>> > >> kernel to the next 2MB aligned address.
>> > >>
>> > >> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
>> > >> ---
>> > >>
>> > >>  cmd/booti.c | 6 +++++-
>> > >>  1 file changed, 5 insertions(+), 1 deletion(-)
>> > >>
>> > >> diff --git a/cmd/booti.c b/cmd/booti.c
>> > >> index f65f0e7..9408c34 100644
>> > >> --- a/cmd/booti.c
>> > >> +++ b/cmd/booti.c
>> > >> @@ -11,6 +11,8 @@
>> > >>  #include <image.h>
>> > >>  #include <lmb.h>
>> > >>  #include <mapmem.h>
>> > >> +#include <linux/kernel.h>
>> > >> +#include <linux/sizes.h>
>> > >>
>> > >>  DECLARE_GLOBAL_DATA_PTR;
>> > >>
>> > >> @@ -54,7 +56,9 @@ static int booti_setup(bootm_headers_t *images)
>> > >>        * If we are not at the correct run-time location, set the new
>> > >>        * correct location and then move the image there.
>> > >>        */
>> > >> -     dst = gd->bd->bi_dram[0].start + le64_to_cpu(ih->text_offset);
>> > >> +     dst = images->ep - ih->text_offset;
>> > >> +     dst = ALIGN(dst, SZ_2M);
>> > >> +     dst += ih->text_offset;
>> > >
>> > > I think the code will be slightly more complex here but I would rather
>> > > see us check for the presence of the flag which allows for us to
>> > > relocate things rather than assume that we can always use the address
>> > > provided, or round it up.  The 'contract' wwith the kernel previously
>> > > said it must be from start of memory and I'd rather not change that.
>> >
>> >
>> > At first, I tried this approach.
>> >
>> > The problem (at least for me) is
>> > commit a7f8de168ace is quite new; this is only included in Linux 4.5 and later.
>> > Linux 4.4 LTS will be used on Socionext's products for a while.
>> > However, I need to avoid the relocation of the kernel image.
>> >
>> > The gd->bd->bi_dram[0].start points to the start of the DRAM.
>> > Here, some firmware is sitting at the start of the DRAM.
>> > To hide the head of the memory from Linux,
>> > the memory node in the device tree is carved out.
>> >
>> > If CONFIG_ARCH_FIXUP_FDT_MEMORY is not set,
>> > U-Boot passes the memory node as-is to Linux.
>> > As a result, the Image is placed out of the available memory region
>> > specified by DT,
>> > then Linux fails to boot.
>> >
>> >
>> > Somehow I want to achieve,
>> > "Even when booting older kernel versions, it still makes sense to have
>> > some space below the
>> > kernel.  For example, some firmware may sit at the start of the system RAM."
>> >
>> >
>> > Perhaps, can we introduce a CONFIG
>> > to enable/disable the relocation?
>> > Or, any other good idea?
>>
>> I guess the answer is that I need to find some time to re-read the
>> history on Documentation/arm64/booting.txt to see when various
>> restrictions changed / were introduced.  I'm also willing to say that
>> perhaps my initial implementation (or the follow up when text_offset was
>> introduced) was incorrectly too strict.
>
> So, I re-read what the changes to the document were, before and after.
> Prior to the change, the kernel will not be able to use any memory below
> the 2MiB aligned address.  After the change, the memory must be excluded
> using normal mechanisms (and is outside of this problem here).  So,
> conceptually, I'm OK with changing our logic here a bit, what I did at
> first wrt text_offset was too literal.  But:
> a) We need to re-work the comment in question now to explain a little
> better what is going on.

Yes.

> b) we should continue to use le64_to_cpu() on text_offset (for
> consistency).

I had accidentally dropped it.
Will fix.

> c) I'm not convinced your math above is correct.  images->ep is where we
> were put in memory.  This is what we should make sure is 2MiB aligned,
> and then add to it the text_offset.  And some quick testing with
> CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET enabled Images :)


My intention is

  images->ep  =  (2MiB aligned base)  + text_offset


If this equation is met, the image is already placed at the bootable position.
We can skip the relocation.


Theoretically, we can not know the value of text_offset in advance
(especially for CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET).
However, in practice, we know text_offset is 0x80000.


If we put the image at 2MiB aligned base, the relocation would always happen.


-- 
Best Regards
Masahiro Yamada


More information about the U-Boot mailing list