[关闭]
@xiaoxiang 2015-03-16T12:39:47.000000Z 字数 1792 阅读 1914

从一个简单的时间片轮转多道程序内核代码理解Linux内核调度

Linux内核分析


by 赵缙翔

原创作品转载请注明出处

《Linux内核分析》MOOC课程——孟宁

还是新手,如有疏漏,还请指教。

内核简介

Linux是一种开源电脑操作系统内核。它是一个用C语言写成,符合POSIX标准的类Unix操作系统。

内核主要包括了以下几个功能部分:

这次,我们来做个实验对其进程管理,做个简单的时间片轮转多道程序理解它。

mykernel的时间片轮转多道程序内核代码

mykernel源码在github上:mykernel。核心代码在三个文件中,其主要功能如下:

修改后执行shell命令

  1. make allnoconfig
  2. make
  3. qemu -kernel arch/x86/boot/bzImage

可以看到n个进程的PCB组成循环链表,按序被调度,一个进程执行一段时间,进入my_schedule让出CPU,下个进程继续占用CPU,时间中断my_timer_handlemy_need_sched设为1是进入调度的必要条件

my_start_kernel中启动第一个进程的代码:

  1. asm volatile(
  2. "movl %1,%%esp\n\t" /* set task[pid].thread.sp to esp */
  3. "pushl %1\n\t" /* push ebp */
  4. "pushl %0\n\t" /* push task[pid].thread.ip */
  5. "ret\n\t" /* pop task[pid].thread.ip to eip */
  6. "popl %%ebp\n\t"
  7. :
  8. : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp) /* input c or d mean %ecx/%edx*/
  9. );

进程调度时的关键代码:

  1. if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */
  2. {
  3. /* switch to next process */
  4. asm volatile(
  5. "pushl %%ebp\n\t" /* save ebp */
  6. "movl %%esp,%0\n\t" /* save esp */
  7. "movl %2,%%esp\n\t" /* restore esp */
  8. "movl $1f,%1\n\t" /* save eip */
  9. "pushl %3\n\t"
  10. "ret\n\t" /* restore eip */
  11. "1:\t" /* next process start here */
  12. "popl %%ebp\n\t"
  13. : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
  14. : "m" (next->thread.sp),"m" (next->thread.ip)
  15. );
  16. my_current_task = next;
  17. printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
  18. }
  19. else
  20. {
  21. next->state = 0;
  22. my_current_task = next;
  23. printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
  24. /* switch to new process */
  25. asm volatile(
  26. "pushl %%ebp\n\t" /* save ebp */
  27. "movl %%esp,%0\n\t" /* save esp 保存旧进程的ebp和esp*/
  28. "movl %2,%%esp\n\t" /* restore esp */
  29. "movl %2,%%ebp\n\t" /* restore ebp。 esp 和ebp都指向新进程的栈底*/
  30. "movl $1f,%1\n\t" /* save eip 。 前一个进程的下一条执行命令是上面标号1的pop ebp*/
  31. "pushl %3\n\t"
  32. "ret\n\t" /* restore eip 。 开始调度新进程*/
  33. : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
  34. : "m" (next->thread.sp),"m" (next->thread.ip)
  35. );
  36. }

抱歉啊,稍后更新……我先去赶一大堆作业了,by苦逼大二狗

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注