韩岩___第2课___《linux内核分析》MOOC课


题目:简单的时间片轮转多道程序内核代码

一、简单的时钟中断程序

1、代码mymain.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#include

#include

#include

#include

#include

 

#ifdefCONFIG_X86_LOCAL_APIC

#include

#endif

 

void__init my_start_kernel(void)

{

    int i = 0;

    while(1)

    {

        i++;

        if(i%10000000 == 0)

            printk(KERN_NOTICE"my_start_kernel here  %d\n",i);

           

    }

}

2、myinterupt.c程序代码如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#include

#include

#include

#include

#include

 

#defineCREATE_TRACE_POINTS

#include

 

/*

 * Called by timer interrupt.

 */

voidmy_timer_handler(void)

{

      printk(KERN_NOTICE"\n>>>>>my_timer_handler here<<<<<\n\n");

}

3、运行结果:

韩岩___第2课___《linux内核分析》MOOC课_第1张图片

二、简单的时间片轮转多道程序

1、mypcb.h

#defineMAX_TASK_NUM        4

#defineKERNEL_STACK_SIZE   1024*8

 

/*CPU-specific state of this task */

structThread {

    unsigned long                  ip;

    unsigned long                  sp;

};

 

typedefstruct 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;

 

voidmy_schedule(void);

以上程序的结构为:

结构体包括:

Ø  1个pid位

Ø  1个state位

Ø  1个堆栈

Ø  1个线程(包括ip、sp)

Ø  1个入口与1个next位

 

2、mymain.c

#include

#include

#include

#include

#include

 

 

#include"mypcb.h"

 

tPCBtask[MAX_TASK_NUM];

tPCB *my_current_task = NULL;

volatileint my_need_sched = 0;

 

voidmy_process(void);

 

 

void__init my_start_kernel(void)

{

    int pid = 0;

    int i;

    /* Initialize process 0*/

    task[pid].pid = pid;

    task[pid].state = 0;/* -1 unrunnable, 0runnable, >0 stopped */

    task[pid].task_entry = task[pid].thread.ip= (unsigned long)my_process;

    task[pid].thread.sp = (unsignedlong)&task[pid].stack[KERNEL_STACK_SIZE-1];

    task[pid].next = &task[pid];

    /*fork more process */

    for(i=1;i

    {

       memcpy(&task[i],&task[0],sizeof(tPCB));

        task[i].pid = i;

        task[i].state = -1;

        task[i].thread.sp = (unsignedlong)&task[i].stack[KERNEL_STACK_SIZE-1];

        task[i].next = task[i-1].next;

        task[i-1].next = &task[i];

    }

    /* start process 0 by task[0] */

    pid = 0;

    my_current_task = &task[pid];

asm volatile(

       "movl%1,%%esp\n\t"          /* settask[pid].thread.sp to esp */

       "pushl%1\n\t"            /* push ebp */

       "pushl%0\n\t"            /* push task[pid].thread.ip */

       "ret\n\t"                /* pop task[pid].thread.ip to eip*/

       "popl%%ebp\n\t"

       :

       :"c" (task[pid].thread.ip),"d" (task[pid].thread.sp)     /* input c or d mean %ecx/%edx*/

);

}  

voidmy_process(void)

{

    int i = 0;

    while(1)

    {

        i++;

        if(i%10000000 == 0)

        {

            printk(KERN_NOTICE "this isprocess %d -\n",my_current_task->pid);

            if(my_need_sched == 1)

            {

                my_need_sched = 0;

                my_schedule();

            }

            printk(KERN_NOTICE"this is process %d +\n",my_current_task->pid);

        }    

    }

}

韩岩___第2课___《linux内核分析》MOOC课_第2张图片

韩岩___第2课___《linux内核分析》MOOC课_第3张图片

 

3、myinterrupt.c

#include

#include

#include

#include

#include

 

#include"mypcb.h"

 

externtPCB task[MAX_TASK_NUM];

externtPCB * my_current_task;

externvolatile int my_need_sched;

volatileint time_count = 0;

 

/*

 * Called by timer interrupt.

 * it runs in the name of current runningprocess,

 * so it use kernel stack of current runningprocess

 */

voidmy_timer_handler(void)

{

#if 1

    if(time_count%1000 == 0 &&my_need_sched != 1)

    {

        printk(KERN_NOTICE">>>my_timer_handler here<<<\n");

        my_need_sched = 1;

    }

    time_count ++ ; 

#endif

    return;       

}

 

voidmy_schedule(void)

{

    tPCB * next;

    tPCB * prev;

 

    if(my_current_task == NULL

        || my_current_task->next == NULL)

    {

       return;

    }

    printk(KERN_NOTICE">>>my_schedule<<<\n");

    /* schedule */

    next = my_current_task->next;

    prev = my_current_task;

    if(next->state == 0)/* -1 unrunnable, 0runnable, >0 stopped */

    {

       /*switch to next process */

       asmvolatile(       

            "pushl%%ebp\n\t"          /* save ebp */

            "movl%%esp,%0\n\t"          /* save esp */

            "movl%2,%%esp\n\t"     /* restore  esp */

            "movl$1f,%1\n\t"       /* save eip */ 

            "pushl%3\n\t"

            "ret\n\t"                /* restore  eip */

            "1:\t"                  /* next process start here */

            "popl%%ebp\n\t"

            :"=m" (prev->thread.sp),"=m" (prev->thread.ip)

            :"m" (next->thread.sp),"m" (next->thread.ip)

       );

       my_current_task= next;

       printk(KERN_NOTICE">>>switch %d to%d<<<\n",prev->pid,next->pid);     

    }

    else

    {

        next->state = 0;

        my_current_task = next;

        printk(KERN_NOTICE">>>switch %d to%d<<<\n",prev->pid,next->pid);

       /*switch to new process */

       asmvolatile(       

            "pushl%%ebp\n\t"          /* save ebp */

            "movl%%esp,%0\n\t"          /* save esp */

            "movl%2,%%esp\n\t"     /* restore  esp */

            "movl%2,%%ebp\n\t"     /* restore  ebp */

            "movl$1f,%1\n\t"       /* save eip */ 

            "pushl%3\n\t"

            "ret\n\t"                /* restore  eip */

            :"=m" (prev->thread.sp),"=m" (prev->thread.ip)

            :"m" (next->thread.sp),"m" (next->thread.ip)

       );         

    }  

    return; 

}

韩岩___第2课___《linux内核分析》MOOC课_第4张图片

4、编译以上代码:

gcc–c 文件名.c 生成目标文件后

cdLinuxKernel/linux-3.9.4

qemu-kernel arch/x86/boot/bzImage

韩岩___第2课___《linux内核分析》MOOC课_第5张图片

 

你可能感兴趣的:(liunx)