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 __initchức năng.
Trường hợp mỗi x86_capabilityphầ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.cbở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_XXXbê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.cvớ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 để procthiết lập hệ thống. Điểm vào là tại fs/proc/cpuinfo.c.
x86_cap_flagschuỗi được tạo bởi arch/x86/kernel/cpu/mkcapflags.htrự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.cthư 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_FPUtươ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 bitlà một hằng số thời gian biên dịch.
test_cpu_cap: điều này sử dụng hết CPUIDdữ liệu từ struct cpuinfo_x86 boot_cpu_datatoà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 .