การจำลอง Linus Torvalds: สร้างระบบปฏิบัติการของคุณเองจาก 0 (V)

ในงวดที่ห้านี้เราจะเห็นตารางที่ค่อนข้างคล้ายกับ GDT ทั้งในทางทฤษฎีและในการใช้งานเราอ้างถึง IDT IDT ย่อมาจาก ตารางคำอธิบายขัดจังหวะ y คือตารางที่ใช้จัดการกับการขัดจังหวะที่เกิดขึ้น ตัวอย่างเช่นมีคนหารด้วย 0 ฟังก์ชันที่รับผิดชอบในการประมวลผลจะถูกเรียกใช้ ฟังก์ชันเหล่านี้คือ ISR (ขัดจังหวะบริการตามปกติ). มาสร้าง IDT และเพิ่ม ISR

ก่อนอื่นเราจะประกาศโครงสร้างที่สอดคล้องกับ 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));

ดังจะเห็นได้ว่าถ้าคุณเปรียบเทียบกับ GDT โครงสร้าง Ptr จะเหมือนกันและ Entry นั้นค่อนข้างคล้ายกัน ดังนั้นฟังก์ชั่นของการใส่รายการ (SetGate) และการติดตั้ง (Install) จึงคล้ายกันมาก

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 :: Memory :: Set ที่เราได้ประกาศไว้ในโพสต์อื่น นอกจากนี้เรายังสามารถดูว่าเราไม่ได้โทรไปยัง SetGate และเราเรียกว่า ND :: IDT :: Flush สำหรับฟังก์ชันนี้เราใช้คำสั่ง asm volatile อีกครั้ง:

asm volatile("lidtl (idtptr)");

หากทุกอย่างเป็นไปด้วยดีและเราจัดเตรียมความสวยงามควรมีลักษณะดังนี้:

ต่อไปDive-IDT

เอาล่ะมาเริ่มเติม RTD ด้วยอินเทอร์รัปต์ ที่นี่ฉันจะสร้างเพียงอันเดียว แต่สำหรับส่วนที่เหลือมันจะเหมือนเดิม ผมจะหารด้วยตัวแบ่งศูนย์ ดังที่คุณทราบกันดีในทางคณิตศาสตร์ตัวเลขไม่สามารถหารด้วย 0 ได้หากสิ่งนี้เกิดขึ้นในโปรเซสเซอร์จะมีการสร้างข้อยกเว้นเนื่องจากไม่สามารถดำเนินการต่อได้ ใน IDT อินเตอร์รัปต์แรกในรายการ (0) สอดคล้องกับเหตุการณ์นี้

เราเพิ่มสิ่งนี้ระหว่างการตั้งค่าหน่วยความจำและการล้างภายในฟังก์ชั่นติดตั้งของ IDT:

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 ในการบันทึกไฟล์และปรับปรุงความสามารถในการอ่านเราสามารถใช้« C » {} ภายนอก:

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 เพื่อเข้าถึงข้อมูลที่สร้างโดยการขัดจังหวะ เห็นได้ชัดว่าถ้าคุณไม่ต้องการแบบนั้นคุณสามารถเรียก Kernel Panic ใน 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 (รวมถึงลิงก์ C ด้วย) ซึ่งเราจะแสดงเคอร์เนลแพนิคและคำอธิบายข้อผิดพลาดเล็กน้อยตามข้อผิดพลาดที่เรามีในรายการข้อผิดพลาด

extern "C"
void ND_ISR_Handler(struct regs *r)
{
if(r->int_no < 32) { ND::Panic::Show(exception_messages[r->int_no]);
for(;;);
}
}

ดีและด้วยสิ่งนี้เราสามารถจัดการกับการหยุดชะงักนี้ได้แล้ว ด้วยการขัดจังหวะที่เหลือมันจะเกิดขึ้นคล้าย ๆ กันยกเว้นว่ามีบางพารามิเตอร์ที่ส่งคืนพารามิเตอร์และเราจะใช้โครงสร้าง reg เพื่อให้ได้มา อย่างไรก็ตามคุณอาจสงสัยว่าเรารู้ได้อย่างไรว่ามันใช้งานได้จริง เพื่อทดสอบว่ามันใช้งานได้หรือไม่เราจะแนะนำบรรทัดง่ายๆหลังจาก ND :: IDT :: Install ():

int sum=10/0;

หากเรารวบรวมมันจะทำให้เรามีคำเตือนและหากเราพยายามดำเนินการเราจะได้หน้าจอที่สวยงาม:

ต่อไปDive-ISR


และเมื่อจบโพสต์นี้ฉันคิดว่ามันเป็นหนึ่งในโพสต์ที่กว้างขวางที่สุด แต่ใช้งานได้ดีทีเดียว


แสดงความคิดเห็นของคุณ

อีเมล์ของคุณจะไม่ถูกเผยแพร่ ช่องที่ต้องการถูกทำเครื่องหมายด้วย *

*

*

  1. ผู้รับผิดชอบข้อมูล: Miguel ÁngelGatón
  2. วัตถุประสงค์ของข้อมูล: ควบคุมสแปมการจัดการความคิดเห็น
  3. ถูกต้องตามกฎหมาย: ความยินยอมของคุณ
  4. การสื่อสารข้อมูล: ข้อมูลจะไม่ถูกสื่อสารไปยังบุคคลที่สามยกเว้นตามข้อผูกพันทางกฎหมาย
  5. การจัดเก็บข้อมูล: ฐานข้อมูลที่โฮสต์โดย Occentus Networks (EU)
  6. สิทธิ์: คุณสามารถ จำกัด กู้คืนและลบข้อมูลของคุณได้ตลอดเวลา

  1.   mesodabler dijo

    ฉันเปลี่ยนมาใช้ LFS มันต่อเนื่องมากขึ้น

  2.   Eliotime3000 dijo

    ศักดิ์สิทธิ์ ... อย่างไรก็ตามบทแนะนำเป็นสิ่งที่ดี

  3.   sc dijo

    ดีมากติดตามมาตั้งแต่แรกแล้ว คุณช่วยแนบรหัสกับตัวอย่างแต่ละชิ้นได้ไหม

    1.    เอเดรียน ArroyoStreet dijo

      คุณมีซอร์สโค้ดทั้งหมดบน GitHub: http://github.com/AdrianArroyoCalle/next-divel จากนั้นคุณสามารถดาวน์โหลดไฟล์ ZIP, TAR.GZ หรือใช้คอมไพล์

  4.   เหมาะสม dijo

    ฮามาก! อนุมัติ! 🙂