x86
ค้นหาด้วยตัวคุณเองใน 4.1.3 x86 และคู่มือ Intel
arch/x86/include/asm/cpufeature.h มีรายการทั้งหมด
ค่ากำหนดเป็นชนิด:
X*32 + Y
เช่น:
#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */
แฟล็กคุณสมบัติแยกจาก CPUID จะถูกเก็บไว้ภายใน:
__u32 x86_capability[NCAPINTS + NBUGINTS]; สนาม
- ของ
struct cpuinfo_x86 boot_cpu_data
- กำหนดไว้ที่
x86/kernel/setup.c
ซึ่งเริ่มต้นผ่าน__initฟังก์ชั่น
ที่แต่ละx86_capabilityองค์ประกอบอาร์เรย์มาจาก:
| 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 |
หมายเหตุ:
- รายการที่ว่างเปล่าหมายถึง: "จากสถานที่ต่าง ๆ " หรือ "ไม่ว่าง"
index: เป็นดัชนีของx86_capabilityเช่นx86_capability[0]
eaxและexc: คือค่าอินพุตสำหรับ CPUID ในฐานสิบหก อินพุตที่ใช้excซึ่งน้อยกว่าจะเรียกมันว่าsubleaf (ของทรี 2 ระดับด้วยeaxที่รูท)
output: คือรีจิสเตอร์ที่ใช้เอาต์พุต CPUID
file: เป็นไฟล์ที่มีการกำหนดฟิลด์เหล่านั้น arch/x86/kernel/cpu/เส้นทางเป็นญาติกับ
transmeta: เป็นชื่อของผู้จำหน่ายซีพียูhttps://en.wikipedia.org/wiki/Transmetaที่โนวาโฟร่าซื้อกิจการhttps://www.crunchbase.com/organization/novafora
centaur: เป็นชื่อของผู้ผลิตซีพียูhttps://en.wikipedia.org/wiki/Centaur_Technologyที่ถูกซื้อกิจการโดย VIA https://en.wikipedia.org/wiki/VIA_Technologies Cyrix เป็นอีกหนึ่ง
สรุป:
รายการส่วนใหญ่มาจากการลงทะเบียน CPUID โดยตรงและมีการตั้งค่าcommon.cโดย:
c->x86_capability[0] = edx;
สิ่งเหล่านี้หาได้ง่ายในคู่มือ Intel สำหรับ CPUID
คนอื่น ๆ set_cpu_capที่มีการกระจายอยู่ทั่วทั้งแหล่งที่มาและมีการตั้งค่าทีละนิดกับ
จะพบพวกเขาใช้ภายในgit grep X86_FEATURE_XXXarch/x86
โดยปกติคุณสามารถอนุมานได้ว่าบิต CPUID ใดที่สอดคล้องกับจากรหัสที่อยู่รอบ ๆ
ข้อเท็จจริงสนุกอื่น ๆ
แฟล็กถูกพิมพ์จริงarch/x86/kernel/cpu/proc.cด้วยรหัส:
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]);
ที่ไหน:
cpu_has ตรวจสอบคุณสมบัติหลักเป็นหลัก
x86_cap_flags[i] มีสตริงที่สอดคล้องกับแต่ละธง
สิ่งนี้จะถูกส่งผ่านเป็นการเรียกกลับไปยังการprocตั้งค่าระบบ fs/proc/cpuinfo.cจุดเริ่มต้นอยู่ที่
x86_cap_flagsสตริงจะถูกสร้างขึ้นarch/x86/kernel/cpu/mkcapflags.hโดยตรงจากarch/x86/include/asm/cpufeature.hโดย "การแยก" กับsed...
เอาต์พุตจะไปarch/x86/kernel/cpu/capflags.cที่ไดเร็กทอรี build และอาร์เรย์ผลลัพธ์จะมีลักษณะดังนี้:
const char * const x86_cap_flags[NCAPINTS*32] = {
[X86_FEATURE_FPU] = "fpu",
[X86_FEATURE_VME] = "vme",
ตัวอย่างเช่นX86_FEATURE_FPUสอดคล้องกับสตริง"fpu"และอื่น ๆ
cpu_has แบ่งออกเป็นสองกรณีด้วยรหัส:
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
test_cpu_cap(c, bit))
พวกเขาคือ:
__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit): จำเป็นต้องใช้แฟล็กเพื่อให้เคอร์เนลทำงาน
นี้จะถูกกำหนดโดยข้อมูลภายในrequired-features.hซึ่งความคิดเห็น:
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!
เนื่องจากสิ่งเหล่านี้เป็นที่รู้จักกันในเวลารวบรวม (ข้อกำหนดของเคอร์เนล) ได้ถูกตรวจสอบแล้วเมื่อเริ่มต้นการตรวจสอบสามารถแก้ไขได้ในเวลารวบรวมหากbitเป็นที่รู้จักในเวลารวบรวม
ดังนั้นสิ่ง__builtin_constant_p(bit)ที่ตรวจสอบว่าbitเป็นค่าคงที่เวลารวบรวม
test_cpu_cap: นี่ใช้CPUIDข้อมูลจากstruct cpuinfo_x86 boot_cpu_dataทั่วโลก
$ egrep -wo ^flags|vmx|ept|vpid|npt|tpr_shadow|flexpriority|vnmi|lm|aes' /proc/cpuinfo --color | sort -uIntel: และนอกจากนี้ยังมี CLI / GUI ที่ดีเยี่ยมของ i-NEX