冬天OS(十):外中断处理框架

--------------------------------------------------------

构建外中断处理框架

--------------------------------------------------------

我们这节试图为每个外部中断都设置相同的中断处理流程!

 

// -------------------------------------
%macro    hwint_master    1
    call    save
    in    al, INT_M_CTLMASK
    or    al, (1<<%1)
    out    INT_M_CTLMASK, al
    mov    al, EOI
    out    INT_M_CTL, al

    sti
    push     %1
    call    [irq_table + 4 * %1]
    pop    ecx

    cli
    in    al, INT_M_CTLMASK
    and    al, ~(1<<%1)
    out    INT_M_CTLMASK, al
    ret

%endmacro
// -------------------------------------

 

// -------------------------------------
save:
	pushad		; ┓
	push	ds	; ┃
	push	es	; ┣ 保存原寄存器值
	push	fs	; ┃
	push	gs	; ┛
	mov	dx, ss
	mov	ds, dx
	mov	es, dx

	mov	eax, esp			; eax = 进程表起始地址

	inc	dword [k_reenter]		; k_reenter++;
	cmp	dword [k_reenter], 0		; if(k_reenter ==0)
	jne	.1				; {
	mov	esp, StackTop			;	mov esp, StackTop <-- 切换到内核栈
	push	restart				;	push restart
	jmp	[eax + RETADR - P_STACKBASE]	;	return;
.1:						; } else { 已经在内核栈,不需要再切换
	push	restart_reenter			;	push restart_reenter
	jmp	[eax + RETADR - P_STACKBASE]	;	return;
						; }
// -------------------------------------

 

// -------------------------------------
restart:


    mov    esp, [p_proc_ready]
    lldt    [esp + P_LDT_SEL] 
    lea    eax, [esp + P_STACKTOP]
    mov    dword [tss + TSS3_S_SP0], eax

restart_reenter:
    dec    dword [k_reenter]
    pop    gs
    pop    fs
    pop    es
    pop    ds
    popad
    add    esp, 4
    iretd
// -------------------------------------
 

 分析分析:


1,内核栈只设置一次(后面的重入中断将使用这次设置的内核栈)
2,防止了同类型中断的重入
3,重入不意味着非法,而是需求
4,巧妙地解决了时钟中断和其余外部中断的共存(公用一个处理机制)

 

  • 如果当前有一个有效的时钟中断再绿色区域执行,那么时钟中断以外的所有中断都可以打断打断这个有效时钟中断,那些打断者也只在绿色的区域中执行自己类型的中断处理函数时可以被除自己类型之外的中断打断!
  • 如果当前有一个非时钟中断的有效中断在绿色区域执行,那么时钟中断进来之后将不能发生调度(发生一个无效的调度)
  • 如果当前有一个非时钟中断的有效中断在绿色区域执行,且没有其余中断打扰,那么它将执行一次非有效的任务切换(如下红色部分):

restart:
    mov    esp, [p_proc_ready]
    lldt    [esp + P_LDT_SEL] 
    lea    eax, [esp + P_STACKTOP]
    mov    dword [tss + TSS3_S_SP0], eax

restart_reenter:
 

执行结果:

 

这几句代码真的是太奇妙了,非人哉!!!下一节我们试试系统调用...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柔弱胜刚强.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值