Linux 커널은 바이너리를 실행할 수 없습니다(오류 -12).

Linux 커널은 바이너리를 실행할 수 없습니다(오류 -12).

문제: 메모리 할당 문제

내 플랫폼:

SOC = STM32H743 (ARMv7E-M | Cortex-M7)
Board = Waveshare CoreH7XXI 
Linux Kernel = 5.8.10 (stable 2020-09-17)
initial defconfig file = stm32_defconfig
rootfs = built using busybox | busybox compiled using arm-linux-gnueabihf-gcc as FDPIC ELF

나는 다음을 통해 rootfs를 한 번 만들었습니다.이 가이드FDPIC ELF(arm_cortex-m 시리즈와 같은 mmu가 없는 플랫폼에 대한 위치 독립적 elf)로 컴파일하도록 직접 구성했고 또 다른 때는 buildroot(툴체인, rootfs 및 커널)를 사용하여 빌드했습니다.

그러나 그것은 작동하지 않았습니다. 내 커널은 어떤 파일도 실행할 수 없습니다. 심지어 내 rootfs의 /linuxrc 또는 /sbin/init에 있는 init 파일도 실행할 수 없습니다(비지박스 바이너리에 대한 심볼릭 링크라는 것을 알고 있습니다). 첫 번째 단락에서 언급했듯이, 다른 실행 가능 형식(FDPIC ELF 및 BFLT(플랫 바이너리)을 의미함)을 시도했지만 그 중 아무 것도 작동하지 않았고 커널에서 다음을 errno -12의미하는 오류가 발생했습니다.충분한 저장.

이것은 내 커널 로그입니다. log_level은 7입니다.

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.7.19 (root@Mahyar1284) (gcc version 9.3.0 (Buildroot 2020.08), GNU ld (GNU Binutils) 2.32) #3 PREEMPT Sun Oct 11 08:20:09 +0330 2020
[    0.000000] CPU: ARMv7-M [411fc271] revision 1 (ARMv7M), cr=00000000
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[    0.000000] OF: fdt: Machine model: Waveshare STM32H743i-Coreh7 board
[    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 1937
[    0.000000] Kernel command line: console=ttySTM0,115200n8 root=/dev/mmcblk0p2 rw rootwait loglevel=7 init=/linuxrc
[    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 5136K/7812K available (1517K kernel code, 142K rwdata, 556K rodata, 72K init, 114K bss, 2676K reserved, 0K cma-reserved)
       .
       .
       .
       .
[    0.866164] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    0.875365] devtmpfs: mounted
[    0.879076] Freeing unused kernel memory: 72K
[    0.883567] This architecture does not have kernel memory protection.
[    0.889882] Run /linuxrc as init process
[    0.902632] random: fast init done
[    0.911679] linuxrc: page allocation failure: order:8, mode:0xcc0(GFP_KERNEL), nodemask=(null)
[    0.922278] nommu: Allocation of length 675840 from process 1 (linuxrc) failed
[    0.929778] binfmt_flat: Unable to allocate RAM for process text/data, errno -12
[    0.937629] Kernel panic - not syncing: Requested init /linuxrc failed (error -12).
[    0.945187] ---[ end Kernel panic - not syncing: Requested init /linuxrc failed (error -12). ]---

로깅에 디버그 수준 17을 사용합니다.

[    1.019849] Run /linuxrc as init process
[    1.023842]   with arguments:
[    1.026661]     /linuxrc
[    1.029174]   with environment:
[    1.032436]     HOME=/
[    1.034646]     TERM=linux
[    1.052238] linuxrc: page allocation failure: order:8, mode:0xcc0(GFP_KERNEL), nodemask=(null)
[    1.060781] CPU: 0 PID: 1 Comm: linuxrc Not tainted 5.8.10 #41
[    1.066932] Hardware name: STM32 (Device Tree Support)
[    1.072346] [<d000b3fd>] (unwind_backtrace) from [<d000a527>] (show_stack+0xb/0xc)
[    1.079832] [<d000a527>] (show_stack) from [<d0056421>] (warn_alloc+0x63/0xe2)
[    1.087242] [<d0056421>] (warn_alloc) from [<d00567e9>] (__alloc_pages_nodemask+0x33b/0x55a)
[    1.095743] [<d00567e9>] (__alloc_pages_nodemask) from [<d0056a17>] (__get_free_pages+0xf/0x24)
[    2.108641] [<d0056a17>] (__get_free_pages) from [<d0056c9f>] (alloc_pages_exact+0x33/0x44)
[    2.117162] [<d0056c9f>] (alloc_pages_exact) from [<d0054025>] (do_mmap+0x46f/0x5aa)
[    2.124999] [<d0054025>] (do_mmap) from [<d004f47b>] (vm_mmap_pgoff+0x5d/0x86)
[    2.132321] [<d004f47b>] (vm_mmap_pgoff) from [<d008bbdb>] (load_flat_file+0x39b/0x5dc)
[    2.140215] [<d008bbdb>] (load_flat_file) from [<d008bfe9>] (load_flat_binary+0x49/0x2dc)
[    2.148593] [<d008bfe9>] (load_flat_binary) from [<d00614c1>] (__do_execve_file+0x439/0x584)
[    2.157129] [<d00614c1>] (__do_execve_file) from [<d0061b03>] (do_execve+0x17/0x1a)
[    2.164892] [<d0061b03>] (do_execve) from [<d0184965>] (kernel_init+0x41/0xa0)
[    2.172212] [<d0184965>] (kernel_init) from [<d00082ad>] (ret_from_fork+0x11/0x24)
[    2.179638] Exception stack(0xd0435fb0 to 0xd0435ff8)
[    2.184861] 5fa0:                                     00000000 00000000 00000000 00000000
[    2.193055] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    2.201091] 5fe0: 00000000 00000000 00000000 00000000 00000000 00000000
[    2.207831] Mem-Info:
[    2.210012] active_anon:0 inactive_anon:0 isolated_anon:0
[    2.210012]  active_file:6 inactive_file:11 isolated_file:0
[    2.210012]  unevictable:0 dirty:1 writeback:0
[    2.210012]  slab_reclaimable:26 slab_unreclaimable:339
[    2.210012]  mapped:0 shmem:0 pagetables:0 bounce:0
[    2.210012]  free:580 free_pcp:0 free_cma:0
[    2.239767] Node 0 active_anon:0kB inactive_anon:0kB active_file:24kB inactive_file:44kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:0kB dirty:4kB writeback:0kB shmem:0kB writeback_tmp:0kB all_unreclaimable? no
[    2.259994] Normal free:2320kB min:284kB low:352kB high:420kB reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB active_file:24kB inactive_file:44kB unevictable:0kB writepending:4kB present:7812kB managed:5188kB mlocked:0kB kernel_stack:200kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
[    2.287792] lowmem_reserve[]: 0 0
[    2.290982] Normal: 10*4kB (UM) 5*8kB (UM) 4*16kB (UM) 6*32kB (UM) 1*64kB (M) 3*128kB (UM) 2*256kB (M) 2*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 2320kB
[    2.304689] 17 total pagecache pages
[    2.308111] 1953 pages RAM
[    2.310798] 0 pages HighMem/MovableOnly
[    2.314765] 656 pages reserved
[    2.317682] nommu: Allocation of length 675840 from process 1 (linuxrc) failed
[    2.325066] active_anon:0 inactive_anon:0 isolated_anon:0
[    2.325066]  active_file:6 inactive_file:11 isolated_file:0
[    2.325066]  unevictable:0 dirty:1 writeback:0
[    2.325066]  slab_reclaimable:26 slab_unreclaimable:339
[    2.325066]  mapped:0 shmem:0 pagetables:0 bounce:0
[    2.325066]  free:580 free_pcp:0 free_cma:0
[    2.354738] Node 0 active_anon:0kB inactive_anon:0kB active_file:24kB inactive_file:44kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:0kB dirty:4kB writeback:0kB shmem:0kB writeback_tmp:0kB all_unreclaimable? no
[    2.374960] Normal free:2320kB min:284kB low:352kB high:420kB reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB active_file:24kB inactive_file:44kB unevictable:0kB writepending:4kB present:7812kB managed:5188kB mlocked:0kB kernel_stack:200kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
[    2.402754] lowmem_reserve[]: 0 0
[    2.405941] Normal: 10*4kB (UM) 5*8kB (UM) 4*16kB (UM) 6*32kB (UM) 1*64kB (M) 3*128kB (UM) 2*256kB (M) 2*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 2320kB
[    2.419639] 17 total pagecache pages
[    2.423247] binfmt_flat: Unable to allocate RAM for process text/data, errno -12
[    2.430708] Kernel panic - not syncing: Requested init /linuxrc failed (error -12).
[    2.438253] ---[ end Kernel panic - not syncing: Requested init /linuxrc failed (error -12). ]---


고쳐 쓰다: GDB + OpenOCD를 사용하여 커널을 디버깅했는데 binfmt_flat.c파일 라인 에서 오류를 발견했습니다 634. ::

pr_err("Unable to allocate RAM for process text/data, " "errno %d\n", ret);
        memp = realdatastart;
        memp_size = len;
    } else {

        len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(u32);
        len = PAGE_ALIGN(len);
        textpos = vm_mmap(NULL, 0, len,
            PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);

        if (!textpos || IS_ERR_VALUE(textpos)) {
            ret = textpos;
            if (!textpos)
                ret = -ENOMEM;
            pr_err("Unable to allocate RAM for process text/data, "
                   "errno %d\n", ret);
            goto err;
        }

textpos = vm_mmap(NULL, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);vm_mmap 함수( ) 에서 문제가 발생한 것 같습니다.

Linux 소스 트리의 vm_mmap 함수에 대한 링크

unsigned long vm_mmap(struct file *file, unsigned long addr,
    unsigned long len, unsigned long prot,
    unsigned long flag, unsigned long offset)
{
    if (unlikely(offset + PAGE_ALIGN(len) < offset))
        return -EINVAL;
    if (unlikely(offset_in_page(offset)))
        return -EINVAL;

    return vm_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
}

관련 정보