Note 2: From Dynamics and Static, Tracking the MiniX Interrupt Procedure

xiaoxiao2021-03-06  46

Ricky zhangrickycheung@21cn.com2005-2-141, experimental purpose: Understand how Minix encapsulates interrupt calls, and fuses with the kernel messaging mechanism. 2, experiment objective: dynamically track: On Bochs, the HWINT_MASTER01 breakpoint of the system's keyboard interrupt call code / kernel/mpx386.s, renew, and resume. Static tracking: Interrupt from the system has the source code, / kernel / mpx386.s, / kernel / proc.c3, experimental steps: dynamic tracking notes: 1. Upload Minix's kernel image (/ miniX / xxx) to Windows Use any anti-compiler to disassemble (Debug can also, but I use W32DASM).

Use STI to find the hwout_master01 code segment of /kernel/mpx386.s, the source code is used in the source code ---------------- / kernel / mpx386.s hwint_master01 Code segment -----------------------------! * =============== ============================================================================================================================================================================================================= ========== *! * Hwint00 - 07 *! * ================================ ===================================================== *! Note this is a Macro, IT Looks Like a Subroutine. # Define Hwint_master (IRQ) / Call Save / * Save Interrupted Process State * /; / INB INT_CTLMASK; / ORB AL, [1 << Irq]; / OUTB IRQ * /; / MOVB AL, ENABLE; / OUTB INT_CTL / * Reenable Master 8259 * /; / 459 * /; /; /; (* IRQ_TABLE [IRQ]) (IRQ) * /; / POP ECX; / CLI / * Disable Interrupts * /; / TEST EAX, EAX / * NEED TO Reenable Irq? * /; / jz 0f; / Inb INT_CTLMASK; / Andb Al, ~ [1 << Irq]; / OUTB INT_CTLMASK / * Enable the Irq * /; / 0: Ret / * R ESTART (Another) Process * /

! Each of these entry points is an expansion of the hwint_master macro .align 16_hwint00: Interrupt routine for irq 0 (the clock) hwint_master (0) .align 16_hwint01: Interrupt routine for irq 1 (keyboard) hwint_master (1) -!.! -------------------------------------------------- -------------------------------------------------- ------------------------------- Correspondence / kernel/mpx386.s The HWINT_MASTER01 core image Results of the HWINT_MASTER01: 000002F1 E8CB020000 call 000005C1: 000002F6 E421 in al, 21: 000002F8 0C02 or al, 02: 000002FA E621 out 21, al: 000002FC B020 mov al, 20: 000002FE E620 out 20, al: 00000300 FB sti: 00000301 6A01 push 00000001: 00000303 FF15C86C0000 Call Dword PTR [00006CC8]: 000000001000303315: IN Al, 21: 00000311 24fd and al, fd: 00000313 E621 OUT 21, Al: 00000315 C3 RET

00000000-00-00 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 BYTE 10 DUP (0)

00000320 00--------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------------------------- 2, mention from note, by secondary boot, MINIX image Document (under / minix), loaded into memory physical 0x00800 addresses (source code in /boot/boot.h under /boot/boot.h under /boot/boot.h)) 3, use Bochs's Debug Function bochsdbg, add a physical address breakpoint because the MiniX image is 0x00800 in memory, and the offset of hwint_master01 is 0x000002F1 (the head inside with a.out.h, for some minus 200h) , So the physical start address of HWINT01 in memory is 0x00800 0x002f1-200h-1h = 0x8f0 in the background of Bochs, press Ctrl C, stop PB 0x08F0 // Physical address breakpoint C // Continue4, return to minix, freely pressing a foreign key 5, bochs automatically enters Debug (0) Breakpoint 4, 0x8f0 in ?? () Next At t = 2340001600 (0) [0x000008F0] 0030: 000000F0 (UNK. CTXT) : Call 0x3c0; E8CB020000 6, start entering the HWINT01 interrupt fall section. 7, check the register (0) [0x000008F0] 0030: 000000F0 (UNK. CTXT): Call 0x3c0; e8cb0200 00 INFO R EAX 0x0 0 ECX 0x0 0 EDX 0X 0 EBX 0x0 0 ESP 0x735C 0x735C EBP 0x0 0x0 ESI 0x0 0 EDI 0X0 0 EIP 0xF0 0xF0 EFLAGS 0x2 2 CS 0x30 48 SS 0x18 24 DS 0xF 15 ES 0xF 15 FS 0xF 15 GS 0xF 15 Register Table 1 S Next At t =

468489601 (0) [0x00000BC0] 0030: 000003C0 (UNK. CTXT): CLD; FS INFO R EAX 0x0 0 ECX 0x0 0 ESP 0x0 0 EBX 0x0 0 EBP 0x7358 0x7358 EBP 0x0 0x0 ESI 0x0 0 EDI 0x0 0 EIP 0x3c0 0x3c0 EFLAGS 0X2 2 CS 0x30 48 SS 0x18 24 DS 0xF 15 ES 0xF 15 FS 0xF 15 GS 0xF 15 Register Table 2 Note: Call instruction, make ESP subtracted = 0x735c-0x7358 = 4 (byte) U / 40 0xBC0 00000BC0: (): CLD; FC 00000BC1: (): Pushhad; 60 00000BC2: (): Opsize Push DS; 661E 00000BC4: (): Opsize Push ES; 6606 00000BC6: (): Opsize push fs; 660fa0 00000bc9: (): Opsize push gs; 660fa8 00000bcc: (): MOV DX, SS; 8CD2 00000BCE: (): MOV DS, DX; 8eda 00000BD0: (): MOV ES, DX; 8EC2 00000BD2: (): MOV EAX, ESP; 89E0 00000BD4: (): increst PTR [DS: 0x6C58]; Fe05586C0000 00000BDA: (): JNZ 0xBEC; 7510 00000BDC: (): MOV ESP, 0x2FF8; BCF82F0000 00000Be1 : (): Push 0x433;

6833040000 00000Be6: (): xor EBP, EBP; 31ed 00000Be8: (): JMP DWORD PTR DS: [EAX 0x28]; FF6028 byte alignment (4 integrity .align 4) 00000BEC: (): push 0x455; 6855040000 00000BF1: (): JMP DWORD PTR DS: [EAX 0x28]; FF6028 Note: Pushhao is equivalent to TEMP ← (ESP); Push (EAX); Push (ECX); Push (EDX); Push (EBX); Push (TEMP); Push (EBP); Push (ESI); Push (EDI); put DS, ES, FS, GS, and stack. The last four total 2 * 4 = 8Byte, the PUSHAD has a stack size of 8 * 4 = 32byte. Therefore, Total is 0x28 (40D), so the address of JMP DWORD PTR DS: [EAX 0x28] is saved by CS: IP. With SAVE / Kenel/mpx386.s, SAVE comparison! * == ============================================================================================================================================================================================================= ======================== *! * Save *! * ====================== ============================================================================================================================================================================================================= ===== *! Save for protected mode.! This is much simpler Than for 8086 Mode, Because The Stack ALREADY POINTS! INTO The Process Table, or Has Already Been Switch To The Kernel Stack.

.align 16SAVE: CLD! SET DIRECTION FLAG TO A KNOWN VALUE PUSHAD! Save "General" Registers O16 Push DS! Save DS O16 Push ES! SAVE ES O16 PUSH FS! SAVE FS O16 PUSH GS! SAVE GS MOV DX, SS! SS IS KERNEL DATA Segment Mov DS, DX! Load Rest of Kernel Segments Mov ES, DX! KERNEL DOES NOT USE FS, GS MOV EAX, ESP! PREPARE TO RETURN INCB (_K_REENTER)! from -1 if not Reentering jnz set_restart1! Stack IS already kernel stack mov esp, k_stktop push _restart build return address for int handler xor ebp, ebp for stacktrace jmp RETADR-P_STACKBASE (eax) .align 4set_restart1:!! push restart1 jmp RETADR-P_STACKBASE (eax)

From the code, save the restore work divided, one is that there is no interrupt that has not been nested yet, and the other is an interrupted interrupt. The former should first restore the use of the Kernel stack, then let the _Restart get back to the interrupt to make a recovery work and call the un_hold in /proc.c, activate the hangful other interrupt routines. The latter only puts the restart1 in the stack, and then makes recovery after the interrupt is completed. The last two use JMP RetAdr-P_StackBase (EAX) to return to the code after Save.

The following is a dynamic debug result: single step to 0xBD4 (0) [0x00000BD4] 0030: 000003D4 (unk. Ctxt): increst PTR [DS: 0x6c58]; Fe05586C0000 x / b 0x18: 0x6c58 [bochs] : 0x00017558 : 0xff :解: Incb (_K_REENTER), _ k_reenter record interrupt nesting number. If _k_reenter is -1 (0xFF is the complement of -1), it is 0 after the INC instruction is executed, and the current is not nested and the stack is not a kernel's stack, and the ESP refers back to the kernel stack, using the Kernel Stack and then restore the recovery The register work is transferred to the _Restart's address into the kernel stack, and after the interrupt work is completed, the re-adjustment _Restart

MOV ESP, K_STKTOP PUSH _RESTART! Build Return Address for int handler The following is the _Restart program! * ================================ ============================================== *! * Restart *! * =============================================================================================================================================== =========================================== Reenter.! this does not matter, Because The Current Handler Is About To EXIT AND NO! Other Handlers Can Renerness Flushing is Only Done When K_Reenter == 0.

! Cmp (_held_head), 0 do fast test to usually avoid function call jz over_call_unhold call _unhold this is rare so overhead acceptableover_call_unhold:! Mov esp, (_proc_ptr) will assume P_STACKBASE == 0 lldt P_LDT_SEL (esp) enable segment descriptors for!! task lea eax, P_STACKTOP (esp) arrange for next interrupt mov (_tss TSS3_S_SP0), eax to save state in process tablerestart1:!! decb (_k_reenter) o16 pop gs o16 pop fs o16 pop es o16 pop ds popad add esp, 4 ! SKIP RETURN ADR IRETD! Continue Process Note: When k_reenter == 0, when the nested weight is 0, the UNHOLD routine of the proc.c is called, activating the suspended interrupt routine. Otherwise, the current stack is the Kernel stack, jump directly to set_restart1, and the recovery register works to the address of Restart1 PUSH to the stack, and after the interrupt is completed, execute. Restart1: decB (_K_REENTER) O16 POP GS O16 POP FS O16 POP ES O16 POP DS POPAD Add ESP, 4! Skip Return ADR IRETD! Continue Process Continue Dynamic debug, single step to return 00000Be8: (): JMP DWORD PTR DS: [EAX 0x28]; FF6028 S next at t = 468489616 (0) [0x00000Be8] 0030: 000003E8 (UNK. CTXT): JMP DWORD PTR DS: [EAX 0x28]; ff6028

Info R EAX 0x7330 29488 ECX 0x0 0 EDX 0x18 24 EBX 0x0 0 ESP 0x2FF4 0x2FF4 EBP 0x0 0x0 ESI 0x0 0 EDI 0x0 0 EIP 0x3E8 0x3E8 EFLAGS 0X42 66 CS 0x30 48 SS 0x18 24 DS 0x18 24 ES 0x18 24 FS 0xF 15 GS 0xF 15 x 0x18: 0x7358 0x00017c58 : 0x000000F5

Note: So the return IP is 0xF5, so CS is 0x30, jumps back 0x30: 0xF5 (currently protecting mode) Calc 0x30: 0xf50x8f5 2293 Jumped physical address 0x8f5 ------- ------------------------ HWINT01 memory anti-assembly results U / 25 0x8F0000008F0: (): CALL 0XBC0; E8CB020000000008F5: () : in Al, 0x21; E421000008F7: (): OR Al, 0x2; 0C02000008F9: (): OUT 0X21, Al; E621000008FB: (): MOV Al, 0x20; B020000008FD: (): OUT 0x20, Al; E620000008FF: () : STI; FB00000900: (): push 0x1; 6a0100000902: (): Call DWORD PTR [DS: 0x6cc8]; FF15C86C0000 // Call Keyboard interrupt routine 00000908: (): POP ECX; 5900000909: (): CLI; FA0000090A : (): Test Eax, EAX; 85C00000090C: : JZ 0x914; (): in Al, 0x21; E42100000910: (): And Al, 0xFD; 24FD00000912: (): OUT 0X21, Al; E62100000914: (): Retn; C3 ------- -------------------------------------------------- ------------------------ (to expand)

转载请注明原文地址:https://www.9cbs.com/read-58388.html

New Post(0)