linux精簡作業系統設計**
一、 準備工作
1、標頭檔案mypcb.h:/*
* linux/mykernel/mypcb.h
** kernel internal pcb types**
*/#define max_task_num 4
#define kernel_stack_size 1024*8
/* cpu-specific state of this task */
struct thread ;
typedef struct pcbtpcb;
voidmy_schedule(void);
2、mymain.c程式模組/*
* linux/mykernel/mymain.c
** kernel internal my_start_kernel**
*/#include
#include
#include
#include
#include
#include "mypcb.h"
tpcb task[max_task_num];
tpcb * my_current_task = null;
volatile int my_need_sched = 0;
void my_process(void);
void __init my_start_kernel(void)
/* start process 0 bytask[0] */
pid = 0;
my_current_task =&task[pid];
asm volatile(
"movl %1,%%esp\n\t" /*set task[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*/
);}
void my_process(void)
printk(kern_notice "this is process %d+\n",my_current_task->pid);
} }}
3、myinterrupt.c程式模組/*
* linux/mykernel/myinterrupt.c
** kernel internal my_timer_handler**
*/#include
#include
#include
#include
#include
#include "mypcb.h"
extern tpcb task[max_task_num];
extern tpcb * my_current_task;
extern volatile int my_need_sched;
volatile int time_count = 0;
/** called by timer interrupt.
* it runs in the name ofcurrent running process,
* so it use kernel stack ofcurrent running process
*/void my_timer_handler(void)
time_count ++ ;
#endif
return;
}void my_schedule(void)
printk(kern_notice">>>my_schedule<<<\n");
/* schedule */
next =my_current_task->next;
prev = my_current_task;
if(next->state == 0)/*-1 unrunnable, 0 runnable, >0 stopped */
else
return;
}二、程序的啟動
程序的啟動是在mymain.c模組中的my_start_kernel函式。其中內嵌彙編**部分是程式啟動的關鍵:
程式剛開始啟動時只有0號程序即pid=0.
/* start process 0 by task[0] */
pid = 0;
my_current_task =&task[pid];
asm volatile(
"movl %1,%%esp\n\t" /*set task[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*/
);其中movl %1,%%esp\n\t 是將task[0].thread.sp賦給esp暫存器,即將0號程序的棧空間的棧頂指標賦給esp暫存器;
pushl %1\n\t 是將ebp壓棧;
"pushl %0\n\t" 是將task[0].thread.ip壓棧,即將my_process函式位址壓棧;
"ret\n\t" 是將task[0].thread.ip 彈出棧並賦給eip暫存器,此時eip暫存器指向my_process的位址,程式開始轉向my_process函式執行。此時完成了啟動0號程序的工作,my_process函式中含有無限迴圈**while(1),每迴圈10000000次執行一次如下**:「printk(kern_notice "this is process %d-\n",my_current_task->pid」,然後檢驗排程函式狀態變數my_need_sched,如果該變數為1,則執行排程函式my_schedule,否則繼續while迴圈塊。my_need_sched是個volatile型的int變數,被初始化為0狀態。my_need_sched變數值的改變是由於時鐘中斷機制週期性性執my_time_handler中斷處理程式,執行完後中斷返回總是可以回到my_start_kernel中斷的位置繼續執行。
"popl %%ebp\n\t" 是將原來ebp內容出棧講給ebp暫存器。
三、程序的切換
當my_need_sched=1時,執行執行緒切換程式my_schedule函式。當第一次切換至某個程序時,執行my_schedule函式中的else語句,此時儲存當前程序的堆疊及執行的下條指令的eip到相應的記憶體空間。然後重置eip暫存器的值為下個程序的my_process函式的開始位址。之後的程序切換都呼叫my_schedule 函式中的if分支,同理儲存當前程序的堆疊及eip值到相應的記憶體,然後將下乙個程序的上次執行的下一條指令的地值賦給eip暫存器。從而完成了程序的切換。
四、總結
從以上可以看出,程序上下文切換及中斷上下文切換在作業系統中占有很重要的地位,以上僅僅分析了程序上下文切換過程。
作業系統之程序切換
最近複習作業系統關於程序切換的一些記錄。程序切換指從正在執行的程序中收回處理器,讓待執行程序來占有處理器執行。實質上就是被中斷執行程序與待執行程序的上下文切換。二 模式切換 程序切換必須在作業系統核心模式下完成,這就需要模式切換。模式切換又稱處理器切換,即使用者模式和核心模式的互相切換。1 中斷 異...
作業系統的多程序組織 程序間切換
使用者使用計算機就是啟動了一堆程序 使用者管理計算機就是管理這一堆程序 即根據pcb 根據狀態形成不同的佇列放在不同的位置。多個程序如何組織呢?用pcb放在不同的佇列中 就緒 阻塞 用狀態轉化來推進多個程序的執行 排程選擇下乙個程序,得到下乙個程序的pcb,把上乙個程序的執行現場儲存起來,把下乙個程...
作業系統 程序
在作業系統中,作業系統將記憶體,網路,檔案系統抽象為資源的統一抽象表示。1 什麼是程序 程序就是進入記憶體中正在執行的程式。把程序當做一組元素組成的實體。程序包括兩個部分,一部分是 部分,另一部分是 相關的資料集合。程序控制塊 每乙個程序,在核心中都對應著乙個程序控制塊。程序控制塊中儲存著程序的所有...