Linux内核学习系列(2)——时间片轮转与任务切换

前言

上一篇文章,通过系统调用引出了中断以及分段机制和保护模式相关内容,并进行了简单说明。本篇将在中断基础上,从时间片轮转和任务切换的角度切入,进一步地探究linux内核。

时间片轮转

时间片轮转是操作系统实现并发的方式,简单地说,操作系统为每个进程分配一定的时间片,当前进程的时间片用尽,则切换到下一个就绪进程进行执行。实现时间片轮转的方式很容易想到,根据上一篇举例的时钟中断,我们可以设计实现如下

  1. 设置定时芯片隔N毫秒发出时钟中断
  2. 设计时钟中断的执行程序完成以下步骤
    • 获取当前任务结构
    • 将当前任务时间片-1
    • 判断当前任务时间片是否剩余
    • 若时间片有剩余,则中断返回,继续执行当前任务
    • 若时间片用尽,则根据CPL权限标志判断当前任务为内核任务,还是用户任务
    • 若为内核任务,直接中断返回。(因为内核任务不允许被抢占)
    • 若为用户任务,则执行任务调度,完成任务切换
  3. 将设计好的中断程序与时钟中断向量号绑定。即修改idt

实际上,linux内核也是这么干的。根据源码,可以进行印证。
设置定时芯片隔N毫秒发出时钟中断 kernel\sched.c

 // 下面代码用于初始化 8253 定时器。通道 0,选择工作方式 3,二进制计数方式。通道 0 的
 // 输出引脚接在中断控制主芯片的 IRQ0 上,它每 10 毫秒发出一个 IRQ0 请求。LATCH 是初始
 // 定时计数值。
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */ // 定时值低字节。
outb(LATCH >> 8 , 0x40); /* MSB */ // 定时值高字节。

将设计好的中断程序与时钟中断向量号绑定。即修改idt kernel\sched.c

	set_intr_gate(0x20,&timer_interrupt);

设计时钟中断的执行程序 kernel\system_call.s

_timer_interrupt:
	push %ds		# save ds,es and put kernel data space
	push %es		# into them. %fs is used by _system_call
	push %fs
	pushl %edx		# we save %eax,%ecx,%edx as gcc doesn't
	pushl %ecx		# save those across function calls. %ebx
	pushl %ebx		# is saved as we use that in ret_sys_call
	pushl %eax
	movl $0x10,%eax
	mov %ax,%ds
	mov %ax,%es
	movl $0x17,%eax
	mov %ax,%fs
	incl _jiffies //自加自身
	movb $0x20,%al		# EOI to interrupt controller #1
	outb %al
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值