前言

由于笔者的日常工作都是基于MacOs的笔记本,日常的工作总需要切换跳转机到aarch64的机器上编译内核,因此想在本地修改直接本地交叉编译,也踩了不少坑。目前看网上也没有相关的踩坑的资料,这里仅以记录,希望对各位有帮助

安装交叉编译工具

直接使用github上一个同学做好的工具:

brew tap messense/macos-cross-toolchains
# install x86_64-unknown-linux-gnu toolchain
brew install x86_64-unknown-linux-gnu
# install aarch64-unknown-linux-gnu toolchain
brew install aarch64-unknown-linux-gnu

安装gcc

brew install gcc cpp
#修改默认gcc连接到gcc
cat ~/.zprofile
alias gcc="gcc-11"
alias g++="g++-11"
alias c++="c++-11"

编译内核

git clone https://github.com/torvalds/linux.git

#生成.config
make defconfig ARCH=arm64 cross_compile=aarch64-unknown-linux-gnu-

#编译内核
make Image ARCH=arm64 cross_compile=aarch64-unknown-linux-gnu- -j8

踩坑实录


问题一: ld: unknown option: --version

diff --git a/init/Kconfig b/init/Kconfig
index 5a0251b5f..90698ffe6 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -35,7 +35,7 @@ config GCC_VERSION
 
 config LD_VERSION
        int
-       default $(shell,$(LD) --version | $(srctree)/scripts/ld-version.sh)
+       default 13
 
 config CC_IS_CLANG
        def_bool $(success,echo "$(CC_VERSION_TEXT)" | grep -q clang)
diff --git a/scripts/lld-version.sh b/scripts/lld-version.sh
index d70edb4d8..f8b2954f4 100755
--- a/scripts/lld-version.sh
+++ b/scripts/lld-version.sh
@@ -6,7 +6,7 @@
 # Print the linker version of `ld.lld' in a 5 or 6-digit form
 # such as `100001' for ld.lld 10.0.1 etc.
 
-linker_string="$($* --version)"
+linker_string="$($* -v)"
 
 if ! ( echo $linker_string | grep -q LLD ); then
        echo 0


问题二: scripts/sorttable.c:27:10: fatal error: ‘elf.h’ file not found
在内核目录下建立一个目录:macos,将编译器sysroot目录下的相关头文件拷贝到macos目录中,主要拷贝以下文件,并保持目录级数相同:

cp sysroot/usr/include/asm-generic/bitsperlong.h asm-generic 
cp sysroot/usr/include/asm/bitsperlong.h asm
cp sysroot/usr/include/asm-generic/int-ll64.h asm-generic 
cp sysroot/usr/include/asm-generic/types.h asm-generic 
cp sysroot/usr/include/asm/types.h asm
cp sysroot/usr/include/asm/posix_types.h ./asm
cp sysroot/usr/include/asm-generic/posix_types.h ./asm-generic 
cp sysroot/usr/include/linux/elf-em.h ./linux/elf-em.h
cp sysroot/usr/include/elf.h .
cp sysroot/usr/include/features.h . 
cp sysroot/usr/include/stdc-predef.h .
cp sysroot/usr/include/gnu/stubs.h gnu/ 

freejared@B-T2HTMD6R-1928 include % ls
asm             asm-generic     elf.h           features.h      gnu             linux           stdc-predef.h

#编译指定路径 -I/macos
make Image ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- HOSTCFLAGS="-I/macos"

问题三: scripts/extract-cert.c:21:10: fatal error: ‘openssl/bio.h’ file not found

#安装openssl
brew install openssl

#指定头文件路径 -I/usr/local/Cellar/openssl@3/3.0.3/include
make Image ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- HOSTCFLAGS="-I/macos -I/usr/local/Cellar/openssl@3/3.0.3/include"

问题四:ld: library not found for -lcrypto

#指定库路径 -L/usr/local/opt/openssl/lib
make Image ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- HOSTCFLAGS="-I/macos -I/usr/local/Cellar/openssl@3/3.0.3/include -L/usr/local/opt/openssl/lib"

问题五:error: member reference base type ‘typeof (((struct tee_client_device_id )0)->uuid)’ (aka ‘unsigned char [16]’) is not a structure or union uuid.b[15])

从错误提示上看,是由于macOS环境已经定义了uuid_t从而引发了重复定义的错误

修改uuid的定义方式:

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 2417dd1dee33..3477058781a3 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -42,9 +42,15 @@ typedef struct {
 typedef struct {
        __u8 b[16];
 } uuid_le;
+
 typedef struct {
        __u8 b[16];
-} uuid_t;
+} compat_uuid_t;
+
+#ifdef __APPLE__
+#define uuid_t compat_uuid_t
+#endif
+
 #define        UUID_STRING_LEN         36

最终编译命令

make Image ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- HOSTCFLAGS="-I/macos -I/usr/local/Cellar/openssl@3/3.0.3/include -L/usr/local/opt/openssl/lib" -j8

部分参考了Philon同学的经验:https://ixx.life/notes/cross-compile-linux-on-macos/

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐