O FDT realocado pelo U-Boot não pode ser acessado pelo Linux (no highmem)

3

Executamos uma versão personalizada do U-Boot em um sistema embarcado baseado no ARM e gostaríamos de carregar o Linux 4.3 com um blob da árvore de dispositivos. O sistema possui 1 GB de RAM, dos quais os 128 MB superiores são reservados para armazenamento persistente. Eu uso o tftp para copiar o kernel e o DTB em certos locais de memória (kernel: 0x02000000, DTB: 0x02400000), e por enquanto eu gostaria de ignorar o initramfs. Então eu chamo bootm 0x2000000 - 0x2400000 .

O que acontece é que o DTB é realocado até o final da memória disponível do U-Boot, para 0x37b60000 (virtual: 0xf7b60000). O Linux não inicializa porque não pode acessar esse endereço. Parece ser um problema sobre o highmem / lowmem que eu não entendo, e o lowmem termina em 760MB (virtual 0xef800000). Não é esperado que o mapa seja mapeado dinamicamente quando necessário? (CONFIG_HIGHMEM está definido.)

Qual é a maneira correta e limpa de resolver isso - porque o U-Boot usa um local mais baixo (como?) ou altera a configuração do Linux para poder acessar memória alta (como?)?

Nota: usando fdt_high = 0xffffffff (e initrd_high = 0xffffffff) o Linux inicializa bem quando a relocação é suprimida.

U-Boot com informações de depuração:

DRAM:  Monitor len: 00044358
Ram size: 40000000
Ram top: 40000000
Reserving 131072k for protected RAM at 38000000
TLB table from 37ff0000 to 37ff4000
Reserving 272k for U-Boot at: 37fab000
Reserving 4352k for malloc() at: 37b6b000
Reserving 80 Bytes for Board Info at: 37b6afb0
Reserving 160 Bytes for Global Data at: 37b6af10

RAM Configuration:
Bank #0: 00000000 1 GiB

DRAM:  1 GiB
New Stack Pointer is: 37b6aef0
Relocation Offset is: 33fab000
Relocating to 37fab000, new gd at 37b6af10, sp at 37b6aef0

[…]

*  fdt: cmdline image address = 0x02400000
## Checking for 'FDT'/'FDT Image' at 02400000
*  fdt: raw FDT blob
## Flattened Device Tree blob at 02400000
   Booting using the fdt blob at 0x2400000
   of_flat_tree at 0x02400000 size 0x0000493c
   Loading Multi-File Image ... OK
## device tree at 02400000 ... 0240493b (len=31036 [0x793C])
   Loading Device Tree to 37b60000, end 37b6793b ... OK
    
por Hans W. Heckel 25.01.2016 / 13:10

1 resposta

0

Portanto, uma das maneiras de corrigir isso é fazer uso de algumas variáveis de ambiente adicionais. Se olharmos em include / configs / ti_armv7_common.h, temos:

/*
 * We setup defaults based on constraints from the Linux kernel, which should
 * also be safe elsewhere.  We have the default load at 32MB into DDR (for
 * the kernel), FDT above 128MB (the maximum location for the end of the
 * kernel), and the ramdisk 512KB above that (allowing for hopefully never
 * seen large trees).  We say all of this must be within the first 256MB
 * as that will normally be within the kernel lowmem and thus visible via
 * bootm_size and we only run on platforms with 256MB or more of memory.
 */
#define DEFAULT_LINUX_BOOT_ENV \
        "loadaddr=0x82000000
/*
 * We setup defaults based on constraints from the Linux kernel, which should
 * also be safe elsewhere.  We have the default load at 32MB into DDR (for
 * the kernel), FDT above 128MB (the maximum location for the end of the
 * kernel), and the ramdisk 512KB above that (allowing for hopefully never
 * seen large trees).  We say all of this must be within the first 256MB
 * as that will normally be within the kernel lowmem and thus visible via
 * bootm_size and we only run on platforms with 256MB or more of memory.
 */
#define DEFAULT_LINUX_BOOT_ENV \
        "loadaddr=0x82000000%pre%" \
        "kernel_addr_r=0x82000000%pre%" \
        "fdtaddr=0x88000000%pre%" \
        "fdt_addr_r=0x88000000%pre%" \
        "rdaddr=0x88080000%pre%" \
        "ramdisk_addr_r=0x88080000%pre%" \
        "scriptaddr=0x80000000%pre%" \
        "pxefile_addr_r=0x80100000%pre%" \
        "bootm_size=0x10000000%pre%"
" \ "kernel_addr_r=0x82000000%pre%" \ "fdtaddr=0x88000000%pre%" \ "fdt_addr_r=0x88000000%pre%" \ "rdaddr=0x88080000%pre%" \ "ramdisk_addr_r=0x88080000%pre%" \ "scriptaddr=0x80000000%pre%" \ "pxefile_addr_r=0x80100000%pre%" \ "bootm_size=0x10000000%pre%"

Então, para o problema que você está descrevendo, você deve reutilizar bootm_size = 0x10000000 para garantir que mantenhamos a árvore de dispositivos dentro dos primeiros 256MB, que será o kernel visible lowmem (com as configurações padrão do kernel hoje pelo menos, o tamanho do kernel lowmem é configurável).

Outra solução igualmente útil aqui é simplesmente colocar a árvore de dispositivos e o ramdisk na memória onde você sabe que eles estarão seguros e usar fdt_high = 0xffffffff e initrd_high = 0xffffffff para desabilitar a realocação. O principal uso da relocação é certificar-se de que as coisas estarão seguras no caso genérico (onde o U-Boot pode receber um kernel e uma árvore de dispositivos aleatórios e um ramdisk e simplesmente não saber o tamanho de tudo). Em um caso de produção como esse, você pode descobrir alguns valores sempre seguros e corretos, carregá-los e não movê-los em outro momento.

    
por 26.01.2016 / 15:57