Linux는 U-Boot 재배치된 FDT(highmem에서)에 액세스할 수 없습니다.

Linux는 U-Boot 재배치된 FDT(highmem에서)에 액세스할 수 없습니다.

우리는 ARM 기반 임베디드 시스템에서 U-Boot의 맞춤형 버전을 실행하고 있으며 장치 트리 Blob과 함께 Linux 4.3을 로드하려고 합니다. 시스템에는 1GB RAM이 제공되며, 그 중 상위 128MB는 영구 저장용으로 예약되어 있습니다. 저는 tftp를 사용하여 커널과 DTB를 일부 메모리 위치(커널: 0x02000000, DTB: 0x02400000)에 복사했으며 이제 initramfs를 무시하고 싶습니다. 그래서 전화했어요 bootm 0x2000000 - 0x2400000.

DTB는 사용 가능한 U-Boot 메모리의 맨 끝인 0x37b60000(가상: 0xf7b60000)으로 재배치됩니다. Linux가 주소에 접근할 수 없기 때문에 부팅할 수 없습니다. 이것은 highmem/lowmem에 문제가 있는 것 같습니다. 이해할 수 없습니다. lowmem은 760MB(가상 0xef800000)로 끝납니다. highmem은 필요할 때 동적으로 매핑되어야 하지 않나요? (CONFIG_HIGHMEM이 설정되었습니다.)

이 문제를 해결하는 깨끗하고 올바른 방법은 무엇입니까? U-Boot가 낮은 위치를 사용하도록 하거나(어떻게?) 높은 메모리에 액세스할 수 있도록 Linux 구성을 변경합니까(어떻게?)?

참고: Linux는 재배치가 억제되므로 fdt_high=0xffffffff(및 initrd_high=0xffffffff)를 사용하여 정상적으로 부팅할 수 있습니다.

디버깅 정보가 포함된 U-Boot:

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

답변1

따라서 이 문제를 해결하는 한 가지 방법은 몇 가지 추가 환경 변수를 사용하는 것입니다. include/configs/ti_armv7_common.h를 보면 다음과 같은 내용이 있습니다.

/*
 * 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\0" \
        "kernel_addr_r=0x82000000\0" \
        "fdtaddr=0x88000000\0" \
        "fdt_addr_r=0x88000000\0" \
        "rdaddr=0x88080000\0" \
        "ramdisk_addr_r=0x88080000\0" \
        "scriptaddr=0x80000000\0" \
        "pxefile_addr_r=0x80100000\0" \
        "bootm_size=0x10000000\0"

따라서 설명하는 문제의 경우 bootm_size=0x10000000을 재사용하여 커널 표시 lowmem이 될 첫 번째 256MB 내에서 장치 트리를 유지해야 합니다(적어도 현재의 기본 커널 설정에서는 커널 lowmem의 크기가 구성됨). ).

똑같이 유용한 또 다른 솔루션은 간단히 장치 트리와 램디스크를 메모리에 넣는 것입니다.알다그들은 안전하며 fdt_high=0xffffffff 및 initrd_high=0xffffffff를 사용하여 재배치를 비활성화합니다. 재배치의 주요 용도는 일반적인 상황에서 모든 것이 안전한지 확인하는 것입니다(U-Boot에 임의의 커널, 장치 트리 및 램디스크가 제공될 수 있고 모든 것이 얼마나 큰지 전혀 알 수 없는 경우). 이와 같은 생산 상황에서는 항상 안전하고 올바른 일부 값을 파악하여 다시 이동할 필요 없이 여기에 로드할 수 있습니다.

관련 정보