2018-2019-1 20189210 《LInux内核原理与分析》第六周作业
系統調用實驗(下):
將第四章的兩個實驗集成到MenuOS系統中,將其作為MenuOS系統的兩個命令,新版本的menu中已經把兩個系統調用添加進去了,只需重新克隆一個新版本的menu。
使用make rootf 打開menu鏡像,可以看到MenuOS菜單中新增了兩條命令,time和time-asm。
使用gdb跟蹤系統調用內核函數sys_time
同第二個實驗,打開gdb,在函數中設置斷點,按c繼續執行,在斷點處停下來,可以用list查看這段代碼。
(實驗樓的環境非常卡,經常崩壞)
使用s進行單步執行,會進入get_seconds()函數,使用finish將函數執行完,之后再單步執行,一直到return i代碼獲取時間數值。
繼續單步執行,將顯示Cannot find bounds of current function,這是因為sys_time返回后進入匯編代碼處理gdb無法繼續跟蹤。
執行int 0x80之后執行system_call對應的代碼,在system_call處設置斷點后執行,發現函數無法在處停止,說明system_call是一個特殊的函數,實際上其不是一個函數,只是一段匯編代碼的起點,gdb不能跟蹤它。
系統調用的工作,一旦在start_kernel初始化好了以后,運行到init x80指令之后,立刻跳轉到systime_call這個位置,entry(system_call),中斷系統調用處理過程,存在保護現場,恢復現場的功能, sys_call_table(%eax,4) 系統調用表,eax傳過來的是系統調用號
syscall_after_call: 保存返回值
syscall_exit: 處理退出工作 有可能發生進程調度,有可能處理信號
restore all 返回用戶態
system_call的代碼:
ENTRY(system_call)
RING0_INT_FRAME
ASM_CLAC
pushl_cfi %eax //保存系統調用號;
SAVE_ALL //可以用到的所有CPU寄存器保存到棧中
GET_THREAD_INFO(%ebp) //ebp用于存放當前進程thread_info結構的地址
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax //檢查系統調用號(系統調用號應小于NR_syscalls),
jae syscall_badsys //不合法,跳入到異常處理
syscall_call:
call *sys_call_table(,%eax,4) //合法,對照系統調用號在系統調用表中尋找相應服務例程
movl %eax,PT_EAX(%esp) //保存返回值到棧中
syscall_exit:
testl $_TIF_ALLWORK_MASK, %ecx //檢查是否需要處理信號
jne syscall_exit_work //需要,進入 syscall_exit_work
restore_all:
TRACE_IRQS_IRET //不需要,執行restore_all恢復,返回用戶態
irq_return:
INTERRUPT_RETURN //相當于iret
使用流程圖來理解system_call流程
小結:
系統調用是特殊的中斷函數,是多種中斷處理過程的集合。通過INT指令發起調用,通過IRET指令用于返回系統調用到用戶態結束。
init ox80是通過中斷向量將信息傳遞給system_call,system_call是通過系統調用號于sys_syz()進行通信
轉載于:https://www.cnblogs.com/20189210mujian/p/9976965.html
總結
以上是生活随笔為你收集整理的2018-2019-1 20189210 《LInux内核原理与分析》第六周作业的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MongoDB学习笔记(2)
- 下一篇: Appium——appium之mac环境