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_XXX
arch/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 -u
Intel: และนอกจากนี้ยังมี CLI / GUI ที่ดีเยี่ยมของ i-NEX