Linux kernel series -13.c. The process of operating system development is broken and re-entered

Source: Internet
Author: User

Now another problem arises, should the next interrupt be allowed to occur during interrupt processing?

Let's change the code so that the system can accept the next clock interrupt during the processing of the clock interrupt. It doesn't sound a good idea, but you can use it to do an experiment.

First, because the CPU shuts down interrupts automatically in response to an outage, we need to manually open the interrupt to join the STI directive, and then, to ensure that the interrupt processing process is long enough that there will be a next outage before it is complete, we call a delay function in the interrupt processing routine. The code is as follows:

externdelayhwint00:; Interrupt routine for IRQ 0 (the clock). Subesp, 4pushad; '. Pushds;  | pushes;  | Save original register value PUSHFS;  | Pushgs; /MOVDX, Ssmovds, Dxmoves, Dxmovesp, stacktop; Cut to Kernel stack incbyte [gs:0]; Change the screen No. 0 row, the character of the No. 0 column moval, EOI; `. Reenableoutint_m_ctl, AL; /  Master 8259stipushclock_int_msgcalldisp_straddesp, 4push1calldelayaddesp, 4CLIMOVESP, [P_proc_ready]; Leave the kernel stack leaeax, [esp + p_stacktop]movdword [TSS + tss3_s_sp0], Eaxpopgs; '. Popfs;  | Popes;  | Restore original register value Popds;  | Popad; /ADDESP, 4iretd

Run as follows, print "^" After printing a a0x0, and no longer into the process:

This happens because another outage occurs when an interrupt has not been processed. At this point, the program jumps to the beginning of the interrupt handler, and so on, and never executes until the end of the interrupt handler-the skip-back process continues execution.

This problem is not difficult to solve, just set a global variable on it. This global variable has an initial value of 1, and when the interrupt handler starts executing, it is self-added and ends with self-subtraction. This variable needs to be checked at the beginning of the handler, and if the value is not 0 (0=-1+1), then another interrupt occurs before the interrupt is processed, and the execution of the interrupt handler is ended by jumping directly to the end. Of course, it's not a good idea to end a new interruption arbitrarily, but let's do it first.

public int Kernel_main () {... k_reenter =-1; ...}

Then add K_reenter to the interrupt routine and determine if the code is 0:

externk_reenterhwint00:; Interrupt routine for IRQ 0 (the clock). Subesp, 4pushad; '. Pushds;  | pushes;  | Save original register value PUSHFS;  | Pushgs; /MOVDX, Ssmovds, dxmoves, Dxincbyte [gs:0]; Change the screen No. 0 row, the character of the No. 0 column moval, EOI; `. Reenableoutint_m_ctl, AL; /  Master 8259incdword [K_reenter]cmpdword [K_reenter], 0JNE.RE_ENTERMOVESP, stacktop; cut to kernel stack Stipushclock_int_ Msgcalldisp_straddesp, 4push1calldelayaddesp, 4CLIMOVESP, [P_proc_ready]; Leave the kernel stack leaeax, [esp + p_stacktop]movdword [TSS + tss3_s_sp0], eax.re_enter:; if (K_reenter! = 0), will jump to here Decdword [K_reenter]popgs; '. Popfs;  | Popes;  | Restore original register value Popds;  | Popad; /ADDESP, 4iretd

Run as follows, you can see that the character a and the corresponding numbers are constantly appearing, which shows that our changes are in effect, and the upper left corner of the screen, the letter beating speed is the same as fast as before the character "^" printing speed is much slower, indicating that there are many times the program in the Implementation of INC byte [gs:0] The DISP_STR is not executed afterwards, which also shows that interrupt re-entry does occur:

Well, we've got a way to solve the problem of interrupt re-entry, so comment out the words of the print character and the delay:

hwint00:; Interrupt routine for IRQ 0 (the clock). Subesp, 4pushad; '. Pushds;  | pushes;  | Save original register value PUSHFS;  | Pushgs; /MOVDX, Ssmovds, dxmoves, Dxincbyte [gs:0]; Change the screen No. 0 row, the character of the No. 0 column moval, EOI; `. Reenableoutint_m_ctl, AL; /  Master 8259incdword [K_reenter]cmpdword [K_reenter], 0JNE.RE_ENTERMOVESP, stacktop; cut to kernel stack Stipushclock_int_ Msgcalldisp_straddesp, 4;;; Push1;;; Calldelay;;; Addesp, 4climovesp, [P_proc_ready]; Leave the kernel stack leaeax, [esp + p_stacktop]movdword [TSS + tss3_s_sp0], eax.re_enter:; if (K_reenter! = 0), will jump to here Decdword [K_reenter]popgs; '. Popfs;  | Popes;  | Restore original register value Popds;  | Popad; /ADDESP, 4iretd

Run again, the character "^" prints faster and faster,

" Source "

Linux kernel series -13.c. The process of operating system development is broken and re-entered

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.