一个简单的时间片轮转多道程序内核代码

董涛

原创作品转载请注明出处

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

本文通过编写一个简单的时间片轮转多道程序内核代码,阐述操作系统进程的启动和进程的切换机制。

首先,进入实验楼(www.shiyanlou.com)的Linux内核分析实验平台,该实验平台已经预装了部分linux操作系统的内核,主要用来初始化硬件,这部分内核在文件夹linux-3.9.4中,打开linux源代码文件夹linux-3.9.4,并进入该文件夹下的mykernel文件夹,如图所示:



在mykernel文件夹中创建头文件mypcb.h,在mypcb.h中我们主要定义了线程结构体和进程结构体,为操作系统管理线程和进程提供框架。程序源代码截图如下:

/*

* linux/mykernel/mypcb.h

*

* Kernel internal PCB types

*

* Copyright (C) 2013 Mengning

*

*/

#define MAX_TASK_NUM 4

#define KERNEL_STACK_SIZE 1024*8


/* CPU-specific state of this task */

struct Thread {

    unsigned long ip;

    unsigned long sp;

};


typedef struct PCB{

    int pid;

    volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */

    char stack[KERNEL_STACK_SIZE];

    /* CPU-specific state of this task */

    struct Thread thread;

    unsigned long task_entry;

    struct PCB *next;

}tPCB;


void my_schedule(void);


接下来,我们在mykernel文件夹中编辑操作系统的两个文件mymain.c和myinterrupt.c,mymain.c文件是操作系统函数的入口,myinterrupt.c文件实现操作系统进程之间的切换。现在我们逐个分析这两个文件中的关键代码,先看mymain.c,其关键代码截图如下所示:


在mymain.c文件中,关键内核代码是期中的汇编段,首先是把某个进程的线程栈顶指针存到esp寄存器中,第二步,将栈基址指针压入栈中,第三步,将该进程中某个线程的ip指针压入栈中,第四步,线程结束后,将该线程的ip指针出栈,第五步,该进程结束后,将基址指针出栈。

再来看myinterrupt.c文件,在myinterrupt.c文件中,关键的代码有两部分,一部分代码针对的情况是:当前进程切换到下一个进程时,下一个进程本身已经在运行,另一部分代码针对的情况是:当前进程切换到下一个进程时,下一个进程还没有运行,我们只分析第二部分的关键代码,其关键代码截图如下所示:

http://simplecloud.qiniudn.com/443962295087e8e686c60d4d2f4d6df3?watermark/1/image/aHR0cDovL3N5bC1zdGF0aWMucWluaXVkbi5jb20vaW1nL3dhdGVybWFyay5wbmc=/dissolve/60/gravity/SouthEast/dx/0/dy/10

 在myinterrupt.c文件的这部分代码中,现将当前的进程堆栈栈底和栈顶指针保存,然后调用下一个进程并运行。

总结一下:操作系统内核在对硬件完成初始化以后,搭建了堆栈的框架,并定义了程序的入口,同时实现了进程间切换的功能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值