在Mac OS X上构建Linux内核

时间:2012-04-04 20:29:17

标签: linux macos kernel elf

我正在做一个修改Linux内核的项目。我有一台桌面Linux机器,我在构建内核方面没有问题。

但是,我要去旅行,我想继续前进。我只有一台MacBook。当我尝试构建Linux内核时,它抱怨elf.h was not found

我从互联网上下载了一个elf.h。现在它抱怨:NO ELF

我尝试从我的Linux桌面复制整个/usr/include,并将其设置为包含目录,但仍然会出现奇怪的错误,例如"u8" not declared

在Mac上进行内核开发的标准方法是什么?我有一台在同一台Mac上运行Linux的虚拟机,它将用于测试修改后的内核。但是,我真的不想在它上面构建内核,因为它有点慢。

6 个答案:

答案 0 :(得分:20)

首先,我同意使用Linux VM通常更简单。也就是说,如果您真的想要这样做,我已经使用以下过程成功编译了Linux内核代码。

在开始之前,您可能需要在Mac上的区分大小写的文件系统上安装Linux源代码树。 (默认的HFS文件系统不区分大小写。)我不会在这里讨论,但很多人这样做是为了编译Android源代码树,所以you can use Google to find instructions

首先,您需要以下文件在OS X盒上交叉编译内核(将它们从已知的Linux VM复制到本地/usr/include):

/usr/include/elf.h
/usr/include/features.h
/usr/include/bits/predefs.h
/usr/include/bits/wordsize.h
/usr/include/gnu/stubs.h
/usr/include/gnu/stubs-64.h

接下来,您需要malloc.h位于Linux系统的预期位置,所以:

sudo ln -s /usr/include/malloc/malloc.h /usr/include/malloc.h

最后,您需要担心系统上安装的编译器是否适合构建Linux内核。我已经使用这个程序为Android编译的内核,使用适当的交叉编译工具链,但我不确定你是否可以在OS X上使用默认的gcc编译器成功编译Linux内核(假设你有Xcode附带的一个...)


编辑:您可能还想按照上面评论中链接的错误指出“nmagerko”,以确保您拥有正确的依赖关系,以及GNU版本{{ 1}}。特别是:

sed

答案 1 :(得分:4)

这是一个常见的问题(好吧,通常是在Windows上构建,但答案是一样的。)

就是不要这样做。如果要正确构建任何东西,你将会遇到很多麻烦,这是不值得的。 正如您自己所说,使用虚拟机。它有点慢,但并不是那么多,至少建筑物能正常工作。

内核开发很难,不会引入额外的,不必要的问题。

答案 2 :(得分:3)

以下是Android 6.0 Marshmallow和OSX 10.10 Yosemite的更新。我使用这种方法完成了几个成功的交叉构建。唯一的限制是我只检查了完整的AOSP源。

我使用brew的libelf来获得一个很好的包托管精灵库。这将我们需要包含的精灵文件usr/local/opt/libelf/include/libelf/gelf.h

brew install libelf

但如果将符号链接到usr/local/include,这仍会在构建时抛出错误,因为显然缺少某些定义。所以我偷了<kernel_source>/arch/arm/include/asm/elf.h中缺少的定义并创建了一个shim include文件:

cat <<EOT >> /usr/local/include/elf.h
#include "../opt/libelf/include/libelf/gelf.h"
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6
#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
#define R_PPC_ADDR32 1 /* 32bit absolute address */
#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
#define R_SH_DIR32 1
#define R_SPARC_64 32 /* Direct 64 bit */
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_390_32 4 /* Direct 32 bit. */
#define R_390_64 22 /* Direct 64 bit. */
#define R_MIPS_64 18
EOT

这应该足以让构建完成。如果有人需要关于此的更多信息,我有一个post,它涵盖了OSX上完整的Android内核版本。

答案 3 :(得分:3)

使用AOSP的预编译

编译内核

我已经从linux主机上删除了OSX标题的符号链接,显然效果很好!在我的设置中,我已同步整个AOSP repo,其中包括所有prebuilts,但我实际用于构建内核的那些是:

克隆它们,以便以下目录树有效:

<SOME-PATH>/prebuilts/
<SOME-PATH>/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/
<SOME-PATH>/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8/

确保根据您的Android目标版本检出相应的分支/标记。

安装缺少的标题

不确定它是否是正确的方法,但在/usr/local/include中放入一堆linux标头可以解决所有问题。别忘了chmod +x剧本。

install_headers.sh:

#!/bin/sh

PREBUILTS_DIR="<SOME-PATH>/prebuilts" # fill in the path here!

PREBUILT_GCC=$PREBUILTS_DIR"/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8"
KERNEL_HEADERS=$PREBUILT_GCC"/sysroot/usr/include"
HOST_HEADERS="/usr/local/include"

function install_header() {
    header=$1
    ln -s $KERNEL_HEADERS/$header $HOST_HEADERS/$header
}

# create symlinks for the missing headers
install_header elf.h
install_header features.h
# the following are folders (that contain headers)
install_header bits
install_header gnu
install_header linux
install_header asm
install_header asm-generic

构建内核

export PATH=<SOME-PATH>/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8/bin:$PATH
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
# in this example it builds for N6
make shamu_defconfig
make -j8

瞧:

  

内核:arch / arm / boot / zImage-dtb准备就绪

我的配置

  • macOS Sierra 10.12.3
  • XCode:使用MacOSX10.11.sdk,允许在mac上构建AOSP
  • 目标设备:N6 / shamu
  • AOSP分支:Marshmallow(mac_version.mk更新build以允许使用10.12.3 sdk)

答案 4 :(得分:2)

这适用于kitkat(未尝试早期版本) - make -j8 ARCH=arm CROSS_COMPILE=arm-eabi- HOSTCFLAGS="-I ../external/elfutils/libelf"

这假设android构建的其余部分像往常一样设置,内核目录在android构建中。

答案 5 :(得分:0)

在OSX 10.15.4 Catalina上使用arm64内核进行的一个更新。

我的意图是在macOS上本地构建最新的(5.7)arm64内核,并在qemu-system-aarch64上播放它。 btw,从crosstool-ng构建的工具链。

1)首先按照上述步骤操作,以包含一些头文件。我把它们放在我的主文件夹下

$ ls〜/ usr / include / -l <​​/ p>

drwxr-xr-x 4 yupluo01 admin 128 5月4日16:47位

-rw-r--r-- 1 yupluo01 admin 177346 5月4日16:23 elf.h

-rw-r--r-- 1 yupluo01 admin 17079 5月4日16:23 features.h

drwxr-xr-x 4 yupluo01 admin 128 May 4 16:44 gnu

-rw-r--r-- 1 yupluo01 admin 6186 5月4日16:33 malloc.h

-rw-r--r-- 1 yupluo01 admin 2290 5月4日16:43 stdc-predef.h

2)第二,对主机uuid代码的一些破解,因为mac上的uuid_t类型与linux不同:scripts / mod / file2alias.c 通过一个宏BUILD_ON_LINUX删除uuid_t定义,并在do_tee_entry()中注释代码

3)make ARCH = arm64 HOSTCFLAGS =“ -I / usr / local / include -I〜/ usr / include -I / usr / local / opt / openssl / include / -L / usr / local / opt / openssl / lib / -DBUILD_ON_LINUX = 0“ CROSS_COMPILE = aarch64-unknown-linux-gnu- O = out_arm64 /