① linux系統調用是通過軟中斷實現的嗎
軟中斷是利用硬體中斷的概念,用軟體方式進行模擬,實現宏觀上的非同步執行效果。很多情況下,軟中斷和信號有些類似,同時,軟中斷又是和硬中斷相對應的,硬中斷是外部設備對CPU的中斷,軟中斷通常是硬中斷服務程序對內核的中斷,信號則是由內核(或其他進程)對某個進程的中斷(《Linux內核源代碼情景分析》第三章)。軟中斷是linux系統原「底半處理」的升級,在原有的基礎上發展的新的處理方式,以適應多cpu 、多線程的軟中斷處理。
軟中斷是實現系統API函數調用的手段
函數調用時將返回地址和CPU狀態寄存器內容壓棧,函數執行完畢後出棧返回斷點繼續執行。
軟中斷調用時將返回地址和CPU狀態寄存器內容壓棧,修改特權級,根據中斷號查找中斷向量表,找到ISR中斷服務常式地址,跳轉執行。
② 如何在Linux內核里增加一個系統調用
一、Linux0.11下添加系統調用:x0dx0ax0dx0a我在bochs2.2.1中對linux0.11內核添加了一個新的系統調用,步驟如下: x0dx0a1./usr/src/linux/include/unistd.h中添加:#define __NR_mytest 87 x0dx0a然後在下面聲明函數原型:int mytest(); x0dx0a2./usr/src/linux/include/linux/sys.h中添加:extern int sys_mytest(); x0dx0a然後在sys_call_table中最後加上sys_mytest; x0dx0a3.在/usr/src/linux/kernel/sys.c中添加函數實現如下: x0dx0aint sys_mytest(){ x0dx0aprintk("This is a test!"); x0dx0areturn 123; x0dx0a} x0dx0a4.在/usr/src/linux/kernel/system_call.s中對系統調用號加1(原來是86改成了87) x0dx0a5.然後到/usr/src/linux目錄下編譯內核make clean; make Image x0dx0a6. cp /usr/src/linux/include/unistd.h /usr/include/unistd.h x0dx0a7. reset bochs x0dx0a8. 在/usr/root中生成test.c文件如下: x0dx0a#define __LIBRARY__ x0dx0a#include
③ Linux中斷 異常 系統調用 中斷上半部 中斷下半部 這些有什麼區別和聯系
中斷分軟中斷跟硬中斷,硬中斷是由硬體從外部觸發,軟中斷由軟體觸發,就像linux系統調用int 80一樣。至於中斷的上下部其實就是因為中斷的處理時間跟它的優先順序不一定成正比,所以一般先處理中斷最重要的部分(上半部),待到不怎麼忙的時候,再來處理比較悠閑的部分(下半部)。就像輸入的時候,拿到鍵盤輸入的是什麼才是最重要的(上半部),顯示字元才是次要的(下半部)。
④ 什麼是中斷系統調用
中斷、異常和系統調用
所謂中斷是指CPU對系統發生的某個事件做出的一種反應,CPU暫停正在執行的程序,保留現場後自動地轉去執行相應的處理程序,處理完該事件後再返回斷點繼續執行被「打斷」的程序。
中斷可分為三類,第一類是由CPU外部引起的,稱作中斷,如I/O中斷、時鍾中斷、控制台中斷等。第二類是來自CPU的內部事件或程序執行中的事件引起的過程,稱作異常,如由於CPU本身故障(電源電壓低於105V或頻率在47~63Hz之外)、程序故障(非法操作碼、地址越界、浮點溢出等)等引起的過程。
第三類由於在程序中使用了請求系統服務的系統調用而引發的過程,稱作「陷入」(trap,或者陷阱)。前兩類通常都稱作中斷,它們的產生往往是無意、被動的,而陷入是有意和主動的。
1.中斷處理
中斷處理一般分為中斷響應和中斷處理兩個步驟。中斷響應由硬體實施,中斷處理主要由軟體實施。
(1)中斷響應
對中斷請求的整個處理過程是由硬體和軟體結合起來而形成的一套中斷機構實施的。發生中斷時,CPU暫停執行當前的程序,而轉去處理中斷。這個由硬體對中斷請求作出反應的過程,稱為中斷響應。一般說來,中斷響應順序執行下述三步動作:
◆中止當前程序的執行;
◆保存原程序的斷點信息(主要是程序計數器PC和程序狀態寄存器PS的內容);
◆從中斷控制器取出中斷向量,轉到相應的處理程序。
通常CPU在執行完一條指令後,立即檢查有無中斷請求,如果有,則立即做出響應。
當發生中斷時,系統作出響應,不管它們是來自硬體(如來自時鍾或者外部設備)、程序性中斷(執行指令導致「軟體中斷」—Software Interrupts),或者來自意外事件(如訪問頁面不在內存)。
如果當前CPU的執行優先順序低於中斷的優先順序,那麼它就中止對當前程序下條指令的執行,接受該中斷,並提升處理機的執行級別(一般與中斷優先順序相同),以便在CPU處理當前中斷時,能屏蔽其它同級的或低級的中斷,然後保存斷點現場信息,通過取得的中斷向量轉到相應的中斷處理程序的入口。
(2)中斷處理
CPU從中斷控制器取得中斷向量,然後根據具體的中斷向量從中斷向量表IDT中找到相應的表項,該表項應是一個中斷門。於是,CPU就根據中斷門的設置而到達了該通道的總服務程序的入口。
核心對中斷處理的順序主要由以下動作完成:
◆保存正在運行進程的各寄存器的內容,把它們放入核心棧的新幀面中。
◆確定「中斷源」或核查中斷發生,識別中斷的類型(如時鍾中斷或盤中斷)和中斷的設備號(如哪個磁碟引起的中斷)。系統接到中斷後,就從機器那裡得到一個中斷號,它是檢索中斷向量表的位移。中斷向量因機器而異,但通常都包括相應中斷處理程序入口地址和中斷處理時處理機的狀態字。
◆核心調用中斷處理程序,對中斷進行處理。
◆中斷處理完成並返回。中斷處理程序執行完以後,核心便執行與機器相關的特定指令序列,恢復中斷時寄存器內容和執行核心棧退棧,進程回到用戶態。如果設置了重調度標志,則在本進程返回到用戶態時做進程調度。
2.系統調用
在Unix/Linux系統中,系統調用像普通C函數調用那樣出現在C程序中。但是一般的函數調用序列並不能把進程的狀態從用戶態變為核心態,而系統調用卻可以做到。
C語言編譯程序利用一個預先確定的函數庫(一般稱為C庫),其中有各系統調用的名字。C庫中的函數都專門使用一條指令,把進程的運行狀態改為核心態。Linux的系統調用是通過中斷指令「INT 0x80」實現的。
每個系統調用都有惟一的號碼,稱作系統調用號。所有的系統調用都集中在系統調用入口表中統一管理。
系統調用入口表是一個函數指針數組,以系統調用號為下標在該數組中找到相應的函數指針,進而就能確定用戶使用的是哪一個系統調用。不同系統中系統調用的個數是不同的,目前Linux系統中共定義了221個系統調用。
另外,系統調用表中還留有一些余項,可供用戶自行添加。
當CPU執行到中斷指令「INT 0x80」時,硬體就做出一系列響應,其動作與上述的中斷響應相同。CPU穿過陷阱門,從用戶空間進入系統空間。相應地,進程的上下文從用戶堆棧切換到系統堆棧。
接著運行內核函數system_call()。首先,進一步保存各寄存器的內容;接著調用syscall_trace( ),以系統調用號為下標檢索系統調用入口表sys_call_table,從中找到相應的函數;然後轉去執行該函數,完成具體的服務。
執行完服務程序,核心檢查是否發生錯誤,並作相應處理。如果本進程收到信號,則對信號作相應處理。最後進程從系統空間返回到用戶空間。
上面兩講簡要介紹了Linux內核的主要數據結構和相應的演算法。Linux內核包含了豐富的內容,這里僅是其中的一點點,以求起到「拋磚引玉」的作用。
信號的中斷與系統調用的重起
#include <signal.h>int sigaction(ints signo, const struct sigaction *act, struct sigaction *oact) ;struct sigaction ; 當更改信號動作時,如果sa _handler指向一個信號捕捉函數(不是常數SIG_IGN或SIG_DFL),則sa_mask欄位說明了一個信號集,在調用信號捕捉函數之前,該信號集要加到進程的信號屏蔽字中。僅當從信號捕捉函數返回時再將進程的信號屏蔽字恢復為原先值。這樣,在調用信號處理程序時就能阻塞某些信號。在信號處理程序被調用時,系統建立的新信號屏蔽字會自動包括正被遞送的信號。因此保證了在處理一個給定的信號時,如果這種信號再次發生,那麼它會被阻塞到對前一個信號的處理結束為止。A. 可自動重起的signal()的實現:#include <signal.h>#typpdef void Sigfunc(int signo); Sigfunc *signal(int signo, Sigfunc *func) else // for other signal if (sigaction(signo, &act, &oac) < 0) return (SIG_ERR); return (oact.sa_handler);}注: 在if語句中,我們檢查是否為SIGALRM信號,如果是,且系統定義了 SA_INTERRUPT(SUNOS),即為SUNOS,該系統默認的系統調用是自 動重起的,我們阻止該信號中斷的系統調用重起,因為我們要用該信號 中斷I/O操作,實現定時的功能. 接著的else語句中的信號為SIGALRM之外的其他信號,且系統定義了 SA_RESTART,即為SVR4或4.3+BSD類系統,該類系統中默認的系統 調用是不可重起的,所以應該加上SA_RESTART標志,使由這些信號中 斷的系統調用自動重起.B. 不可重起的signal_intr()實現: Sigfunc *signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTTERRUPT //SUNOS
act.flags |= SA_INTTERRUPT;
#endif
if (sigaction(signo, &act, &oac) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
注: 只有SUNOS為自動重起的,其他為不自動重起的,所以只要將SUNOS標 志為非自動重起即可.如上.
⑤ Linux系統調用表(system call table)
轉自:《 Linux系統調用表 》
《 linux系統調用表(system call table) 》
《 線上環境 Linux 系統調用追蹤 》
《 Linux系統調用權威指南 》
《 為什麼系統調用會消耗較多資源?系統調用的三種方法:軟體中斷(分析過程)、SYSCALL指令、vDSO(虛擬動態鏈接對象linux-vdso.so.1) 》