问题:内存分配问题
我的平台:
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(对于无 mmu 平台(如 arm_cortex-m 系列)而言位置独立的 elf),另一次我使用 buildroot(工具链、rootfs 和内核)构建它。
但这没有用。我的内核无法执行任何文件,甚至是我的 rootfs 中的 /linuxrc 或 /sbin/init 的 init 文件(我知道它们是 busybox 二进制文件的符号链接)。正如我在第一段中提到的,我尝试了不同的可执行格式(我的意思是 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;
}
我认为问题发生在 vm_mmap 函数 ( textpos = vm_mmap(NULL, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
)
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);
}