4

Problem: Memory Allocation Problem

my platform:

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

I've created my rootfs one time by following this guide and configured it by myself to compile it as FDPIC ELF (an elf that is position independent for mmu-less platforms such as arm_cortex-m family) and the other time I built it using buildroot (the toolchain and rootfs and kernel).

But it didn't work. my kernel cannot execute any file even the init file I mean /linuxrc or /sbin/init that are in my rootfs (I know they are symlinks to the busybox's binary). As I mentioned in the first paragraph, I tried different executable formats (I mean FDPIC ELF and BFLT (flat binary)) but none of them worked and kernel throws the errno -12 error that means not enough memory.

this is my kernel log with log_level of 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). ]---

Log with debug level 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). ]---


UPDATE: I managed to debug the kernel using GDB + OpenOCD, and I found out the error is in binfmt_flat.c file line: 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;
        }

I think the problem is happening in the vm_mmap function (textpos = vm_mmap(NULL, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);)

the link to vm_mmap function in the linux source tree

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);
}
  • (Just a guess) You need enough free memory all in one place (well one place for text, one for rss, one for … etc.) With no MMU there can be no un-fragmenting of RAM pages. – ctrl-alt-delor Oct 13 at 21:46
  • @ctrl-alt-delor thanks for helping! but I saw that some engineers, run multiple programs on uClinux with 4MB ram. but my ram is 8MB. and if you look at my boot log, you can see that more 5MBytes of Ram is free! so, it should easily run these light-weight executables. Can a wrong kernel kconfig configuration cause this? – Mahyar Shokraeian Oct 14 at 3:32
  • Sorry I only have tips, I have not done this in years. – ctrl-alt-delor Oct 14 at 9:27
  • Is this on bare metal? – rfmodulator Oct 24 at 0:02
  • @rfmodulator hmm... what do you mean? let me make it clear. I've booted linux on a microcontroller. before booting linux it was a bare-metal platform. but when we have linux on it, it's not bare-metal anymore because we have operating system on it – Mahyar Shokraeian Oct 24 at 9:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.