linux 系統呼叫(一)概述

2021-09-27 01:31:02 字數 3520 閱讀 9170

linux系統呼叫這部分經常出現兩個詞:libc庫和封裝函式。

1. libc概念

libc是stantard c library的簡稱,它是符合ansi c標準的乙個標準函式庫。libc庫提供c語言中所使用的巨集,型別的定義,字串操作符,數學計算函式以及輸入輸出函式等。正如ansi c是c語言的標準一樣,libc只是乙個函式庫標準,每個作業系統都會按照該標準對標準庫進行具體實現。通常我們所說的libc是特指某個作業系統的標準庫,比如:在linux作業系統下所說的libc即glibc。glibc是類unix作業系統中使用最廣泛的libc庫,它的全稱是gnu c library.

2. glibc

類unix作業系統通常將glibc庫作為作業系統的一部分,它被視為作業系統與使用者程式的介面。glibc庫不僅實現標準c語言中的函式,而且也包含自己所屬的函式介面。比如:在glibc庫中,既包含標準c中的fopen(),又包含類unix系統中的open()。在類unix作業系統中,如果缺失了標準庫,那麼整個作業系統將不能正常運轉。

需要注意的是,函式庫中的api和系統呼叫並沒有一一對應的關係。應用程式借助系統呼叫可以獲得核心所提供的服務,但是,像字串操作這樣的函式並不需要借助核心來實現,因此也就不必與某個系統呼叫關聯。

不過,我們並不是必須通過封裝例程才能使用系統呼叫,syscall()也可以直接呼叫系統呼叫。

1.緩衝檔案系統

緩衝檔案系統的特點是:在記憶體開闢乙個「緩衝區」,為程式中的每乙個檔案使用,當執行讀檔案的操作時,從磁碟檔案將資料先讀入記憶體「緩衝區」, 裝滿後再從記憶體「緩衝區」依此讀入接收的變數。執行寫檔案的操作時,先將資料寫入記憶體「緩衝區」,待記憶體「緩衝區」裝滿後再寫入檔案。由此可以看出,記憶體 「緩衝區」的大小,影響著實際操作外存的次數,記憶體「緩衝區」越大,則操作外存的次數就少,執行速度就快、效率高。一般來說,檔案「緩衝區」的大小隨機器 而定。

fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等

2.非緩衝檔案系統

緩衝檔案系統是借助檔案結構體指標來對檔案進行管理,通過檔案指標來對檔案進行訪問,既可以讀寫字元、字串、格式化資料,也可以讀寫二進位制數 據。非緩衝檔案系統依賴於作業系統,通過作業系統的功能對檔案進行讀寫,是系統級的輸入輸出,它不設檔案結構體指標,只能讀寫二進位制檔案,但效率高、速度 快,由於ansi標準不再包括非緩衝檔案系統,因此建議大家最好不要選擇它。本書只作簡單介紹。open, close, read, write, getc, getchar, putc, putchar 等。

open 是系統呼叫 返回的是檔案控制代碼,檔案的控制代碼是檔案在檔案描述副表裡的索引,fopen是c的庫函式,返回的是乙個指向檔案結構的指標。

fopen是ansic標準中的c語言庫函式,在不同的系統中應該呼叫不同的核心api 

linux中的系統函式是open,fopen是其封裝函式。

檔案描述符是linux下的乙個概念,linux下的一切裝置都是以檔案的形式操作.如網路套接字、硬體裝置等。當然包括操作檔案。

fopen是標準c函式。返回檔案流而不是linux下檔案控制代碼。

裝置檔案不可以當成流式檔案來用,只能用open

fopen是用來操縱正規檔案的,並且設有緩衝的,跟open還是有一些區別

一般用fopen開啟普通檔案,用open開啟裝置檔案

fopen是標準c裡的,而open是linux的系統呼叫.

他們的層次不同.

fopen可移植,open不能

fopen和open最主要的區別是fopen在使用者態下就有了快取,在進行read和write的時候減少了使用者態和核心態的切換,而open則每次都需要進行核心態和使用者態的切換;表現為,如果順序訪問檔案,fopen系列的函式要比直接呼叫open系列快;如果隨機訪問檔案open要比fopen快。

比如用glibc 提供的chmod函式來改變檔案etc/passwd的屬性為 444:

chmod("/etc/passwd", 0444);
使用glibc有很多好處,首先無須知道更多的細節,如 chmod 系統呼叫號,你只需了解 glibc 提供的 api 的原型;其次,該方法具有更好的移植性,你可以很輕鬆將該程式移植到其他平台,或者將 glibc 庫換成其它庫,程式只需做少量改動。

但有點不足是,如果 glibc 沒有封裝某個核心提供的系統呼叫時,我就沒辦法通過上面的方法來呼叫該系統呼叫。如我自己通過編譯核心增加了乙個系統呼叫,這時 glibc 不可能有你新增系統呼叫的封裝 api,此時我們可以利用 glibc 提供的syscall函式直接呼叫。該函式定義在unistd.h標頭檔案中,函式原型如下:

long int syscall (long int sysno, ...)
把上面glibc實現的chmod換成syscall呼叫:

syscall(sys_chmod, "/etc/passwd", 0444);
如果我們知道系統呼叫的整個過程的話,應該就能知道使用者態程式通過軟中斷指令svc來陷入核心態

unsigned int __sys_result;              

register int _a1 __asm__ ("r0"), _nr __asm__ ("r7");

_nr = sys_ify(name);//系統呼叫號

__asm__ __volatile__ ("svc 0x0"

: "=r" (_a1)

: "r" (_nr),"b" ((long)file_name), "c" ((long)mode)

: "memory");

__sys_result = _a1;

}

早期linux採用oabi方式傳遞系統呼叫的number。流程如下:

1.將number 放在軟終斷的中斷號內( eg: swi __nr_oabi_syscall_base | numbe)。

2.在跳轉到軟中斷後,再在之前已經執行過的指令所在記憶體位址中獲取當時的指令(ldr r10, [lr, #-4]),並解析出syscall number。

很明顯讀取已經執行過的指令的記憶體位址處的資料是一種很原始的行為,現在用的不多,但**依然保留了下來。

現在linux採用新的eabi(embedded)方式傳遞系統呼叫的number。比如現在的android編譯器arm-linux-androideabi-gcc。這種新的系統呼叫方式流程如下:

1.將syscall number 儲存到r7暫存器中。

2. 執行swi指令跳轉到軟中斷處執行,並從r7中獲取syscall number。(用現在的編譯器反編譯看swi應該是svc指令)

這裡提到的軟中斷是 supervisor call exception(svc),由於原來名字是software interrupt(swi)一直沿用軟中斷的叫法。

成就系統實現(一) 概述

在乙個完整的業務流程鏈路中,使用者的某種行為可能會觸發成就的達成,如果成就達成了,推送乙個彈窗讓使用者感知。一期功能有11種可以達成的成就。第11種成就 達成條件是完成前面10中成就,每個成就都有對應的獎勵。這11種成就都歸屬新手成就包,二期考慮拓展成就系統,引入多種成就包。1.成就達成的條件分析,...

linux排程器(一) 概述

本次分析的kernel 為2.6.32 220。並且我們先不考慮smp。當前linux的排程程式由兩個排程器組成 主排程器,週期性排程器 兩者又統稱為核心排程器 並且每個排程器包括兩個內容 排程框架 其實質就是兩個函式框架 及排程器類。排程器類是實現了不同排程策略的例項,如 cfs rt class...

作業系統(一)概述

學習資料 作業系統 清華大學出版社 2012 一 功能 1.管理系統的各個部件,使它們能夠正常運轉 2.給上層的應用軟體提供乙個易於理解和程式設計的介面 二 角色 對於作業系統的設計者,作業系統是系統資源的管理者 如何管理cpu 記憶體 i o裝置等系統部件 對於應用程式開發人員,作業系統是一組抽象...