本文基于ubuntu,以目标arm64为例,搭建交叉编译环境,并对linux4.19.186内核源码进行交叉编译。
所谓的交叉编译是:编译环境的平台与编译成果所要运行的平台,不是一类平台。通常指X86平台下编译的成果,提供给arm下要运行的程序或内核。因此需要交叉编译工具链来解决平台差异化问题 。
1、下载交叉编译工具链
工具链官方路径:
http://releases.linaro.org/components/toolchain/binaries/
也可以到国内源网站下载更快:
https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain
arm64用的工具链是包含aarch64关键字,选择最新版本下载并解压:
wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
tar -xvf gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz
对于交叉编译工具链,做一些如下补充说明:
1、通常不同内核版本对编译工具版本有最低要求,可以查看Documentation/Changes文档有描述,如下对于4.19.186内核的编译工具最低版本为V4.6。
2、GCC 的命名规则为: arch [-vendor] [-os] [-(gnu)eabi]-gcc
比如 arm-linux-gnueabi-gcc ,arm-none-eabi-gcc, aarch64-linux-gnu-gcc
• 带 [] 的是可选部分。
• arch: 芯片架构,比如 32 位的 Arm 架构对应的 arch 为 arm,64 位的 Arm 架构对应的 arch 为 aarch64。
• vendor :工具链提供商,大部分工具链名字里面都没有包含这部分。
• os :编译出来的可执行文件(目标文件)针对的操作系统,比如 Linux。
arm-none-eabi-gcc 一般适用用于 Arm Cortex-M/Cortex-R 平台,它使用的是 newlib 库。
arm-linux-gnueabi-gcc 和 aarch64-linux-gnu-gcc 适用于 Arm Cortex-A 系列芯片,前者针对 32 位芯片,后者针对 64 位芯片,它使用的是 glibc 库。可以用来编译 u-boot、linux kernel 以及应用程序。
另外需要补充一点的是,32 位的 Arm 和 64 位的 Arm,它们的指令集是不同的,所以需要使用不同的工具链编译。
2、下载linux源码
到linux官网:https://cdn.kernel.org
下载源码:4.19.186,并解压
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.186.tar.xz
tar -xvf linux-4.19.186.tar.xz
1、随便创建一个路径来存放工具链:/usr/bin/toolchain,整个目录拷贝到路径下:
root@ubuntu:/home/ldy/# mkdir /usr/bin/toolchain
root@ubuntu:/home/ldy# cp gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu /usr/bin/toolchain/ -rf
2、设置环境变量,加入工具链存放的路径
root@ubuntu:/home/ldy# export PATH=$PATH:/usr/bin/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/
root@ubuntu:/home/ldy# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/:/usr/bin/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/
做make交叉编译时候需要指定平台架构和编译工具:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
如果不加参数,可以直接修改顶层Makefile里变量
ARCH ?= arm64
CROSS_COMPILE ?= aarch64-linux-gnu-
1、配置.config
配置.config有两种方法:
root@ubuntu:/home/ldy/linux-4.19.186# cd arch/arm64/configs/
root@ubuntu:/home/ldy/linux-4.19.186/arch/arm64/configs# ls
defconfig
2、编译
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4
-j4 表示4个cpu核心同时编译,加快编译速度。
如上默认生成Image,如果要编译生成对应target镜像文件,如uImage,可以在后面加上uImage.
查看源码该架构(arm64)下支持哪些target镜像,可以采用help查看。
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- help |grep image -i
没有对应uImage、bzImage等的target,只有Image 和Image.gz, 因此默认生成Image内核镜像文件。
从该源码的arch/arm64/MakefileMakefile下,也是可以查看支持哪些target的。
补充:几种内核镜像文件关系
vmlinux: 编译出来的最原始的内核文件,未压缩。
zImage: bzImage 是vmlinux经过gzip压缩后的文件(内核比较小采用zimage 大内核采用bzimage)。
uImage: U-boot专用的映像文件,在zImage之前加上一个长度为0x40的tag(文件的类型、加载位置、生成时间、大小等信息)
1、如果是本机安装内核的话,在编译后直接执行:
make modules_install #安装模块
make install #安装内核
2、 但由于是交叉环境,需要将编译的成果物安装到arm64系统机上。
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install
拷贝/lib/modules/ 到目标系统的/lib/modules/下
拷贝 arch/ arm64/boot/zImage 到目标系统/boot下
拷贝System.map 到目标系统/boot下
(可以参考arch/arm64/boot/install.sh安装脚本)
1、make menuconfig时遇到的报错
scripts/Makefile.lib:196: recipe for target ‘scripts/kconfig/zconf.tab.c’ failed
解决方法:
安装如下两软件
2、编译报错
scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: No such file or directory
解决方法: