[英]How to cross compile a c program to aarch64 with cpuid.h?
我正在尝试将一个简单的 C 程序从 64 位 Ubuntu Linux 交叉编译为 aarch64(arm64)。 有人可以帮助我为什么会收到此错误。
它说找不到'cpuid.h'。 我已经尝试在 64 位 linux 上编译它,它工作正常。 但是在使用aarch64-linux-gnu-gcc
时会出错。
我收到以下错误。
aarch64-linux-gnu-gcc -O1 -fno-stack-protector -march=armv8-a test.c -o test
test.c:4:10: fatal error: cpuid.h: No such file or directory
4 | #include <cpuid.h>
| ^~~~~~~~~
compilation terminated.
test.c
的内容:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cpuid.h>
// Requires that the user input the CPUID,
// plus the bytes "3" and "Q";
void succeed(char* string) {
printf("Yes, %s is correct!\n", string);
exit(0);
}
void fail(char* string) {
printf("No, %s is not correct.\n", string);
exit(1);
}
void shift_int_to_char(int i, char* buff) {
buff[0] = (i) & 0xFF;
buff[1] = (i >> 8) & 0xFF;
buff[2] = (i >> 16) & 0xFF;
buff[3] = (i >> 24) & 0xFF;
}
int main(int argc, char** argv) {
if (argc != 2) {
printf("Need exactly one argument.\n");
return -1;
}
unsigned int eax, ebx, ecx, edx;
char* buff = malloc(sizeof(char) * 15);
__get_cpuid(0, &eax, &ebx, &ecx, &edx);
shift_int_to_char(ebx, buff);
shift_int_to_char(edx, buff + 4);
shift_int_to_char(ecx, buff + 8);
buff[12] = '3';
buff[13] = 'Q';
buff[14] = '\0';
int correct = (strcmp(buff, argv[1]) == 0);
free(buff);
if (correct) {
succeed(argv[1]);
} else {
fail(argv[1]);
}
}
正如评论中所解释的,您需要将此程序移植到 Aarch64 架构,您不能只按原样编译代码。 SoC 中实现的功能通过各种AArch64 功能系统寄存器或指令集属性寄存器公开,例如ID_AA64PFR1_EL1 。
按照惯例,名称以 _EL1 结尾的寄存器不能从运行在 EL0 的用户模式程序访问。 因此,从用户模式程序中读取这些寄存器需要操作系统(在 EL1 上运行)的一些支持——我使用 Linux 5.15.0 内核来回答这个问题。
在最近的 Linux 内核上,这可以通过使用 hwcaps 中提供的HWCAP_CPUID API 来实现 - 更多详细信息请参见本文ARM64 CPU 功能寄存器。
我们可以编译/执行附录 I 中提供的示例代码:
/*
* Sample program to demonstrate the MRS emulation ABI.
*
* Copyright (C) 2015-2016, ARM Ltd
*
* Author: Suzuki K Poulose <suzuki.poulose@arm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <asm/hwcap.h>
#include <stdio.h>
#include <sys/auxv.h>
#define get_cpu_ftr(id) ({ \
unsigned long __val; \
asm("mrs %0, "#id : "=r" (__val)); \
printf("%-20s: 0x%016lx\n", #id, __val); \
})
int main(void)
{
if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) {
fputs("CPUID registers unavailable\n", stderr);
return 1;
}
get_cpu_ftr(ID_AA64ISAR0_EL1);
get_cpu_ftr(ID_AA64ISAR1_EL1);
get_cpu_ftr(ID_AA64MMFR0_EL1);
get_cpu_ftr(ID_AA64MMFR1_EL1);
get_cpu_ftr(ID_AA64PFR0_EL1);
get_cpu_ftr(ID_AA64PFR1_EL1);
get_cpu_ftr(ID_AA64DFR0_EL1);
get_cpu_ftr(ID_AA64DFR1_EL1);
get_cpu_ftr(MIDR_EL1);
get_cpu_ftr(MPIDR_EL1);
get_cpu_ftr(REVIDR_EL1);
#if 0
/* Unexposed register access causes SIGILL */
get_cpu_ftr(ID_MMFR0_EL1);
#endif
return 0;
}
执行:
gcc -o cpu-feature-registers cpu-feature-registers.c
./cpu-feature-registers
ID_AA64ISAR0_EL1 : 0x0000000000010000
ID_AA64ISAR1_EL1 : 0x0000000000000000
ID_AA64MMFR0_EL1 : 0x00000111ff000000
ID_AA64MMFR1_EL1 : 0x0000000000000000
ID_AA64PFR0_EL1 : 0x0000000000000011
ID_AA64PFR1_EL1 : 0x0000000000000000
ID_AA64DFR0_EL1 : 0x0000000000000006
ID_AA64DFR1_EL1 : 0x0000000000000000
MIDR_EL1 : 0x00000000410fd034
MPIDR_EL1 : 0x0000000080000000
REVIDR_EL1 : 0x0000000000000000
您现在只需要识别将为您提供 x86_64 代码提供的相同类型信息的功能/指令集寄存器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.