x86
Tìm chính nó trong 4.1.3 x86 và hướng dẫn sử dụng Intel
arch/x86/include/asm/cpufeature.h
chứa danh sách đầy đủ.
Các giá trị xác định là loại:
X*32 + Y
Ví dụ:
#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
Các cờ tính năng, được trích xuất từ CPUID, được lưu trữ bên trong:
__u32 x86_capability[NCAPINTS + NBUGINTS];
cánh đồng
- của
struct cpuinfo_x86 boot_cpu_data
- được định nghĩa tại
x86/kernel/setup.c
được khởi tạo thông qua các __init
chức năng.
Trường hợp mỗi x86_capability
phần tử mảng đến từ:
| index | eax | ecx | output | file |
|-------|----------|-----|--------|-------------|
| 0 | 1 | 0 | edx | common.c |
| 1 | 80000001 | | edx | common.c |
| 2 | 80860001 | | edx | transmeta.c |
| 3 | | | | |
| 4 | 1 | 0 | ecx | common.c |
| 5 | C0000001 | | edx | centaur.c |
| 6 | 80000001 | | ecx | common.c |
| 7 | | | | scattered.c |
| 8 | | | | |
| 9 | 7 | 0 | ebx | common.c |
| 10 | D | 1 | eax | common.c |
| 11 | F | 0 | edx | common.c |
| 12 | F | 1 | edx | common.c |
Ghi chú:
Kết luận:
hầu hết các mục đến trực tiếp từ các thanh ghi đầu ra CPUID và được thiết lập common.c
bởi một cái gì đó như:
c->x86_capability[0] = edx;
Chúng có thể dễ dàng tìm thấy hàng loạt trên sổ tay Intel cho CPUID.
những cái khác nằm rải rác trong nguồn và được thiết lập từng chút một set_cpu_cap
.
Để tìm thấy chúng, sử dụng git grep X86_FEATURE_XXX
bên trong arch/x86
.
Bạn thường có thể suy ra bit CPUID tương ứng với mã xung quanh.
Những sự thật thú vị khác
Các cờ thực sự được in arch/x86/kernel/cpu/proc.c
với mã:
seq_puts(m, "flags\t\t:");
for (i = 0; i < 32*NCAPINTS; i++)
if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
seq_printf(m, " %s", x86_cap_flags[i]);
Ở đâu:
cpu_has
kiểm tra chính cho các tính năng.
x86_cap_flags[i]
chứa các chuỗi tương ứng với mỗi cờ.
Điều này được thông qua như một cuộc gọi lại để proc
thiết lập hệ thống. Điểm vào là tại fs/proc/cpuinfo.c
.
x86_cap_flags
chuỗi được tạo bởi arch/x86/kernel/cpu/mkcapflags.h
trực tiếp từ arch/x86/include/asm/cpufeature.h
"phân tích" nó bằng sed
...
Đầu ra đi đến arch/x86/kernel/cpu/capflags.c
thư mục build và mảng kết quả trông như sau:
const char * const x86_cap_flags[NCAPINTS*32] = {
[X86_FEATURE_FPU] = "fpu",
[X86_FEATURE_VME] = "vme",
vì vậy, ví dụ X86_FEATURE_FPU
tương ứng với chuỗi "fpu"
và như vậy.
cpu_has
chia thành hai trường hợp với mã:
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
test_cpu_cap(c, bit))
Họ đang:
__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit)
: cờ được yêu cầu cho kernel chạy.
Điều này được xác định bởi dữ liệu bên trong required-features.h
, nhận xét:
Define minimum CPUID feature set for kernel These bits are checked
really early to actually display a visible error message before the
kernel dies. Make sure to assign features to the proper mask!
Vì những cái đó được biết đến tại thời gian biên dịch (yêu cầu kernel), đã được kiểm tra khi khởi động, kiểm tra có thể được giải quyết tại thời gian biên dịch nếu bit
được biết tại thời gian biên dịch.
Do __builtin_constant_p(bit)
đó, kiểm tra nếu bit
là một hằng số thời gian biên dịch.
test_cpu_cap
: điều này sử dụng hết CPUID
dữ liệu từ struct cpuinfo_x86 boot_cpu_data
toàn cầu
$ egrep -wo ^flags|vmx|ept|vpid|npt|tpr_shadow|flexpriority|vnmi|lm|aes' /proc/cpuinfo --color | sort -u
. Và còn có i-nex CLI / GUI xuất sắc .