在 Mac OS X 上构建 Linux 内核

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10018764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:37:16  来源:igfitidea点击:

building Linux kernel on Mac OS X

linuxmacoskernelelf

提问by Alfred Zhong

I am doing a project to modify the Linux kernel. I have a desktop Linux machine and I have no problem building kernel on it.

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

However, I am going on a trip and I want to work on my way. I only have a MacBook. When I tried to build the Linux kernel, it complained that elf.h was not found.

但是,我要去旅行,我想在路上工作。我只有一台 MacBook。当我尝试构建 Linux 内核时,它抱怨elf.h was not found.

I download an elf.h from internet. Now it complains: NO ELF

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

I tried copying the entire /usr/includefrom my Linux desktop, and set it as the include directory, and still get strange errors like "u8" not declared

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

What is the standard way of doing kernel development on Mac? I have a virtual machine running Linux on the same Mac, and it will be used to test the modified kernel. However, I don't really want to build kernel on it, as it is kinda slow.

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

回答by Kristof Provost

This is a common question (well, usually it's building on Windows, but the answer is the same).

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

Just don't do it. You're going to have so much trouble getting anything to build correctly, it's just not worth it. Use a virtual machine, as you said yourself. It's a little slower, but not all that much, and at least building will work correctly.

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

Kernel development is hard enough without introducing additional, unnecessary problems.

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

回答by mpontillo

First, I agree that it's usually simpler to just use a Linux VM. That said, if you reallywant to do this, I have successfully compiled Linux kernel code using the procedure below.

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

Before you can even start, you may need to install the Linux source tree on a case-sensitive filesystem on your Mac. (the default HFS filesystem is case insensitive.) I won't cover that here, but a lot of people do this to compile the Android source tree, so you can use Google to find instructions.

在开始之前,您可能需要在 Mac 上区分大小写的文件系统上安装 Linux 源代码树。(默认的 HFS 文件系统不区分大小写。)我不会在这里介绍,但是很多人这样做是为了编译 Android 源代码树,因此您可以使用 Google 查找说明

First you'll need the following files to cross-compile a kernel on an OS X box (copy them from your known-working Linux VM to your local /usr/include):

首先,您需要以下文件在 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

Next you'll need malloc.hto be in the expected location for a Linux system, so do:

接下来,您需要malloc.h位于 Linux 系统的预期位置,因此请执行以下操作:

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

Finally, you'll need to worry about whether or not the compiler installed on your system is suitable for building the Linux kernel. I have used this procedure for kernels compiled for Android, using an appropriate cross-compiler toolchain, but I'm not sure if you can successfully compile a Linux kernel with the default gcccompiler on OS X (assuming you have the one that comes with Xcode...)

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



EDIT: You may also want to follow the steps pointed out in the bug linked in the comment above from "nmagerko", to ensure you have the correct dependencies, and the GNU version of sed. In particular:

编辑:您可能还希望按照上面“nmagerko”评论中链接的错误中指出的步骤操作,以确保您拥有正确的依赖项,以及sed. 特别是:

$ sudo port install libelf
$ sudo port install gsed

回答by Naseer

This works as of kitkat (didn't try earlier versions) - make -j8 ARCH=arm CROSS_COMPILE=arm-eabi- HOSTCFLAGS="-I ../external/elfutils/libelf"

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

This assumes the rest of the android build is set up as usual and the kernel directory is in the android build.

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

回答by 3martini

Here is an update for Android 6.0 Marshmallow and OSX 10.10 Yosemite. I have done several successful cross builds using this method. The only limitation is that I have only done these with the full AOSP source checked out.

这是 Android 6.0 Marshmallow 和 OSX 10.10 Yosemite 的更新。我已经使用这种方法完成了几次成功的交叉构建。唯一的限制是我只在签出完整的 AOSP 源的情况下完成了这些操作。

I used brew's libelf to get a nice package managed elf library. This gets us the elf file we need to include, usr/local/opt/libelf/include/libelf/gelf.h

我使用 brew 的 libelf 来获得一个不错的包管理精灵库。这为我们提供了需要包含的 elf 文件,usr/local/opt/libelf/include/libelf/gelf.h

brew install libelf

But this will still throw errors on build if you symlink it to usr/local/includeas apparently some definitions are missing. So I stole the missing definitions from <kernel_source>/arch/arm/include/asm/elf.hand created a shim include file:

但是,如果您将其符号链接到usr/local/include,这仍然会在构建时引发错误,因为显然缺少某些定义。因此,我从其中窃取了缺失的定义<kernel_source>/arch/arm/include/asm/elf.h并创建了一个 shim 包含文件:

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

That should be enough to get the build to complete. If anyone needs further information on this, I have a postthat covers a full Android kernel build on OSX.

这应该足以完成构建。如果有人需要这方面的更多信息,我有一篇文章介绍了在 OSX 上构建的完整 Android 内核。

回答by Paschalis

Compile Kernel using AOSP's prebuilts

使用 AOSP 的预构建编译内核

I've made symlinks to the missing OSX headers from the linux host ones and apparently it worked out well! In my setup I have sync'd the whole AOSP repo, which includes all prebuilts, but the ones that I am actually using to built the kernel are:

我已经创建了来自 linux 主机的缺失 OSX 头文件的符号链接,显然它运行良好!在我的设置中,我已经同步了整个AOSP repo,其中包括所有prebuilts,但我实际用来构建内核的那些是:

Clone them so that the following directory tree is valid:

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

<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/

Make sure you checkout the appropriate branch/tag, according to your Android target version.

确保根据您的 Android 目标版本签出适当的分支/标签。

Install the missing headers

安装缺少的头文件

Not sure if it's the proper way to do it, but putting the a bunch of linux headers in /usr/local/includeresolves all issues. Don't forget to chmod +xthe script.

不确定这是否是正确的方法,但是放入一堆 linux 头文件/usr/local/include可以解决所有问题。不要忘记chmod +x脚本。

install_headers.sh:

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=
    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

Build the kernel

构建内核

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

Voila:

瞧:

Kernel: arch/arm/boot/zImage-dtb is ready

内核:arch/arm/boot/zImage-dtb 准备好了

My configuration

我的配置

  • macOS Sierra 10.12.3
  • XCode: using MacOSX10.11.sdk, which allows building AOSPon mac
  • Target device: N6/shamu
  • AOSP branch: Marshmallow (updated mac_version.mkin buildto allow using 10.12.3 sdk)
  • macOS Sierra 10.12.3
  • XCode:使用 MacOSX10.11.sdk,允许AOSP在 mac 上构建
  • 目标设备:N6/shamu
  • AOSP分支:棉花糖(更新mac_version.mkbuild允许使用10.12.3 SDK)

回答by Yuping Luo

one update with arm64 kernel build on OSX 10.15.4 Catalina .

在 OSX 10.15.4 Catalina 上构建 arm64 内核的一项更新。

My intention is to natively build latest(5.7) arm64 kernel on macOS, and play it on qemu-system-aarch64 . btw, toolchain built from crosstool-ng.

我的目的是在 macOS 上本地构建最新的 (5.7) arm64 内核,并在 qemu-system-aarch64 上播放。顺便说一句,从 crosstool-ng 构建的工具链。

1) Firstly follow above steps, to include some header files. I put them under my home folder

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

$ ls ~/usr/include/ -l

$ ls ~/usr/include/ -l

drwxr-xr-x 4 yupluo01 admin 128 May 4 16:47 bits

drwxr-xr-x 4 yupluo01 admin 128 May 4 16:47 bits

-rw-r--r-- 1 yupluo01 admin 177346 May 4 16:23 elf.h

-rw-r--r-- 1 yupluo01 admin 177346 May 4 16:23 elf.h

-rw-r--r-- 1 yupluo01 admin 17079 May 4 16:23 features.h

-rw-r--r-- 1 yupluo01 admin 17079 May 4 16:23 features.h

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

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

-rw-r--r-- 1 yupluo01 admin 6186 May 4 16:33 malloc.h

-rw-r--r-- 1 yupluo01 admin 6186 May 4 16:33 malloc.h

-rw-r--r-- 1 yupluo01 admin 2290 May 4 16:43 stdc-predef.h

-rw-r--r-- 1 yupluo01 admin 2290 May 4 16:43 stdc-predef.h

2) second, some hack for host uuid code ,as the uuid_t type on mac is different as linux : scripts/mod/file2alias.c Remove uuid_t definition by one macro BUILD_ON_LINUX, and comment code in do_tee_entry()

2)第二,主机uuid代码的一些hack,因为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/

3)使 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/