ARM64开发板启动停滞:__arm64_sys_ppoll定义与编译疑问
我正尝试使用busybox、u-boot和linux-5.10.0-rc5启动一款搭载ARM64核心的开发板,启动过程接近完成,但进入shell程序后很快停滞(无内核panic),甚至未显示'#'提示符;但在QEMU模拟器中,相同镜像和busybox可正常运行并最终进入shell。
通过跟踪代码(路径:arch/arm64/kernel/syscall.c 中的 do_el0_svc()->el0_svc_common->invoke_syscall->__invoke_syscall->syscall_fn)发现,停滞时内核正在处理编号为73的系统调用,该调用对应sys_ppoll(定义于include/uapi/asm-generic/unistd.h)。
在include/uapi/asm-generic/unistd.h中可见:
/* fs/select.c */ #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32 #define __NR_pselect6 72 __SC_COMP_3264(__NR_pselect6, sys_pselect6_time32, sys_pselect6, compat_sys_pselect6_time32) #define __NR_ppoll 73 __SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32) #endif
__SC_COMP_3264的定义位于同一文件开头,为验证#if/#endif宏编译的代码分支,我添加字符'x'触发编译错误,以此确认编译分支:
#ifndef __SYSCALL x <---- 编译报错,说明此段被编译,__SYSCALL(x,y)是否被定义为空? #define __SYSCALL(x, y) #endif #if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT) x <--------- 无编译报错,说明未被编译 #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32) #else #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64) #endif #ifdef __SYSCALL_COMPAT x <-------------- 无编译报错,说明未被编译 #define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp) #define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp) #else #define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys) #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) #endif
这似乎表明__SYSCALL(x,y)被定义为空,但其他系统调用可正常工作,因此我推断__SYSCALL已提前定义,最终在arch/arm64/kernel/sys.c中找到:
#undef __SYSCALL #define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *); #include <asm/unistd.h>
由此可知函数定义为__arm64_sys_ppoll,且可在System.map文件中查到,但我无法找到该函数的源代码定义,请问其位置在哪里?
另外,执行make -j28时,为何在如下代码块中添加'x'会触发编译错误?
#ifndef __SYSCALL x <---- 编译报错,说明此段被编译,__SYSCALL(x,y)是否被定义为空? #define __SYSCALL(x, y) #endif
顺带一提,我在源码中(排除非ARM64架构文件)搜索sys_ppoll的结果如下:
./include/linux/compat.h:asmlinkage long compat_sys_ppoll_time32(struct pollfd __user *ufds, ./include/linux/compat.h:asmlinkage long compat_sys_ppoll_time64(struct pollfd __user *ufds, ./include/linux/syscalls.h:asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, ./include/linux/syscalls.h:asmlinkage long sys_ppoll_time32(struct pollfd __user *, unsigned int, ./include/uapi/asm-generic/unistd.h:__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32) ./include/uapi/asm-generic/unistd.h:__SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) ./tools/include/uapi/asm-generic/unistd.h:__SC_COMP_3264(__NR_ppoll, sys_ppoll_time32, sys_ppoll, compat_sys_ppoll_time32) ./tools/include/uapi/asm-generic/unistd.h:__SC_COMP(__NR_ppoll_time64, sys_ppoll, compat_sys_ppoll_time64) ./arch/arm64/include/asm/unistd32.h:__SYSCALL(__NR_ppoll, compat_sys_ppoll_time32) ./arch/arm64/include/asm/unistd32.h:__SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64)
内容的提问来源于stack exchange,提问作者Chan Kim

