【问题标题】:Error when compiling Linux kernel 3.2 for ARM为 ARM 编译 Linux 内核 3.2 时出错
【发布时间】:2016-07-09 23:51:36
【问题描述】:

我正在按照本教程为 ARM 编译 Linux 内核 3.2 并使用 QEMU 进行仿真:

https://balau82.wordpress.com/2012/03/31/compile-linux-kernel-3-2-for-arm-and-emulate-with-qemu/

我正在执行以下步骤:

  1. wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.tar.bz2
  2. tar xjf linux-3.2.tar.bz2
  3. export ARCH=arm
  4. export CROSS_COMPILE=arm-linux-gnueabi-
  5. cd linux-3.2
  6. make vexpress_defconfig
  7. make all
  8. cd ..
  9. arm-linux-gnueabi-gcc -static init.c -o init
  10. echo init|cpio -o --format=newc > initramfs
  11. qemu-system-arm -M vexpress-a9 -kernel linux-3.2/arch/arm/boot/zImage -initrd initramfs -serial stdio -append "console=tty1"

我的问题是当我尝试第 7 步(全部制作)时,会出现此问题:

include/linux/compiler-gcc.h:94:30: fatal error: linux/compiler-gcc5.h: No such file or directory
compilation terminated.
/home/ramy/QEMU_Learn/kernel/linux-3.2/./Kbuild:35: recipe for target 'kernel/bounds.s' failed
make[1]: *** [kernel/bounds.s] Error 1
Makefile:985: recipe for target 'prepare0' failed

我正在使用 Ubuntu 操作系统,我正在使用 Linaro 工具链编译内核。

我还检查了 PATH 变量,结果如下:

$ printenv | grep PATH

XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
DEFAULTS_PATH=/usr/share/gconf/ubuntu.default.path
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/ramy/gcc-arm-none-eabi-5_3-2016q1/bin
MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path

【问题讨论】:

  • 你的交叉编译器是什么?你的 linaro 版本是什么?链接balau82.wordpress.com/2012/03/31/… 的帖子来自 2012 年,因此使用 2012 年的 linaro 编译 3.2 内核,而不是更新的内核。您的 linaro 中的 gcc 版本太新,无法编译这么旧的 linux 内核。或者尝试更新的内核(但是这个旧博客中的命令可能不起作用)
  • Linux 内核版本 3.2 在 gcc 版本 5 存在之前发布。内核版本 3.2.81 有这个头文件。
  • 谢谢,但是如何在 Ubuntu 中使用 gcc-4 获取 Linaro?

标签: linux gcc linux-kernel qemu


【解决方案1】:

您的内核版本 (3.2.0) 太旧且与使用的 gcc (gcc-5) 不兼容。您可以使用 gcc-4 编译内核,或者使用更新的内核版本。

您的内核在linux/compiler-gcc.h 标头中有特殊的包含 http://lxr.free-electrons.com/source/include/linux/compiler-gcc.h?v=3.2#L91

 91 #define __gcc_header(x) #x
 92 #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
 93 #define gcc_header(x) _gcc_header(x)
 94 #include gcc_header(__GNUC__)

它将包含针对不同 gcc 版本的不同文件(GNUC 是 gcc 的主要版本)。它支持 gcc-3 和 gcc-4,但不支持 gcc-5:

http://lxr.free-electrons.com/source/include/linux/?v=3.2

C file  compiler-gcc.h  3705 bytes
C file  compiler-gcc3.h 631 bytes
C file  compiler-gcc4.h 2073 bytes
C file  compiler-intel.h    746 bytes
C file  compiler.h  8628 bytes

您可以尝试将compiler-gcc4.h 重写为compiler-gcc5.h,但您应该了解如何执行此操作。不能只是把 gcc4 复制到 gcc5,会有错误的宏。

compiler-gcc5.h 仅添加到 linux 内核版本 3.18:http://lxr.free-electrons.com/source/include/linux/compiler-gcc5.h?v=3.18(不在 3.17 中 http://lxr.free-electrons.com/source/include/linux/compiler-gcc5.h?v=3.17

旧的 linaro 编译器(在 gcc-5 之前)是 https://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/

根据 JJ Hakala 的评论,3.2.* 内核的最新版本中有 compiler-gcc5 头文件,即 3.2.81:https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.2.81.tar.gz - 只需将 wget 命令和 tar xjf 更改为此版本并重试即可。

【讨论】:

  • 谢谢。你知道如何在 Ubuntu 中使用 gcc-4 获取 Linaro 吗?
  • Ramy,JJHakala 说 3.2.81 内核有头文件;试试看(将 wget 命令地址更改为kernel.org/pub/linux/kernel/v3.0/linux-3.2.81.tar.gz)。 gcc-5 之前的 Linaro 是 4.9-2016.02 releases.linaro.org/components/toolchain/binaries/4.9-2016.02
  • 我更喜欢使用旧内核,因为我需要遵循旧帖子中的命令,我担心某些命令可能不适用于新内核
  • Ramy,这个 3.2.81 是同一个旧内核,有几个修复/错误向后移植。只需更新脚本中的次要版本。
  • 感谢osgx,我做到了,但是在构建新内核时遇到了一些麻烦。最好在新问题中发布错误,对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多