《Linux內核分析》第六週學習總結

《Linux內核分析》第六週學習總結node

                        ——進程的描述和進程的建立linux

姓名:王瑋怡  學號:20135116shell

1、理論部分數據結構

(一)進程的描述函數

一、進程描述符task_stuck數據結構(一)學習

操做系統三大功能:進程管理(核心)、內存管理、文件系統spa

PCB task_struct中包含:進程狀態、進程打開的文件、進程優先級信息操作系統

進程控制塊PCB——進程描述符task_stuck提供了內核所需瞭解的進程信息線程

Linux進程狀態轉換圖:3d

二、進程描述符task_stuck數據結構(二)

  內核把進程的列表存放在任務隊列的雙向循環鏈表中

(1)非空雙向鏈表結構

(2)空雙向鏈表結構

 

(3)進程父子關係

(二)進程建立

一、進程的建立概覽及fork一個進程的用戶態代碼

(1)進程的建立:start_kernel ...cpu_idle -->kernel_init和kthreadd -->0、一、2號進程(其中1號進程是全部用戶線程的祖先,2號進程是全部內核線程的祖先)

(2)fork()系統調用:在用戶態建立一個子進程

  else if和else都會被執行:fork系統調用在父進程和子進程中各會返回一次,在子進程中pid的返回值爲0,在父進程中的返回值爲子進程的pid。

二、理解進程建立過程發雜代碼的方法

 

建立新進程是經過複製當前進程來實現的,父、子進程大多數信息相同,但有些不一樣,如pid、內核堆棧等,而且只複製了一部分(內核堆棧棧底內容,SAVE_ALL部分)。

三、瀏覽建立進程的相關關鍵代碼

(1)系統調用內核處理函數sys_fork、sys_clone、sysvfork:

fork、vfork和clone三個系統調用均可以建立一個新進程,並且都是經過調用do_fork來實現進程的建立。

(2)do_fork()

(3)copy_procrss()中dup_task_stuck()複製PCB

(4)alloc_thread_info_node()分配內核堆棧空間

(5)copy_thread()中

  • struct pt_regs *childregs = task_pt_regs(p);  //從子進程的pid(stack內核堆棧)找到其棧空間,SAVE_ALL地址
  • *childregs = *current_pt_regs();  //拷貝當前進程(父進程)的內核堆棧的棧底(SAVE_ALL)的內容,內核堆棧已有數據的拷貝

四、建立的新進程是從哪裏開始執行的

  p->thread.ip = (unsigned long) ret_from_fork;  //調度到子進程時的第一條指令

當子進程得到CPU的控制權開始運行, ret_from_fork可使其出棧從iret返回到子進程用戶態。

 

2、實驗部分:使用gdb跟蹤建立新進程的過程

一、啓動MenuOS,並查看fork功能:

二、gdb調試fork指令

(1)qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

(2)在新打開的shell窗口中進程調試:

 (3)設置斷點

(4)在MenuOS中執行fork,就會發現fork函數停在了父進程中 

(5)繼續執行以後,停在了do_fork的位置

而後n單步執行,依次進入copy_process、dup_task_struct

按s進入該函數,能夠看到dst = src(也就是複製父進程的struct)

(6)在copy_thread中,能夠看到把task_pg_regs(p)也就是內核堆棧特定的地址找到並初始化

3、總結

  Linux經過複製父進程來建立一個新進程,經過調用do_ fork來實現,併爲新建立的進程動態分配一個task_ struct結構。

相關文章
相關標籤/搜索