இந்த ஐந்தாவது தவணையில் கோட்பாடு மற்றும் பயன்பாட்டில் ஜி.டி.டிக்கு ஒத்த ஒரு அட்டவணையைப் பார்ப்போம், நாங்கள் ஐ.டி.டி. ஐடிடி என்பது குறிக்கிறது விளக்க அட்டவணையை குறுக்கிடுகிறது y என்பது ஏற்படும் குறுக்கீடுகளை கையாள பயன்படும் அட்டவணை. எடுத்துக்காட்டாக, யாரோ ஒருவர் 0 ஆல் ஒரு பிரிவை உருவாக்குகிறார், செயலாக்கத்தின் பொறுப்பான செயல்பாடு என்று அழைக்கப்படுகிறது. இந்த செயல்பாடுகள் ஐ.எஸ்.ஆர் (குறுக்கீடு சேவை நடைமுறைகள்). எனவே ஐடிடியை உருவாக்கி சில ஐ.எஸ்.ஆரைச் சேர்ப்போம்.
முதலில் நாம் IDT உடன் தொடர்புடைய கட்டமைப்புகளை அறிவிக்கப் போகிறோம்:
struct Entry{
uint16_t base_low;
uint16_t sel;
uint8_t always0;
uint8_t flags;
uint16_t base_high;
} __attribute__((packed));
struct Ptr{
uint16_t limit;
uint32_t base;
} __attribute__((packed));
நீங்கள் அதை ஜி.டி.டியுடன் ஒப்பிட்டுப் பார்த்தால், பி.டி.ஆர் அமைப்பு ஒரே மாதிரியானது மற்றும் நுழைவு மிகவும் ஒத்திருக்கிறது. எனவே ஒரு நுழைவு (செட்கேட்) மற்றும் நிறுவுதல் (நிறுவுதல்) ஆகியவற்றின் செயல்பாடுகள் மிகவும் ஒத்தவை.
void ND::IDT::SetGate(uint8_t num,uint32_t base,uint16_t sel, uint8_t flags)
{
idt[num].base_low=(base & 0xFFFF);
idt[num].base_high=(base >> 16) & 0xFFFF;
idt[num].sel=sel;
idt[num].always0=0;
idt[num].flags=flags;
}
நிறுவு:
idtptr.limit=(sizeof(struct ND::IDT::Entry)*256)-1;
idtptr.base=(uint32_t)&idt;
ND::Memory::Set(&idt,0,sizeof(struct ND::IDT::Entry)*256);
ND::IDT::Flush();
நாம் பார்த்தால், நிறுவல் செயல்பாடு ND :: நினைவகம் :: பிற இடுகையில் அறிவித்த செயல்பாட்டைப் பயன்படுத்துவதைக் காண்போம். செட்கேட்டுக்கு நாங்கள் இதுவரை எந்த அழைப்பையும் செய்யவில்லை என்பதையும் நாங்கள் பாராட்டலாம், மேலும் நாங்கள் ND :: IDT :: Flush என்று அழைக்கிறோம், இந்த செயல்பாட்டிற்காக நாம் மீண்டும் asm ஆவியாகும் அறிக்கையைப் பயன்படுத்துகிறோம்:
asm volatile("lidtl (idtptr)");
எல்லாம் சரியாக நடந்தால், நாம் ஒரு அழகியல் ஏற்பாட்டைச் செய்தால், இது இப்படி இருக்க வேண்டும்:
சரி, இப்போது நாம் IDT ஐ குறுக்கீடுகளால் நிரப்பத் தொடங்க உள்ளோம். இங்கே நான் ஒன்றை மட்டுமே உருவாக்கப் போகிறேன், மீதமுள்ளவர்களுக்கு அது ஒரே மாதிரியாக இருக்கும். நான் பூஜ்ஜிய இடைவெளியால் பிளவு செய்யப் போகிறேன். கணிதத்தில் உங்களுக்கு நன்கு தெரியும், ஒரு எண்ணை 0 ஆல் வகுக்க முடியாது. இது செயலியில் நடந்தால், தொடர முடியாததால் விதிவிலக்கு உருவாக்கப்படுகிறது. ஐடிடியில், பட்டியலில் முதல் குறுக்கீடு (0) இந்த நிகழ்வுக்கு ஒத்திருக்கிறது.
ஐடிடியின் நிறுவல் செயல்பாட்டிற்குள் நினைவக அமைப்பிற்கும் பறிப்புக்கும் இடையில் இதைச் சேர்க்கிறோம்:
ND::IDT::SetGate(0,(unsigned)ND::ISR::ISR1,0x08,0x8E);
திரும்பப்பெறுதல் செயல்பாடு ND :: ISR :: ISR1 ஆக இருக்கும், இது ASM ஐப் பயன்படுத்த வேண்டும் என்றாலும் இது மிகவும் எளிது:
void ND::ISR::ISR1()
{
asm volatile(
"cli \n"
"pushl 0 \n"
"pushl 0 \n"
"jmp ND_ISR_Common \n"
);
}
ND_ISR_Common இதை சி மொழியில் ஒரு செயல்பாடாக வரையறுப்போம். கோப்புகளைச் சேமிக்கவும், வாசிப்பை மேம்படுத்தவும் வெளிப்புற «C» {use ஐப் பயன்படுத்தலாம்:
extern "C"
void ND_ISR_Common()
{
asm volatile(
"pusha \n"
"push %ds \n"
"push %es \n"
"push %fs \n"
"push %gs \n"
"movw $0x10, %ax \n"
"movw %ax, %ds \n"
"movw %ax, %es \n"
"movw %ax, %fs \n"
"movw %ax, %gs \n"
"movl %esp, %eax \n"
"push %eax \n"
"movl $ND_ISR_Handler, %eax \n"
"call *%eax \n"
"popl %eax \n"
"popl %ds \n"
"popl %es \n"
"popl %fs \n"
"popl %gs \n"
"popa \n"
"addl 8, %esp \n"
"iret \n"
);
}
ASM இல் உள்ள இந்த குறியீடு புரிந்துகொள்வது சற்று கடினமாக இருக்கும், ஆனால் இது குறுக்கீட்டால் உருவாக்கப்பட்ட தரவை அணுக C இல் ஒரு கட்டமைப்பை அறிவிக்கப் போகிறோம். வெளிப்படையாக, நீங்கள் அதை விரும்பவில்லை என்றால், நீங்கள் ND :: ISR :: ISR1 அல்லது அது போன்ற ஏதாவது ஒன்றை கர்னல் பீதியை அழைக்கலாம். இந்த அமைப்பு ஒரு வடிவத்தைக் கொண்டுள்ளது:
struct regs{
uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
};
இறுதியாக நாம் ND_ISR_Handler செயல்பாட்டை (ஒரு சி இணைப்புடன்) செய்கிறோம், அதில் நாம் ஒரு கர்னல் பீதியையும் பிழைகள் பற்றிய சிறிய விளக்கத்தையும் காண்பிப்போம்.
extern "C"
void ND_ISR_Handler(struct regs *r)
{
if(r->int_no < 32) { ND::Panic::Show(exception_messages[r->int_no]);
for(;;);
}
}
நல்லது, இதன் மூலம் இந்த குறுக்கீட்டை நாம் ஏற்கனவே கையாள முடிந்தது. மீதமுள்ள குறுக்கீடுகளுடன் இது ஒத்ததாக இருக்கும், தவிர சில அளவுருக்கள் உள்ளன, அதைப் பெறுவதற்கு ரெக் கட்டமைப்பைப் பயன்படுத்துவோம். இருப்பினும், இது உண்மையிலேயே செயல்படுகிறதா என்பது எங்களுக்கு எப்படித் தெரியும் என்று நீங்கள் ஆச்சரியப்படலாம். இது வேலைசெய்கிறதா என்று சோதிக்க, ND :: IDT :: நிறுவு () க்குப் பிறகு ஒரு எளிய வரியை அறிமுகப்படுத்த உள்ளோம்:
int sum=10/0;
நாங்கள் தொகுத்தால் அது எங்களுக்கு ஒரு எச்சரிக்கையைத் தரும், அதை இயக்க முயற்சித்தால் நமக்கு ஒரு நல்ல திரை கிடைக்கும்:
இந்த இடுகையை இது முடிக்கும்போது, இது மிகவும் விரிவான ஆனால் மிகவும் செயல்பாட்டுக்குரியது என்று நான் நினைக்கிறேன்.
நான் எல்.எஃப்.எஸ் க்கு மாறினேன், அது மிகவும் தொடர்ச்சியானது.
புனித ... எப்படியும், பயிற்சிகள் நல்லது.
மிகவும் நல்லது, நான் ஆரம்பத்தில் இருந்தே அதைப் பின்பற்றி வருகிறேன். ஒவ்வொரு டிரெய்லருக்கும் குறியீடுகளை இணைக்க முடியுமா?
கிட்ஹப்பில் எல்லா மூலக் குறியீடும் உங்களிடம் உள்ளது: http://github.com/AdrianArroyoCalle/next-divel அங்கிருந்து நீங்கள் ஒரு ஜிப், ஒரு TAR.GZ ஐ பதிவிறக்கம் செய்யலாம் அல்லது கிட் பயன்படுத்தலாம்.
ஹஹாஹா மிகவும் நல்லது! ஒப்புதல்! 🙂