Linux核心學習

2021-09-12 09:25:29 字數 4669 閱讀 9143

交叉工具鏈

核心相關知識

linux系統的構成:使用者空間、核心空間

思考:為什麼劃分為兩個層次?

目的其實是為保護作業系統,防止應用程式的異常導致作業系統崩潰。

核心空間與使用者空間是程式執行的兩種不同狀態,通過系統呼叫硬體中斷能夠完成從使用者空間到核心空間的轉移。

那麼linux的核心由哪些構成呢?如下圖所示:

根目錄目錄

說明aaaaaaa

aaaaaa

/arch

arch是architecture的縮寫,核心所支援的每種cpu體系,在該目錄下都有對應的子目錄。每個cpu的子目錄,又進一步分解為boot,mm,kernel等子目錄,分別包含控制系統引導,記憶體管理,系統呼叫等。

block

部分塊裝置驅動程式

crypto

加密,壓縮,crc校驗演算法

documentation

核心的文件

drivers

裝置驅動程式

fs存放各種檔案系統的實現**,每個子目錄對應一種檔案系統的實現,公用的源程式用於實現虛擬檔案系統vfs。

include

核心所需要的標頭檔案,與平台無關的標頭檔案在include/linux子目錄下,與平台有關的標頭檔案則放在相應的子目錄中。

lib庫檔案**

mmmm目錄中的檔案用於實現記憶體管理中與與體系結構無關的部分

net所支援的網路協議實現

scripts

配置核心的腳步

security

selinux的模組

sound

應聘裝置的驅動程式

usrcpio命令實現

virt

記憶體虛擬機器

清楚臨時檔案、中間檔案和配置檔案

確定目標系統的軟硬體配置情況,比如cpu的型別、網絡卡的型號,所需要支援的網路協議等。

使用如下命令之一配置核心:

編譯核心

如需要獲取詳細編譯資訊,可使用:

make zlmage v=1 make bzlmage v=1

編譯好的核心位於arch//boot/目錄下

編譯核心模組

make modules

安裝核心模組

make modules_install

將編譯好的核心模組從核心源**目錄copy至/lib/modules下製作init ramdisk

mkinitrd initrd-$version(自行取名) $version(跟當前版本一致,可以通過查詢/lib/modules/下的目錄得到)

例如:mkinitrd initrd-2.6.29 2.6.29

cp arch/x86/boot/bzlmage /boot/vmlinuz-$version

cp $initrd /boot/

修改/etc/grub.conf或者 /etc/lilo.conf

$version為所編譯的核心版本號

進行嵌入式開發前,首先需安裝交叉工具鏈,步驟如下:

解壓工具鏈到某一目錄

例如:tar zxvf arm-linux-gcc-*** -c 目的目錄

修改/etc/profile,新增

pathmunge 目的目錄

執行source /etc/profile

之後便可以在#下敲命令列 # arm-linux-gcc hello.c -o hello 工具

說明舉例

arm-linux-gcc

編譯arm-linux-gcc hello.c -o hello

arm-linux-objdump

反彙編工具

arm-linux-objdump -d -s hello >log(輸出到log檔案中去)

arm-linux-readelf

elf檔案檢視工具

arm-linux-readelf -all hello arm-linux-readelf -d hello(檢視hello使用的動態庫)

首先系統呼叫能做那些事呢?概括來說,大概有下面這些事需要系統呼叫來實現。

控制硬體:系統呼叫往往作為硬體資源和使用者空間的抽象介面,比如讀寫檔案時用到的write/read呼叫。

設定系統狀態或讀取核心資料:因為系統呼叫是使用者空間和核心的唯一通訊手段,所以使用者設定系統狀態,比如開/關某項核心服務(設定某個核心變數),或讀取核心資料都必須通過系統呼叫。比如getpgid、getpriority、setpriority、sethostname

程序管理:用來保證系統中程序能以多工在虛擬記憶體環境下得以執行。比如 fork、clone、execve、exit等

那為什麼一定要用系統呼叫來訪問作業系統的內容呢,其實這可以看做對核心的保護,linux分為使用者空間和核心空間,而使用者空間是不允許訪問核心空間的資料的。那麼在使用者空間的程式需要訪問核心空間的資源時就必須通過系統呼叫這個中間人來實現。這樣可以對使用者空間的行為進行限制,只有特定的得到許可的(事先規定的)使用者空間行為才能進入核心空間。一句話,系統呼叫是核心給使用者空間提供的乙個可以訪問核心資源的乙個介面。

另外多說一句,從使用者程序切換到核心程序只有兩種方式,一種就是系統呼叫,另一種是中斷。

要實現系統呼叫,首先要能從使用者空間切換到核心空間,這個切換在ia-32系統上是用彙編指令int $0x80來引發軟體中斷實現的。這部分內容一般是在c標準庫中實現的。進入核心空間後,系統呼叫中樞處理**(所有的系統呼叫都由一處中樞**處理)根據傳遞的引數(引數是有暫存器傳遞的包括唯一的系統呼叫號)和乙個靜態表分別執行不同的函式。例如read系統呼叫,0x80 中斷處理程式接管執行後,先檢查其系統呼叫號,然後根據系統呼叫號查詢系統呼叫表,並從系統呼叫表中得到處理 read 系統呼叫的核心函式 sys_read ,最後傳遞引數並執行 sys_read 函式。至此,核心真正開始處理 read 系統呼叫(sys_read 是 read 系統呼叫的核心入口)。

使用者程式------>c庫(即api):int 0x80 ----->system_call------->系統呼叫服務例程-------->核心程式

先說明一下,我們常說的使用者api其實就是系統提供的c庫。

系統呼叫是通過軟中斷指令 int 0x80 實現的,而這條int 0x80指令就被封裝在c庫的函式中。

(軟中斷和我們常說的硬中斷不同之處在於,軟中斷是由指令觸發的,而不是由硬體外設引起的。)

int 0x80 這條指令的執行會讓系統跳轉到乙個預設的核心空間位址,它指向系統呼叫處理程式,即system_call函式。

(注意:!!!系統呼叫處理程式system_call 並不是系統呼叫服務例程,系統呼叫服務例程是對乙個具體的系統呼叫的核心實現函式,而系統呼叫處理程式是在執行系統呼叫服務例程之前的乙個引導過程,是針對int 0x80這條指令,面向所有的系統呼叫的。簡單來講,執行任何系統呼叫,都是先通過呼叫c庫中的函式,這個函式裡面就會有軟中斷 int 0x80 語句,然後轉到執行系統呼叫處理程式 system_call ,

system_call 再根據具體的系統呼叫號轉到執行具體的系統呼叫服務例程。)

system_call函式是怎麼找到具體的系統呼叫服務例程的呢?通過系統呼叫號查詢系統呼叫表sys_call_table!軟中斷指令int 0x80執行時,系統呼叫號會被放入 eax 暫存器中,system_call函式可以讀取eax暫存器獲取,然後將其乘以4,生成偏移位址,然後以sys_call_table為基址,基址加上偏移位址,就可以得到具體的系統呼叫服務例程的位址了!

然後就到了系統呼叫服務例程了。需要說明的是,系統呼叫服務例程只會從堆疊裡獲取引數,所以在system_call執行前,會先將引數存放在暫存器中,system_call執行時會首先將這些暫存器壓入堆疊。system_call退出後,使用者可以從暫存器中獲得(被修改過的)引數。

另外:系統呼叫通過軟中斷int 0x80陷入核心,跳轉到系統呼叫處理程式system_call函式,然後執行相應的服務例程。但是由於是代表使用者程序,所以這個執行過程並不屬於中斷上下文,而是程序上下文。因此,系統呼叫執行過程中,可以訪問使用者程序的許多資訊,可以被其他程序搶占,可以休眠。

當系統呼叫完成後,把控制權交回到發起呼叫的使用者程序前,核心會有一次排程。如果發現有優先順序更高的程序或當前程序的時間片用完,那麼會選擇優先順序更高的程序或重新選擇程序執行。

程序分為:普通程序,實時程序。將普通程序細分為互動式程序(interactive processs)和批處理程序(batch process),互動式程序需要和使用者進行交流,因此對排程延遲比較敏感,而批處理程序屬於那種在後台默默幹活的,因此它更注重throughput的需求。對於2.4核心,程序切換有兩種,一種是當程序由於需要等待某種資源而無法繼續執行下去,這時候只能是主動將自己掛起(呼叫schedule函式),引發一次任務排程過程。另外一種是程序歡快執行,但是由於各種排程事件的發生(例如時間片用完)而被迫讓出cpu,被其他程序搶占

linux 核心學習

linux核心獲取 官網 linux作業系統的核心是模組化,可以使用lsmod命令檢視核心模組,下面展示已載入系統的模組 root 172.16.0.55 vendor composer test lsmod module size used by nfnetlink queue 8111 0 nf...

linux 核心學習(2)

linux核心原始碼樹大體結構 由於linux的原 持續在變化,所以不可能給出太詳細的內容,只能指出乙個特殊的驅動大概會出現在什麼地方。makefile 這是整個的原始碼樹的最頂層的makefile。它定義了很多的有用的變數和規則,如預設的gcc編譯標誌。arch 所有的特殊的體系結構的 都在這個目...

linux核心學習導讀

引用出處 像linux 核心這樣龐大而複雜的程式看起來確實讓人望而生畏,它象乙個很大的球,沒有起點和終點。在讀源 的過程中,你會遇到這樣的情況,當讀到核心的某一部分時又會涉及到其它更多的檔案,當返回到原來的地方想繼續往下讀時,又忘了原來讀的內容。在 internet 上,很多人為此付出了很大的努力,...