[英]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.