1.概要
2.内容
1.makefile分享
#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
obj-m += helloworld.o #此处要和你的驱动源文件同名
KDIR :=/home/topeet/linuxsdk/linux_sdk/kernel #这里是你的内核目录
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules #make操作
clean:
make -C $(KDIR) M=$(PWD) clean #make clean操作
这是一个用于编译Linux内核模块的Makefile脚本。这个脚本主要设置了几个环境变量和Makefile目标,用于在特定的交叉编译环境下编译和清理内核模块。下面是对脚本各部分的详细解释:
- 设置环境变量:
export ARCH=arm64
:设置目标架构为ARM64。export CROSS_COMPILE=aarch64-none-linux-gnu-
:设置交叉编译工具链前缀。这意味着编译器、链接器等工具都将使用以aarch64-none-linux-gnu-
开头的名称,如aarch64-none-linux-gnu-gcc
。
- Makefile变量:
obj-m += helloworld.o
:这行代码告诉Makefile要编译的目标模块文件。这里指定了模块名为helloworld.o
,你需要确保当前目录下有一个名为helloworld.c
的源文件。KDIR := /home/topeet/linuxsdk/linux_sdk/kernel
:设置内核目录(KDIR
),这里指向你存放Linux内核源代码的目录。PWD ?= $(shell pwd)
:获取当前目录的路径。如果未设置PWD
环境变量,则使用shell pwd
命令获取。
- Makefile目标:
-
all
:这是一个默认目标,执行时会调用make命令,使用指定的内核目录(KDIR
)和当前目录(M=$(PWD)
)来编译模块。make -C $(KDIR) M=$(PWD) modules
这条命令会在内核源代码目录中执行make,同时传递当前目录作为模块目录,指示make编译所有在该目录下定义的模块。
-
clean
:这个目标用于清理编译生成的文件。make -C $(KDIR) M=$(PWD) clean
这条命令同样在内核源代码目录中执行make,但传递的是clean指令,用于删除在当前目录下生成的所有编译产物。
-
使用说明:
- 确保你的工作目录中有一个名为
helloworld.c
的文件,该文件应包含Linux内核模块的源代码。 - 确保你的系统中安装了名为
aarch64-none-linux-gnu-gcc
等交叉编译工具。 - 运行
make
命令来编译模块。 - 运行
make clean
命令来清理编译生成的文件。
通过这个脚本,你可以方便地在交叉编译环境下编译和清理Linux内核模块。
2.“export CROSS_COMPILE=aarch64-none-linux-gnu-”如果不设置交叉编译工具链前缀,会怎样
如果不设置交叉编译工具链前缀,即不执行 export CROSS_COMPILE=aarch64-none-linux-gnu-
这行代码,那么编译过程将默认使用当前系统上的本地编译器来构建目标模块或程序。
在大多数情况下,如果你的开发环境与目标运行环境不同(比如你在x86架构的电脑上开发,但目标运行环境是ARM64架构的设备),那么不使用交叉编译工具链将导致编译出的模块或程序无法在目标设备上运行。这是因为不同的CPU架构需要不同的指令集,而编译器会根据目标架构生成相应的机器代码。
具体来说,如果不设置交叉编译工具链前缀,可能会发生以下几种情况:
-
编译失败:如果编译环境中没有安装适用于目标架构的编译器,那么编译过程可能会因为找不到合适的编译器而失败。
-
生成错误的二进制文件:如果编译环境中默认使用的是适用于当前系统架构的编译器(比如x86编译器),那么编译出的二进制文件将包含x86架构的指令集,而不是ARM64架构的指令集。这样的二进制文件无法在ARM64设备上运行。
-
运行时错误:即使编译过程没有失败,并且生成了二进制文件,但由于指令集不匹配,该文件在ARM64设备上运行时可能会出现各种错误,比如非法指令错误、段错误等。
因此,在进行跨架构开发时,设置交叉编译工具链前缀是非常重要的步骤,它确保了编译出的模块或程序能够在目标设备上正确运行。
3.如何查看当前系统的本地编译器是啥
要查看当前系统的本地编译器,可以通过以下几种方法来实现:
一、使用命令行查看已安装的编译器
- 查看GCC编译器:
- 在终端中输入命令
gcc --version
,如果GCC编译器已经安装在系统中,这条命令将显示GCC编译器的版本信息。
- 在终端中输入命令
- 查看Clang编译器:
- 在终端中输入命令
clang --version
,同样,如果Clang编译器已经安装在系统中,这条命令将显示Clang编译器的版本信息。
- 在终端中输入命令
- 查看特定交叉编译器:
- 对于特定的交叉编译器(如arm-linux-gcc),需要首先找到其安装路径,然后在该路径下执行相应的版本查看命令,如
arm-linux-gcc --version
。
- 对于特定的交叉编译器(如arm-linux-gcc),需要首先找到其安装路径,然后在该路径下执行相应的版本查看命令,如
二、使用系统软件包管理器查看已安装的编译器
- 基于APT的系统(如Debian、Ubuntu):
- 在终端中输入命令
apt list --installed | grep compiler
,这将列出所有包含“compiler”关键字的已安装软件包,你可以在返回的列表中查找编译器相关的内容。
- 在终端中输入命令
- 基于YUM的系统(如Red Hat、CentOS):
- 在终端中输入命令
yum list installed
,然后你可以在返回的列表中查找编译器相关的内容。
- 在终端中输入命令
三、查看当前系统默认编译器
- 查看环境变量:
- 在终端中输入命令
echo $CC
(或echo $CXX
对于C++编译器),这将显示当前系统默认使用的C(或C++)编译器的路径。
- 在终端中输入命令
- 查看编译器配置:
- 在某些开发环境中,你可以通过查看项目的配置文件(如Makefile)来了解当前项目所使用的编译器。
四、使用IDE或代码编辑器查看编译器
- 在VSCode中查看编译器:
- 打开VSCode,并在顶部菜单中选择“视图”->“终端”,或者按下快捷键
Ctrl + \
。 - 在终端中执行相应的编译器版本查看命令(如
gcc --version
或clang --version
)。
- 打开VSCode,并在顶部菜单中选择“视图”->“终端”,或者按下快捷键
- 在IntelliJ IDEA中查看Java编译器:
- 打开IntelliJ IDEA,并导入你的Java项目。
- 点击菜单栏中的“File”->“Project Structure”。
- 在弹出的窗口中,选择“Project”选项卡,在“Project SDK”下拉菜单中查看当前项目所使用的Java编译器版本。
通过以上方法,你可以方便地查看当前系统的本地编译器信息。请注意,不同的Linux发行版可能使用不同的包管理工具,因此具体的命令可能会有所不同。
4.如果设置交叉编译工具链前缀为gcc行不
将交叉编译工具链前缀设置为gcc
通常是不正确的,因为这样做不会指定一个具体的交叉编译器,而是可能会调用系统上的默认GCC编译器。交叉编译工具链前缀需要明确指出是针对哪个目标平台的编译器。
交叉编译工具链前缀的一般格式是arch-vendor-kernel-system-language
,其中各部分分别表示目标平台的体系结构(arch)、工具链供应商(vendor)、目标操作系统内核(kernel)、系统库和ABI(system),以及编程语言(language)。例如,aarch64-none-linux-gnu-
是一个常见的交叉编译工具链前缀,它表示该工具链用于编译针对ARM 64位架构(aarch64)、无特定供应商(none)、Linux内核(linux)、GNU库和ABI(gnu)的程序。
如果你的目标是进行交叉编译,你需要安装一个针对目标平台的交叉编译工具链,并设置正确的工具链前缀。这个前缀应该与你的目标平台和工具链相匹配。例如,如果你正在为ARM 64位架构编译程序,你应该安装一个适用于ARM 64位架构的交叉编译工具链,并设置前缀如aarch64-none-linux-gnu-
。
在Linux系统上,你可以通过包管理器安装交叉编译工具链。例如,在Ubuntu系统上,你可以使用以下命令安装针对ARM 64位架构的交叉编译工具链:
sudo apt-get install gcc-aarch64-linux-gnu |
安装完成后,你需要设置环境变量CROSS_COMPILE
来指定交叉编译工具链的前缀。例如:
export CROSS_COMPILE=aarch64-linux-gnu- |
请注意,这里的aarch64-linux-gnu-
是工具链前缀的一部分,它省略了gcc
或g++
等具体编译器的名称。在实际编译过程中,Makefile或其他构建脚本会使用这个前缀来调用正确的交叉编译工具链。例如,$(CROSS_COMPILE)gcc
将展开为aarch64-linux-gnu-gcc
,从而调用交叉编译的GCC编译器。