前言

在内核编译时总会遇到一些奇奇怪怪的问题, 这里是对这些问题的解决的汇总

gcc 版本问题

高版本gcc编译低版本总会有一堆error, 可采用多版本gcc共存的方案, 详见Linux环境多版本编译器(gcc)共存, 再用低版本gcc进行编译即可

也可以用于解决编译时错误fatal error: linux/compiler-gcc7.h: No such file or directory

遇到的问题

  1. 编译遇到错误.size expression for copy_user_generic_c does not evaluate to a constant, 可修改arch/x86_64/lib/copy_user.S中的END(copy_user_generic_c) 更改为 END(copy_user_generic_string), 目的是与上边的 ENTRY(()copy_user_generic_string)保持相同变量, 解决方案来自https://stackoverflow.com/questions/23194840/linux-2-6-24-kernel-compilation-error-size-expression-for-copy-user-generic-c-d

  2. 编译遇到如下问题

    error:Makefile:416: *** mixed implicit and normal rules. stop
    error:Makefile:1449: *** mixed implicit and normal rules. stop

    原因及解决方法:make版本过高, 需要修改错误信息中的Makefile指定416、1449行内容

    • 416:config %config: scripts_basic outputmakefile FORCE 改为:%config: scripts_basic outputmakefile FORCE
    • 1449:/ %/: prepare scripts FORCE 改为:%/: prepare scripts FORCE​​​​​​​
  3. 编译遇到如下错误

    kernel/built-in.o: In function `mutex_lock':
    (.sched.text+0x11cf): undefined reference to `__mutex_lock_slowpath'
    kernel/built-in.o: In function `mutex_unlock':
    (.sched.text+0x11de): undefined reference to `__mutex_unlock_slowpath'
    Makefile:715: recipe for target '.tmp_vmlinux1' failed
    make: *** [.tmp_vmlinux1] Error 1

    解决方案: 在kernel/mutex.c文件中对四个位置进行修改,
    将三处static void fastcall noinline __sched修改为static __attribute__ ((used)) void fastcall noinline __sched

    static fastcall noinline void改为static __attribute__ ((used)) void fastcall noinline __sched

  4. 如果出现以下信息导致编译错误,可能是由于 make 版本过高的缘故,如果你是用 Ubuntu18 进行编译,不妨试试 Ubuntu16 或降低 make 版本, make 工具降版本

    make[2]: *** No rule to make target 'net/netfilter/xt_TCPMSS.o', needed by 'net/netfilter/built-in.o'.  Stop.
    scripts/Makefile.build:573: recipe for target 'net/netfilter' failed
    make[1]: *** [net/netfilter] Error 2
    make[1]: *** Waiting for unfinished jobs....
  5. 如果出现以下信息到启动错误,是因为 vmlinux 是 ELF 文件格式,这时用 bzImage 启动虚拟机就可以了

    qemu: linux kernel too old to load a ram disk
  6. 如果编译内核时出现 cc1: error: code model kernel does not support PIC mode 错误

    查找 Makefile 文件中的 KBUILD_CFLAGS, 在尾部添加 -fno-pie 即可,以 linux-4.7 版本源码 Makefile 为例,如图

    20200821185911

  7. 如果编译内核时出现错误make[2]: *** No rule to make target 'net/netfilter/xt_TCPMSS.o', needed by 'net/netfilter/built-in.o'. Stop, 原因可能是你所用的文件系统不区分大小写, 在 net/netfilter 文件夹下应该有两个文件xt_TCPMSS.cxt_tcpmss.c, 但你会发现实际上只有xt_tcpmss.c, 就是不区分大小写所致