Understand U-Boot memory footprint

前端 未结 1 948
无人及你
无人及你 2021-01-30 15:40

I don\'t understand what is happening in RAM when loading U-Boot. I\'m working on a Xilinx Zynq ZC702 evaluation kit and I\'m trying to load a Linux kernel on it using U-Boot. S

相关标签:
1条回答
  • 2021-01-30 16:05

    u-boot relocation on ARM architecture

    Here is the whole sequence for two-stage boot process:

    1. ROM-code reads SPL (from MLO file on SD card) to CONFIG_SPL_TEXT_BASE address. This address is usually in SRAM which doesn't need to be initialized to be functional (as opposed to RAM). ROM-code jumps to SPL code.
    2. SPL configures RAM, then reads u-boot (from u-boot.img file on SD card) to CONFIG_SYS_TEXT_BASE RAM address (which is usually in the begin of RAM) and run it
    3. u-boot relocates itself to gd->relocaddr RAM address (which is usually in the end of RAM) and jumps to relocated code
    4. Now we are ready to boot kernel

    For single-stage boot you don't have SPL, usually only u-boot.bin file is used. In that case you only have steps 3 and 4.

    There are two cases regarding relocation (as described in doc/README.arm-relocation):

    1. CONFIG_SYS_TEXT_BASE != gd->relocaddr: relocation will be performed
    2. CONFIG_SYS_TEXT_BASE == gd->relocaddr: relocation will not be performed

    In your case you see that relocation was performed (as CONFIG_SYS_TEXT_BASE != gd->relocaddr).

    So, addressing your question:

    Why U-Boot need those two offsets ?

    The reason behind that relocation is described in u-boot ARM relocation task:

    ...we can measure the actual size of memory present on the board, and then relocate U-Boot to the very end of the RAM, leaving nearly the whole RAM usable as one big contiguous area for "applications" like loading Linux kernel, ramdisk, etc.

    Indeed, if you look to code you can see that gd->relocaddr is the end of RAM minus monitor code (U-Boot) size:

    gd->relocaddr = gd->ram_top;
    ...
    gd->relocaddr -= gd->mon_len;
    

    Also some extra memory reserving can be performed. For example, on my platform (TI DRA7XX EVM), I can see next functions beeing called:

    setup_dest_addr()
    reserve_round_4k()
    reserve_mmu()
    reserve_uboot()
    

    The actual relocation is done just after board_init_f() call.

    arch/arm/lib/crt0.S:

    bl board_init_f
    ...
    b relocate_code
    

    arch/arm/lib/relocate.S:

    ENTRY(relocate_code)
    

    Now it's easy to answer your next question:

    what is the real memory footprint of U-Boot ?

    Before relocation U-Boot resides at CONFIG_SYS_TEXT_BASE. After relocation U-Boot resides at gs->relocaddr.

    Regarding your last question:

    where can I put my kernel to be sure that it will not overwrite something?

    Since U-Boot was relocated to the end of RAM you can theoretically use any RAM address to put kernel to. But take a look at CONFIG_EXTRA_ENV_SETTINGS definition in include/configs/zynq-common.h:

    "sdboot=if mmcinfo; then " \
            "run uenvboot; " \
            "echo Copying Linux from SD to RAM... && " \
            "load mmc 0 ${kernel_load_address} ${kernel_image} && " \
            "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \
            "load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \
            "bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \
        "fi\0" \
    

    From there you can see that you should load kernel to ${kernel_load_address}, which is 0x2080000:

    "kernel_load_address=0x2080000\0" \
    

    See rest of that definition for other constants.

    bdinfo command

    You can find bdinfo command useful: relocation address along with other useful information can be found using bdinfo command from U-Boot shell. For example for DRA7XX EVM:

    => bdinfo
    
    DRAM bank   = 0x00000000
    -> start    = 0x80000000
    -> size     = 0x60000000
    TLB addr    = 0xDFFF0000
    relocaddr   = 0xDFF5D000
    reloc off   = 0x5F75D000
    irq_sp      = 0xDEF3CEE0
    sp start    = 0xDEF3CED0
    

    From here you can see that:

    • RAM starts at 0x80000000
    • RAM size is 0x60000000
    • ...so RAM end (gd->ram_top) is 0x80000000 + 0x60000000 = 0xE0000000
    • relocation address is 0xDFF5D000
    • reserved memory for relocation is 0xE0000000 - 0xDFF5D000 = 652 KB
    • monitor (U-Boot) size is approximately TLB addr - relocaddr = 0xDFFF0000 - 0xDFF5D000 = 588 KB

    See also:

    [1] u-boot : Relocation

    [2] what is the use of SPL (secondary program loader)

    [3] commit that adds ARM relocation support to u-boot

    0 讨论(0)
提交回复
热议问题