একটি বুটলোডার/কার্নেল তৈরি করার সময়, সফ্টওয়্যার এবং হার্ডওয়্যারের মধ্যে পারফরম্যান্স এবং সামঞ্জস্যতা অপ্টিমাইজ করার জন্য অন্তর্নিহিত আর্কিটেকচার বোঝা অত্যন্ত গুরুত্বপূর্ণ৷
সিস্টেমের তথ্য অনুসন্ধান এবং পুনরুদ্ধার করার জন্য ইঞ্জিনিয়ারদের কাছে উপলব্ধ একটি গুরুত্বপূর্ণ কিন্তু কখনও কখনও উপেক্ষিত টুল হল CPUID নির্দেশনা৷
CPUID নির্দেশনা কি?
CPUID নির্দেশ হল একটি নিম্ন স্তরের নির্দেশ, প্রতিটি আধুনিক x86 এবং x86-64 প্রসেসরের হৃদয়ের ভিতরে যা সফ্টওয়্যারটিকে প্রসেসর এবং এর সমর্থিত বৈশিষ্ট্যগুলি সম্পর্কে তথ্যের জন্য CPU-কে জিজ্ঞাসা করতে দেয়৷
এই নির্দেশের মাধ্যমে, আপনি প্রসেসরের মডেল, পরিবার, অভ্যন্তরীণ ক্যাশের আকার এবং SIMD বা হার্ডওয়্যার ভার্চুয়ালাইজেশনের মতো সমর্থিত বৈশিষ্ট্যগুলির মতো তথ্য সংগ্রহ করতে পারেন। এটি আপনাকে কর্মক্ষমতা অপ্টিমাইজ করতে এবং গতিশীলভাবে সমর্থিত বৈশিষ্ট্যগুলিকে সক্ষম বা অক্ষম করতে সহায়তা করতে পারে৷
বুটলোডার বা কার্নেল ডেভেলপারদের জন্য, প্রসেসর কোন বৈশিষ্ট্যগুলিকে সমর্থন করে — যেমন হার্ডওয়্যার ভার্চুয়ালাইজেশন, ক্যাশের আকার, বা SIMD নির্দেশাবলী — তা নিশ্চিত করতে পারে যে সিস্টেমটি দক্ষতার সাথে চলছে এবং আপনার লেখা কোডটি বিভিন্ন CPU তে সামঞ্জস্যপূর্ণ। CPUID নির্দেশ ব্যবহার করে, আপনি যে নির্দিষ্ট প্রসেসরে চলছে তার উপর ভিত্তি করে আপনার কার্নেলের আচরণ গতিশীলভাবে সামঞ্জস্য করতে পারেন।
এই নিবন্ধে আপনি শিখবেন কিভাবে চেক করতে হয় CPUID নির্দেশ আপনার সিস্টেমের জন্য উপলব্ধ কিনা, এটি কীভাবে কাজ করে এবং আপনি এটি ব্যবহার করে কী তথ্য পেতে পারেন।
পূর্বশর্ত
-
সমাবেশ ভাষার কিছু জ্ঞান (এই উদাহরণের জন্য আমি FASM ব্যবহার করি)
-
অপারেটিং সিস্টেম/কার্নেল সম্পর্কে কিছু জ্ঞান
-
বিভিন্ন প্ল্যাটফর্মে আপনার বুটলোডার/কার্নেল পরীক্ষা করার জন্য নিম্ন-স্তরের ডিবাগিং টুল (উদাহরণস্বরূপ, GDB) বা QEMU-এর মতো হার্ডওয়্যার এমুলেটরগুলিতে অ্যাক্সেস।
ধাপ 1:CPUID উপলব্ধতা পরীক্ষা করুন
CPUID নির্দেশ কার্যকর করার আগে, প্রসেসর এটি সমর্থন করে কিনা তা নির্ধারণ করা গুরুত্বপূর্ণ, কারণ সমস্ত CPU-তে এই কার্যকারিতা থাকার নিশ্চয়তা দেওয়া হয় না। নিম্নলিখিত কোডটি EFLAGS রেজিস্টারে আইডি বিট (বিট 21) পরিবর্তন ও পরীক্ষা করে CPUID নির্দেশের উপলব্ধতা পরীক্ষা করে।
এখানে wiki.osdev.org থেকে একটি ছবি যা EFLAGS রেজিস্টারের প্রতিটি বিট দেখায়:

যদি প্রসেসর এই বিটটিকে টগল করার অনুমতি দেয়, CPUID সমর্থিত; অন্যথায়, এটা না। এখানে শনাক্তকরণ প্রক্রিয়া কিভাবে কাজ করে:
(বেশিরভাগ মানুষ মনে করে যে রিয়েল মোডে 32টি রেজিস্টার অ্যাক্সেসযোগ্য নয়৷ এটি সত্য নয়৷ সমস্ত 32বিট রেজিস্টার ব্যবহারযোগ্য)
cpuid_check:
pusha ; save state
pushfd ; Save EFLAGS
pushfd ; Store EFLAGS
xor dword [esp],0x00200000 ; Invert the ID bit in stored EFLAGS
popfd ; Load stored EFLAGS (with ID bit inverted)
pushfd ; Store EFLAGS again (ID bit may or may not be inverted)
pop eax ; eax = modified EFLAGS (ID bit may or may not be inverted)
xor eax,[esp] ; eax = whichever bits were changed
popfd ; Restore original EFLAGS
and eax,0x00200000 ; eax = zero if ID bit can't be changed, else non-zero
cmp eax,0x00
je .cpuid_instruction_not_is_available
.cpuid_instruction_is_available:
;handle CPUID exists
.cpuid_instruction_not_is_available:
;handle CPUID isn't supported
.cpuid_check_end:
popa ; restore state
ret
pusha :মূল অবস্থা শেষ পর্যন্ত পুনরুদ্ধার করা যায় তা নিশ্চিত করতে সমস্ত সাধারণ উদ্দেশ্য রেজিস্টার সংরক্ষণ করে৷
pushfd :বর্তমান EFLAGS রেজিস্টার সংরক্ষণ করে।
pushfd :EFLAGS-এর একটি অনুলিপি সঞ্চয় করে৷
xor dword [esp], 0x00200000 :কোডটি XOR অপারেটর ব্যবহার করে EFLAGS-এর আইডি বিট (21) ফ্লিপ করে।
popfd :আইডি বিট ইনভার্ট করে পরিবর্তিত EFLAGS পুনরুদ্ধার করে।
pushfd :পরিবর্তিত EFLAGS কে স্ট্যাকের দিকে ঠেলে দেয়।
pop eax :EAX রেজিস্টারে পরিবর্তিত EFLAGS (আইডি বিট উল্টানো হতে পারে বা নাও হতে পারে) রাখে।
xor eax, [esp] :XOR অপারেশনের পরে, EAX-এ পরিবর্তন করা বিটগুলি থাকবে৷
popfd :মূল EFLAGS পুনরুদ্ধার করে৷
and eax, 0x00200000 :and অপারেশন অন্য সব বিট মাস্ক করে 21 তম বিট (আইডি বিট) বিচ্ছিন্ন করে। এই অপারেশনের পরে EAX রেজিস্টারে হয় 0x00200000 (যদি 21 বিট পরিবর্তন করা হয় যার মানে CPUID সমর্থিত) অথবা 0x00 (21 বিট পরিবর্তিত হয়নি, CPUID সমর্থিত নয়)।
cmp eax, 0x00 :CMP নির্দেশনা পূর্ববর্তী অপারেশনের ফলাফল পরীক্ষা করে। যদি EAX 0×00 এর সমান হয়, তাহলে এর অর্থ হল ID বিট পরিবর্তন করা যাবে না এবং প্রসেসর CPUID নির্দেশ সমর্থন করে না। যদি এটি শূন্য না হয়, তাহলে এর অর্থ হল ID বিটটি ফ্লিপ করা হয়েছে এবং আপনার প্রসেসর CPUID নির্দেশকে সমর্থন করে৷
সিপিইউ বৈশিষ্ট্য পান
CPUID নির্দেশ EAX রেজিস্টারে বিভিন্ন মান সহ বিভিন্ন তথ্য প্রদান করবে।
mov eax, 0x1
cpuid
EAX 1-এ সেট করা হলে, CPUID EDX-এ একটি বিটফিল্ড ফেরত দেবে, যাতে নিম্নলিখিত মানগুলি থাকবে৷ বিভিন্ন ব্র্যান্ড এগুলোর ভিন্ন অর্থ দিতে পারে (সূত্র https://wiki.osdev.org/CPUID)
enum {
CPUID_FEAT_ECX_SSE3 = 1 << 0,
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
CPUID_FEAT_ECX_DTES64 = 1 << 2,
CPUID_FEAT_ECX_MONITOR = 1 << 3,
CPUID_FEAT_ECX_DS_CPL = 1 << 4,
CPUID_FEAT_ECX_VMX = 1 << 5,
CPUID_FEAT_ECX_SMX = 1 << 6,
CPUID_FEAT_ECX_EST = 1 << 7,
CPUID_FEAT_ECX_TM2 = 1 << 8,
CPUID_FEAT_ECX_SSSE3 = 1 << 9,
CPUID_FEAT_ECX_CID = 1 << 10,
CPUID_FEAT_ECX_SDBG = 1 << 11,
CPUID_FEAT_ECX_FMA = 1 << 12,
CPUID_FEAT_ECX_CX16 = 1 << 13,
CPUID_FEAT_ECX_XTPR = 1 << 14,
CPUID_FEAT_ECX_PDCM = 1 << 15,
CPUID_FEAT_ECX_PCID = 1 << 17,
CPUID_FEAT_ECX_DCA = 1 << 18,
CPUID_FEAT_ECX_SSE4_1 = 1 << 19,
CPUID_FEAT_ECX_SSE4_2 = 1 << 20,
CPUID_FEAT_ECX_X2APIC = 1 << 21,
CPUID_FEAT_ECX_MOVBE = 1 << 22,
CPUID_FEAT_ECX_POPCNT = 1 << 23,
CPUID_FEAT_ECX_TSC = 1 << 24,
CPUID_FEAT_ECX_AES = 1 << 25,
CPUID_FEAT_ECX_XSAVE = 1 << 26,
CPUID_FEAT_ECX_OSXSAVE = 1 << 27,
CPUID_FEAT_ECX_AVX = 1 << 28,
CPUID_FEAT_ECX_F16C = 1 << 29,
CPUID_FEAT_ECX_RDRAND = 1 << 30,
CPUID_FEAT_ECX_HYPERVISOR = 1 << 31,
CPUID_FEAT_EDX_FPU = 1 << 0,
CPUID_FEAT_EDX_VME = 1 << 1,
CPUID_FEAT_EDX_DE = 1 << 2,
CPUID_FEAT_EDX_PSE = 1 << 3,
CPUID_FEAT_EDX_TSC = 1 << 4,
CPUID_FEAT_EDX_MSR = 1 << 5,
CPUID_FEAT_EDX_PAE = 1 << 6,
CPUID_FEAT_EDX_MCE = 1 << 7,
CPUID_FEAT_EDX_CX8 = 1 << 8,
CPUID_FEAT_EDX_APIC = 1 << 9,
CPUID_FEAT_EDX_SEP = 1 << 11,
CPUID_FEAT_EDX_MTRR = 1 << 12,
CPUID_FEAT_EDX_PGE = 1 << 13,
CPUID_FEAT_EDX_MCA = 1 << 14,
CPUID_FEAT_EDX_CMOV = 1 << 15,
CPUID_FEAT_EDX_PAT = 1 << 16,
CPUID_FEAT_EDX_PSE36 = 1 << 17,
CPUID_FEAT_EDX_PSN = 1 << 18,
CPUID_FEAT_EDX_CLFLUSH = 1 << 19,
CPUID_FEAT_EDX_DS = 1 << 21,
CPUID_FEAT_EDX_ACPI = 1 << 22,
CPUID_FEAT_EDX_MMX = 1 << 23,
CPUID_FEAT_EDX_FXSR = 1 << 24,
CPUID_FEAT_EDX_SSE = 1 << 25,
CPUID_FEAT_EDX_SSE2 = 1 << 26,
CPUID_FEAT_EDX_SS = 1 << 27,
CPUID_FEAT_EDX_HTT = 1 << 28,
CPUID_FEAT_EDX_TM = 1 << 29,
CPUID_FEAT_EDX_IA64 = 1 << 30,
CPUID_FEAT_EDX_PBE = 1 << 31
};
উপরে CPU বৈশিষ্ট্যগুলির একটি সংক্ষিপ্ত ব্যাখ্যা:
-
PCLMUL, AES:দ্রুত এনক্রিপশন এবং ডিক্রিপশনের জন্য ক্রিপ্টোগ্রাফিক নির্দেশনা সেট করে। -
VMX, SMX:ভার্চুয়াল মেশিন চালানোর জন্য ভার্চুয়ালাইজেশন সমর্থন। -
SSE3, SSSE3, SSE4.1, SSE4.2, AVX:দ্রুত মাল্টিমিডিয়া, গণিত, এবং ভেক্টর প্রক্রিয়াকরণের জন্য SIMD নির্দেশনা সেট করে। -
FMA:ফিউজড মাল্টিপ্লাই-অ্যাড, ফ্লোটিং-পয়েন্ট ক্যালকুলেশনে কর্মক্ষমতা উন্নত করে। -
৷RDRAND:এলোমেলো নম্বর জেনারেটর৷ -
X2APIC:মাল্টিপ্রসেসর সিস্টেমে অ্যাডভান্সড ইন্টারাপ্ট হ্যান্ডলিং। -
PCID:কনটেক্সট সুইচের সময় মেমরি ম্যানেজমেন্ট অপ্টিমাইজ করে। -
FPU:দ্রুত গণিত অপারেশনের জন্য হার্ডওয়্যার ফ্লোটিং-পয়েন্ট ইউনিট। -
PAE:ফিজিক্যাল অ্যাড্রেস এক্সটেনশন, 4 গিগাবাইটের বেশি মেমরি অ্যাড্রেস করার অনুমতি দেয়৷ -
HTT:একটি একক CPU কোরকে একাধিক থ্রেড পরিচালনা করার অনুমতি দেয়৷ -
PAT, PGE:ক্যাশিং এবং পৃষ্ঠা ম্যাপিং নিয়ন্ত্রণের জন্য মেমরি ব্যবস্থাপনা বৈশিষ্ট্য। -
MMX, SSE, SSE2:মাল্টিমিডিয়া প্রক্রিয়াকরণের জন্য পুরানো SIMD নির্দেশনা সেট।
সিপিইউ ভেন্ডর স্ট্রিং পান
আপনি যদি CPU বিক্রেতা স্ট্রিং পেতে চান, CPUID নির্দেশনা শুরু করার আগে EAX কে 0×0 এ সেট করা উচিত।
mov eax, 0x0
cpuid
ভেন্ডর স্ট্রিং হল একটি অনন্য শনাক্তকারী যা AMD এবং Intel এর মত CPU বিক্রেতারা ব্যবহার করে। উদাহরণ হল:GenuineIntel (Intel প্রসেসরের জন্য) অথবা AuthenticAMD (AMD প্রসেসরের জন্য)। এটি মূলত CPU এর প্রস্তুতকারককে নির্দিষ্ট করে।
ভেন্ডর স্ট্রিং কার্নেলকে CPU প্রস্তুতকারক সনাক্ত করতে দেয় যা খুবই দরকারী কারণ বিভিন্ন নির্মাতারা নির্দিষ্ট বৈশিষ্ট্যগুলি ভিন্নভাবে প্রয়োগ করে। এছাড়াও, সফ্টওয়্যার বা ড্রাইভারগুলি সামঞ্জস্য নিশ্চিত করতে CPU প্রস্তুতকারকের উপর ভিত্তি করে ভিন্নভাবে যোগাযোগ করতে পারে।
এইভাবে ব্যবহার করা হলে, ইবিএক্স, ইডিএক্স, ইসিএক্স রেজিস্টারে ভেন্ডর আইডি স্ট্রিং ফেরত দেওয়া হবে। আপনি তাদের একটি বাফারে লিখতে পারেন এবং সম্পূর্ণ 12টি অক্ষর স্ট্রিং পেতে পারেন।
উদাহরণ কোড:
ধাপ 1:বাফার
একটি বাফার তৈরি করুন যা 12 বাইট ধারণ করতে পারে:
buffer: db 12 dup(0), 0xA, 0xD, 0
ধাপ 2:বাফার প্রিন্ট করুন
আমরা একটি স্ট্রিং প্রিন্টিং ফাংশন তৈরি করে শুরু করি৷
এই অ্যাসেম্বলি কোডটি অক্ষর অনুসারে একটি স্ট্রিং অক্ষর পড়ে এবং এটি BIOS ইন্টারাপ্ট 0x10 ব্যবহার করে স্ক্রিনে প্রিন্ট করে। print ফাংশন স্ট্রিং এর মাধ্যমে লুপ করে এবং lodsb ব্যবহার করে al-এ প্রতিটি অক্ষর লোড করার নির্দেশ নিবন্ধন করুন।
তারপর print_char ফাংশনটি স্ক্রিনে প্রিন্ট করার জন্য বিঘ্নিত 0×10 ব্যবহার করে। যখন কোডটি স্ট্রিং (নাল টার্মিনেটর) এর শেষে পৌঁছায়, তখন লুপ শেষ হয়।
print_string:
call print
ret
print:
.loop:
lodsb ;read character to al and then increment
cmp al ,0 ;check if we reached the end
je .done ;we reached null terminator, finish
call print_char ;print character
jmp .loop ;jump back into the loop
.done:
ret
print_char:
mov ah, 0eh
int 0x10
ret
ধাপ 3:বাফারটি পূরণ করুন এবং এটি মুদ্রণ করুন
এখানে, pusha ব্যবহার করে বর্তমান অবস্থা সংরক্ষণ করার পরে নির্দেশনা এবং কলিং cpuid EAX রেজিস্টারে 0×0 পাস করলে, আমরা ebx এর বিষয়বস্তু সংরক্ষণ করতে পারি , edx , ecx বাফারে তারপর আমরা print_string কল করি এটি প্রিন্ট করতে।
get_cpu_vendor:
pusha
mov eax, 0x0
cpuid
mov [buffer], ebx
mov [buffer + 4], edx
mov [buffer + 8], ecx
mov si, buffer
call print_string
popa
ret
আমার ইউটিউব চ্যানেলের একটি ভিডিও যেখানে আমি উপরের কোডটি প্রয়োগ করেছি এবং বিস্তারিতভাবে ব্যাখ্যা করেছি
EAX রেজিস্টারে পাস করা মান অনুযায়ী CPUID নির্দেশ আপনাকে কী তথ্য দিতে পারে সে সম্পর্কে আরও তথ্য এখানে পাওয়া যাবে:https://gitlab.com/x86-cpuid.org/x86-cpuid-db
এপিলগ
CPUID নির্দেশনা বুঝে এবং ব্যবহার করে, আপনি আপনার বুটলোডার/কার্নেলকে প্রসেসরের বিস্তৃত পরিসরের সাথে আরও মানিয়ে নিতে পারেন। নির্দেশের প্রাপ্যতা কীভাবে সনাক্ত করা যায় এবং গুরুত্বপূর্ণ সিস্টেম তথ্য যেমন CPU বৈশিষ্ট্য, ক্যাশের আকার এবং সমর্থিত প্রযুক্তিগুলি পুনরুদ্ধার করা যায় তা জানার ফলে কার্যক্ষমতা এবং সামঞ্জস্যতা উল্লেখযোগ্যভাবে উন্নত হতে পারে৷
এই নিবন্ধটি পড়ার পরে, আপনার কাছে CPUID নির্দেশাবলী অন্বেষণ শুরু করার জন্য সরঞ্জাম এবং জ্ঞান থাকা উচিত এবং আপনি কীভাবে এটি আপনার নিজের প্রকল্পে ব্যবহার করতে পারেন!
শুভ কোডিং!
বিনামূল্যে কোড শিখুন. freeCodeCamp-এর ওপেন সোর্স পাঠ্যক্রম 40,000-এরও বেশি লোককে ডেভেলপার হিসেবে চাকরি পেতে সাহায্য করেছে। শুরু করুন