LINUX系統(tǒng)調(diào)用課件_第1頁(yè)
LINUX系統(tǒng)調(diào)用課件_第2頁(yè)
LINUX系統(tǒng)調(diào)用課件_第3頁(yè)
LINUX系統(tǒng)調(diào)用課件_第4頁(yè)
LINUX系統(tǒng)調(diào)用課件_第5頁(yè)
已閱讀5頁(yè),還剩24頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Chapter5:系統(tǒng)調(diào)用

■為什么需要系統(tǒng)調(diào)用

■相關(guān)數(shù)據(jù)和代碼

■例:系統(tǒng)調(diào)用wetuidO的實(shí)現(xiàn)

■添加一個(gè)系統(tǒng)調(diào)用mysyscall

■再實(shí)現(xiàn)一個(gè)稍復(fù)雜的系統(tǒng)調(diào)用

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

為什么需要系統(tǒng)調(diào)用(1)

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

為什么需要系統(tǒng)調(diào)用(2)

用戶空間而、內(nèi)核空間

5模=式^切換、

sys_foo...

廠模式切換、

?邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

相關(guān)數(shù)據(jù)和代碼

■arch/i386/kemel/traps.c

■?

■arch/i386/kernel/entry.S

系統(tǒng)調(diào)用時(shí)的內(nèi)核棧

syscalltable

systemcall和retfix)msyscall

■include/linux/unistd.h

系統(tǒng)調(diào)用編號(hào)

宏定義展開系統(tǒng)調(diào)用

glibC展開系統(tǒng)調(diào)用INLINE_SYSCALL(getuid,0);

?邊干邊學(xué)——內(nèi)核指導(dǎo)

Linux

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

系統(tǒng)調(diào)用時(shí)的內(nèi)核棧

18*Stacklayoutin'ret_from_system_caH':

19*ptraceneedstohaveallregsonthestack.

20*iftheorderhereischanged,itneedstobe

21*updatedinfbrk.c:copy_process,signal.crdosignal,

*ptrace.candptrace.h

23*

24*0(%esp)-%ebx

N-*4(%esp)-%ecx

26*8(%esp)-%edx

27*C(%esp)-%esi

28*10(%esp)-%edi

29*14(%esp)-%ebp

JU*18(%esp)-%eax

31*lC(%esp)-%ds

32*20(%esp)-%es

33*24(%esp)-orig_eax

34*28(%esp)-%eip

35*2C(%esp)-%cs

36*30(%esp)-%eflags

37*34(%esp)-%oldesp

38*38(%esp)-%oldss

39*

40*"current"isinregister%ebxduringanyslowentries.

邊干邊學(xué)---Linux內(nèi)核指導(dǎo)

系統(tǒng)調(diào)用時(shí)的內(nèi)核棧

#defineSAVEALL\

.cld;\

pushl%es;\

pushl%ds;\

pushl%eax;\

pushl%ebp;\

pushl%edi;\

pushl%esi;\

pushl%edx;\

pushl%ecx;\

pushl%ebx;\

movl$(_KERNEL_DS),%edx;\

movl%edx,%ds;\

movl%edx,%es;

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

系統(tǒng)調(diào)用時(shí)的內(nèi)核棧

ftdefineRESTORE_ALL\

popl%ebx;\

popl%ecx;\

popl%edx;\

popl%esi;\

popl%edi;\

popl%ebp;\

popl%eax;\

1:popl%ds;\

2:popl%es;\

addl$4,%esp;\

3:iret;\

?邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

syscalltable

ENTRY(sys_call_table)

.longSYMBOL_NAME(sys_ni_syscall)

.longSYMBOLNAME(sysexit)

,longSYMBOL_NAME(sys_fdrk)

102.longSYMBOLNAME(sysread)

.longSYMBOLNAME(syswrite)

.longSYMBOLNAME(sysopen)/*5*/

.longSYMBOL_NAME(sys_ni_syscall)/*reservedforIremovexattr*/

.longSYMBOL_NAME(sys_ni_syscall)/*reservedforfremovexattr*/

637

.reptNR_syscalls-(.-sys_call_table)/4

,longSYMBOL_NAME(sys_ni_syscall)

.endr

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

syscalltable

eax*4ENTRY(sys_call_table)

,longSYMBOL_NAME(sys_ni_...)

JongSYMBOL_NAME(sys_exit)

,longSYMBOL二NAME(sys二fork)

JongSYMBOL_NAME(sys_read)

,longSYMBOL_NAME(sys_write)

JongSYMBOL_NAME(sys_open)

syscalltable首地址卜---?QA.longSYMBOL_NAME(sys_getuid)

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

systemcall

ENTRY(systemcall)#int0x80后執(zhí)行

pushl%eax#saveorigeax

196'SAVEALL

GET_CURRENT(%ebx)

testb$0x02,tsk_ptrace(%ebx)#PTTRACESYS

jnetracesys

cmpl$(NR_syscalls),%eax

jaebadsys

call*SYMBOL_NAME(sys_call_table)(,%eax,4)

movl%eax,EAX(%esp)#savethereturnvalue

20ENTRY(ret_from_sys_call)

205cli

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

ret_from_sys_call

ENTRY(retfromsyscall)

cli#need_reschedandsignalsatomictest

cmpl$O,need_resched(%ebx)

jnereschedule

cmpl$O,sigpending(%ebx)

jnesignalretum

restoreall:

RESTOREALL

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

用戶空間內(nèi)核空間內(nèi)核堆棧中的變化注解

壓入用戶ss

由于是陷入進(jìn)來

壓入用戶esp

內(nèi)核的,所以機(jī)

壓入EFLAGS器自動(dòng)保存與轉(zhuǎn)

壓入cs換堆棧。

壓入eip

壓入eax

push

push%es;

push%ds;

push%eax;

push%ebp;

push%edi;

push%esi;

push%edx;

push%ecx;

%ebx

popl%ebx;

popl%ecx;

RESTORE_ALLpopl%edx;

popl%esi;

popl%edi;

popl%ebp;

popl%eax;

popl%ds;

popl%es;

addl$4,%esp—等價(jià)于彈出eax

iret

彈出eip

彈出cs

J

回到用戶空間>彈出EFLAGS

彈出用戶esp

彈出用戶ss

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

arch/i386/kernel/traps.c

voidinittrapinit(void)〃初始化中斷描述符表IDT

settrapgate(0,÷_error);

set_trap_gate(l,&debug);

setintrgate(2,&nmi);

set_system_gate(3,&int3);

set_trap_gate(l9,&simd_coprocessor_error);

set_system_gate(SYSCALL_VECTOR,&system_call);

r邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

系統(tǒng)調(diào)用編號(hào)

include/asm-i386/unistd.h

#defineNRexit1

#defineNRfork2

#defineNRread3

#defineNRwrite4

#defineNRopen5

#defineNRclose6

#defineNRllistxattr233

#defineNRflistxattr234

#defineNRremovexattr235

#defineNRlremovexattr236

#defineNRfremovexattr237

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

宏定義展開系統(tǒng)調(diào)用

#define_syscall3(type,name,typel,argl,type2,arg2,type3,arg3)\

typename(typelargl,type2arg2,type3arg3)\

{\

long_res;\

asm_volatile(nint$0x80"\

:res)\

:"0"(_NR_##name),nbn((long)(argl)),McH((long)(arg2)),\

((long)(arg3)));\

_syscall_return(type9_res);\

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

宏定義展開系統(tǒng)調(diào)用

movl$_NR_##name,%eax〃先為輸入?yún)?shù)分配寄存器

■?

movlarg1,%ebx

movlarg25%ecx

movlarg3,%edx

#APP

int$0x80〃匯編代碼

#NO_APP

movl%eax,res//最后處理輸出參數(shù)

?邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

■一個(gè)簡(jiǎn)單的程序,但包含系統(tǒng)調(diào)用和庫(kù)函數(shù)調(diào)用

■"

#include<linux/unistd.h>

/*allsystemcallsneedthisheader*/

intmain(){

inti=getuid();

printf(uHelloWorld!Thisismyuid:%d\n\i);

■假定vunistd.h>定義了“宏”

_syscallO(int,getuid);

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

■這個(gè)“宏”被getuid()展開后

intgetuid(void)

long_res;

asm_volatile("int$0x80”

:“=a"(_res)#輸出

_NR_getuid));#輸入

_syscall_return(int9_res);

}一—一

■顯然,NRgetuid(24)放入eax,并int0x80

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

||幺例:系統(tǒng)調(diào)用getuidO的實(shí)現(xiàn)

??

■因?yàn)橄到y(tǒng)初始化時(shí)設(shè)定了

set_system_gate(SYSCALL_VECTOR,&system_call);

■所以進(jìn)入system_call

ENTRY(systemcall)

pushl%eax#saveorigeax

SAVEALL

GET_CURRENT(%ebx)

testb$0x02,tsk_ptrace(%ebx)#PTTRACESYS

jnetracesys

cmpl$(NR_syscalls),%eax

jaebadsys

call*SYMBOL_NAME(sys_call_table)(,%eax,4)

movl%eax,EAX(%esp)

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

■注意第202行,止匕時(shí)eax為24

■查sys_call_table,得到call指令的操作數(shù)

sys_getuidl6

■調(diào)用函數(shù)sys_getuidl6()

longsys_getuidl6(void)

146{

returnhigh21owuid(current->uid);

148)

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

例:系統(tǒng)調(diào)用getuidO的實(shí)現(xiàn)

??

■第202行完成后,接著執(zhí)行第203行后面的指令

movl%eax,EAX(%esp)

204ENTRY(retfromsyscall)

205cli

cmpl$O9need_resched(%ebx)

jnereschedule

cmpl$O?sigpending(%ebx)

jnesignalretum

restore_all:

RESTOREALL

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

乂例:系統(tǒng)調(diào)用getuidO的實(shí)現(xiàn)

■第203行:返回值從eax移到堆棧中eax的位置

■假設(shè)沒有什么意外發(fā)生,于是ret—ftom_SyS_Call直

接到RESTORE_ALL,從堆棧里面彈由一保存的寄

存器,堆棧切質(zhì)(iret)

■進(jìn)程回到用戶態(tài),返回值保存在eax中

■print甘丁印出

HelloWorld!Thisismyuid:551

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

邊干邊學(xué)——Linux內(nèi)核指導(dǎo)

■系統(tǒng)調(diào)用的編號(hào)名字—NRmysyscall

■改寫/usr/include/asm/unistd.h

240#defineNRllistxattr233

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論