linux 內核 第二週 操做系統是如何工做的

姬夢馨linux

原創博客shell

 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 函數

 

一:計算機的三個法寶

  • 存儲程序計算機工做模型,計算機系統最最基礎性的邏輯結構;spa

  • 函數調用堆棧,高級語言得以運行的基礎,只有機器語言和彙編語言的時候堆棧機制對於計算機來講並不那麼重要,但有了高級語言及函數,堆棧成爲了計算機的基礎功能;操作系統

    • enter rest

      • pushl %ebpcode

      •  movl %esp,%ebpblog

    • leave 進程

      • movl %ebp,%espip

      • popl %ebp

    • 函數參數傳遞機制和局部變量存儲

  • 中斷,多道程序操做系統的基點,沒有中斷機制程序只能從頭一直運行結束纔有可能開始運行其餘程序。

 

二:深刻理解函數調用堆棧

 

 

三:參數傳遞和局部變量

 

 

 

四:mykernel 實驗背後的思想和計算機環境

 利用mykernel 實驗模擬計算機平臺
1:搭建一個虛擬的平臺
2:配置系統
3:執行程序 
  中斷有了以後,就是所謂的多道程序。一個程序有本身的執行流,Cpu把當前的esp壓到另一個內核裏面去,
時鐘中斷調用程序:在系統環境裏,時間片輪轉的操做系統內核。 
 
 
 
 
 

 

五:在其基礎上簡單地操做系統實驗

 

2:兩個百分號     轉移字符

 

實驗過程及步驟

使用實驗樓的虛擬機打開shell
而後cd mykernel 您能夠看到qemu窗口輸出的內容的代碼mymain.c和myinterrupt.c

 

 

實驗代碼myinterrupt及其分析

/*

* linux/mykernel/myinterrupt.c * Kernel internal my_timer_handler * Copyright (C) 2013 Mengning */ #include <linux/types.h> #include <linux/string.h> #include <linux/ctype.h> #include <linux/tty.h> #include <linux/vmalloc.h> #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 of current running process, * so it use kernel stack of current running process */ void my_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; } void my_schedule(void) { tPCB * next; tPCB * prev; if(my_current_task == NULL //task爲空,即發生錯誤時返回 || my_current_task->next == NULL) { return; } printk(KERN_NOTICE ">>>my_schedule<<<\n"); /* schedule */ next = my_current_task->next;//把當前進程的下一個進程賦給next prev = my_current_task;//當前進程爲prev if(next->state == 0)/* -1 unrunnable, 0 runnable, >0 stopped */ { /* switch to next process */ /*若是下一個進程的狀態是正在執行的話,就運用if語句中的代碼表示的方法來切換進程*/ asm volatile( "pushl %%ebp\n\t" /* save ebp 保存當前進程的ebp*/ "movl %%esp,%0\n\t" /* save esp 把當前進程的esp賦給%0(指的是thread.sp),即保存當前進程的esp*/ "movl %2,%%esp\n\t" /* restore esp 把%2(指下一個進程的sp)放入esp中*/ "movl $1f,%1\n\t" /* save eip $1f是接下來的標號「1:」的位置,把eip保存下來*/ "pushl %3\n\t" /*把下一個進程eip壓棧*/ "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 */ asm volatile( "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; }

二、mymain.c

內核初始化和0號進程啓動

 



實驗體會:

實驗步驟雖然很簡單,但過程是很複雜的,須要本身慢慢的理解,體會。理解代碼的過程是很複雜的,須要耐心和認真。
但願本身之後分析代碼的時候可以更加的細心,認真。
相關文章
相關標籤/搜索