在MacOSX上构建Linux内核

在MacOSX上构建Linux内核,linux,macos,kernel,elf,Linux,Macos,Kernel,Elf,我正在做一个修改Linux内核的项目。我有一台桌面Linux机器,在上面构建内核没有问题 然而,我要去旅行,我想在路上工作。我只有一台MacBook。当我试图构建Linux内核时,它抱怨没有找到elf.h 我从网上下载了一个elf.h。现在它抱怨说:没有ELF 我试图从Linux桌面复制整个/usr/include,并将其设置为include目录,但仍然出现奇怪的错误,如“u8”未声明 在Mac上进行内核开发的标准方法是什么?我有一个在同一台Mac上运行Linux的虚拟机,它将用于测试修改后的内

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

然而,我要去旅行,我想在路上工作。我只有一台MacBook。当我试图构建Linux内核时,它抱怨没有找到
elf.h

我从网上下载了一个elf.h。现在它抱怨说:
没有ELF

我试图从Linux桌面复制整个
/usr/include
,并将其设置为include目录,但仍然出现奇怪的错误,如
“u8”未声明

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

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

不要这样做。要正确构建任何东西都会有很多困难,这是不值得的。 使用虚拟机,就像你自己说的那样。它稍微慢一点,但并没有那个么多,至少建筑会正常工作


内核开发在不引入额外的、不必要的问题的情况下已经足够困难了。

首先,我同意只使用Linux虚拟机通常更简单。也就是说,如果你真的想这么做,我已经使用下面的过程成功地编译了Linux内核代码

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

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

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

sudo ln -s /usr/include/malloc/malloc.h /usr/include/malloc.h
最后,您需要担心系统上安装的编译器是否适合构建Linux内核。我已经使用适当的交叉编译器工具链将此过程用于为Android编译的内核,但我不确定您是否能够在OS X上使用默认的
gcc
编译器成功编译Linux内核(假设您有Xcode附带的编译器…)


编辑:您可能还需要遵循上面“nmagerko”评论中链接的bug中指出的步骤,以确保您具有正确的依赖项,以及
sed的GNU版本
。特别是:

$ sudo port install libelf
$ sudo port install gsed
这在kitkat(没有尝试早期版本)起作用--
make-j8 ARCH=arm CROSS\u COMPILE=arm eabi-HOSTCFLAGS=“-I../external/elfutils/libelf”


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

这里是android 6.0棉花糖和OSX 10.10 Yosemite的更新。我已经使用这种方法成功地完成了几次交叉构建。唯一的限制是,我只在签出完整AOSP源代码的情况下执行这些操作

我使用brew的libelf获得了一个很好的包管理的elf库。这将获得需要包含的elf文件,
usr/local/opt/libelf/include/libelf/gelf.h

brew install libelf
但如果您将其符号链接到
usr/local/include
,这仍然会在构建时抛出错误,因为显然缺少一些定义。因此,我从
/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
cat/usr/local/include/elf.h
#包括“./opt/libelf/include/libelf/gelf.h”
#定义R_386_无0
#定义R_386_32 1
#定义R_386_PC32 2
#定义R_ARM_NONE 0
#定义R_ARM_PC24 1
#定义R_ARM_ABS32 2
#定义R\u MIPS\u无0
#定义R_MIPS_16 1
#定义R_MIPS_32 2
#定义R_MIPS_REL32 3
#定义R_MIPS_26 4
#定义R_MIPS_HI16 5
#定义R_MIPS_LO16 6
#定义R_IA64_IMM64 0x23/*符号+加数,mov IMM64*/
#定义R_PPC_ADDR32 1/*32位绝对地址*/
#定义R_PPC64_ADDR64 38/*双字64 S+A*/
#定义R_SH_DIR32 1
#定义R_SPARC_64 32/*直接64位*/
#定义R_X86_64_64 1/*直接64位*/
#定义R_390_32 4/*直接32位*/
#定义R_390_64 22/*直接64位*/
#定义R_MIPS_64 18
EOT
这应该足以让构建完成。如果有人需要这方面的更多信息,我有一个完整的基于OSX的Android内核版本。

使用AOSP的预构建编译内核 我已经将linux主机上丢失的OSX头做了符号链接,显然效果很好!在我的设置中,我同步了整个系统,其中包括所有系统,但我实际用于构建内核的系统是:

  • 缺少Linux标头:
  • 交叉编译器:
克隆它们,以便以下目录树有效:

<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/
构建内核
export PATH=/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8/bin:$PATH
导出ARCH=arm
导出子通道=arm
导出交叉编译=arm eabi-
#在本例中,它是为N6构建的
让沙姆·迪夫配置
make-j8
瞧 内核:arch/arm/boot/zImage dtb已就绪

我的配置
  • macOS Sierra 10.12.3
  • XCode:使用MacOSX10.11.sdk,它允许在mac上构建
    AOSP
  • 目标设备:N6/shamu
  • AOSP分支:棉花糖(在
    build
    中更新了
    mac_version.mk
    以允许使用10.12.3 sdk)

一次基于OSX 10.15.4 Catalina的arm64内核更新

我的意图是在macOS上原生构建最新(5.7)的arm64内核,并在qemu-system-aarch64上运行。顺便说一句,工具链由crosstool ng构建

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

$ls~/usr/include/-l

drwxr-xr-x 4 yupluo01管理128 May 4 16:47位

-rw-r--r--1 yupluo01管理员177346
<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/
#!/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