linux內核api
A. linux內核api man手冊怎麼建立
1. man
man,即 manunal,是 UNIX 系統手冊的電子版本。根據習慣,UNIX 系統手冊通常分為不同的部分(或小節,即 section),每個小節闡述不同的系統內容。目前的小節劃分如下:
命令:普通用戶命令
系統調用:內核介面
函數庫調用:普通函數庫中的函數
特殊文件:/dev 目錄中的特殊文件
文件格式和約定:/etc/passwd 等文件的格式
游戲。
雜項和約定:標准文件系統布局、手冊頁結構等雜項內容
系統管理命令。
內核常式:非標準的手冊小節。便於 Linux 內核的開發而包含
其他手冊小節:
B. Linux進程的調度
上回書說到 Linux進程的由來 和 Linux進程的創建 ,其實在同一時刻只能支持有限個進程或線程同時運行(這取決於CPU核數量,基本上一個進程對應一個CPU),在一個運行的操作系統上可能運行著很多進程,如果運行的進程占據CPU的時間很長,就有可能導致其他進程餓死。為了解決這種問題,操作系統引入了 進程調度器 來進行進程的切換,輪流讓各個進程使用CPU資源。
1)rq: 進程的運行隊列( runqueue), 每個CPU對應一個 ,包含自旋鎖(spinlock)、進程數量、用於公平調度的CFS信息結構、當前運行的進程描述符等。實際的進程隊列用紅黑樹來維護(通過CFS信息結構來訪問)。
2)cfs_rq: cfs調度的進程運行隊列信息 ,包含紅黑樹的根結點、正在運行的進程指針、用於負載均衡的葉子隊列等。
3)sched_entity: 把需要調度的東西抽象成調度實體 ,調度實體可以是進程、進程組、用戶等。這里包含負載權重值、對應紅黑樹結點、 虛擬運行時vruntime 等。
4)sched_class:把 調度策略(演算法)抽象成調度類 ,包含一組通用的調度操作介面。介面和實現是分離,可以根據調度介面去實現不同的調度演算法,使一個Linux調度程序可以有多個不同的調度策略。
1) 關閉內核搶占 ,初始化部分變數。獲取當前CPU的ID號,並賦值給局部變數CPU, 使rq指向CPU對應的運行隊列 。 標識當前CPU發生任務切換 ,通知RCU更新狀態,如果當前CPU處於rcu_read_lock狀態,當前進程將會放入rnp-> blkd_tasks阻塞隊列,並呈現在rnp-> gp_tasks鏈表中。 關閉本地中斷 ,獲取所要保護的運行隊列的自旋鎖, 為查找可運行進程做准備 。
2) 檢查prev的狀態,更新運行隊列 。如果不是可運行狀態,而且在內核態沒被搶占,應該從運行隊列中 刪除prev進程 。如果是非阻塞掛起信號,而且狀態為TASK_INTER-RUPTIBLE,就把該進程的狀態設置為TASK_RUNNING,並將它 插入到運行隊列 。
3)task_on_rq_queued(prev) 將pre進程插入到運行隊列的隊尾。
4)pick_next_task 選取將要執行的next進程。
5)context_switch(rq, prev, next)進行 進程上下文切換 。
1) 該進程分配的CPU時間片用完。
2) 該進程主動放棄CPU(例如IO操作)。
3) 某一進程搶佔CPU獲得執行機會。
Linux並沒有使用x86 CPU自帶的任務切換機制,需要通過手工的方式實現了切換。
進程創建後在內核的數據結構為task_struct , 該結構中有掩碼屬性cpus_allowed,4個核的CPU可以有4位掩碼,如果CPU開啟超線程,有一個8位掩碼,進程可以運行在掩碼位設置為1的CPU上。
Linux內核API提供了兩個系統調用 ,讓用戶可以修改和查看當前的掩碼:
1) sched_setaffinity():用來修改位掩碼。
2) sched_getaffinity():用來查看當前的位掩碼。
在下次task被喚醒時,select_task_rq_fair根據cpu_allowed里的掩碼來確定將其置於哪個CPU的運行隊列,一個進程在某一時刻只能存在於一個CPU的運行隊列里。
在Nginx中,使用了CPU親和度來完成某些場景的工作:
worker_processes 4;
worker_cpu_affinity 0001001001001000;
上面這個配置說明了4個工作進程中的每一個和一個CPU核掛鉤。如果這個內容寫入Nginx的配置文件中,然後Nginx啟動或者重新載入配置的時候,若worker_process是4,就會啟用4個worker,然後把worker_cpu_affinity後面的4個值當作4個cpu affinity mask,分別調用ngx_setaffinity,然後就把4個worker進程分別綁定到CPU0~3上。
worker_processes 2;
worker_cpu_affinity 01011010;
上面這個配置則說明了兩個工作進程中的每一個和2個核掛鉤。
C. linux系統內核數據
正如圖中看到的一樣,存在著兩種WiFi設備,具體是哪一類要看IEEE802.11標準的MLME如何實現。
如果直接通過硬體實現,那麼設備就是硬MAC(fullMAC)設備;如果通過軟體的方式實現,那麼設備就是軟MAC(softMAC)設備。現階段大部分無線設備都是軟體實現的軟MAC設備。
通常我們把Linux內核無線子系統看成兩大塊:cfg80211和mac80211,它們連通內核其他模塊和用戶空間的應用程序。
特別指出,cfg80211在內核空間提供配置管理服務,內核與應用層通過nl80211實現配置管理介面。需要記住的是,
硬MAC設備和軟MAC設備都需要cfg80211才能工作。而mac80211隻是一個驅動API,它只支持軟體實現的軟MAC設備。
接下來,我們主要關注軟MAC設備。
Linux內核無線子系統統一各種WiFi設備,並處理OSI模型中最底層的MAC、PHY兩層。
若進一步劃分,MAC層可以分為MAC高層和MAC底層。前者負責管理MAC層無線網路的探測發現、身份認證、關聯等;
後者實現MAC層如ACK等緊急操作。大部分情況下,硬體(如無線適配器)處理大部分的PHY層以及MAC底層操作。Linux子系統實現大部分的MAC高層回調函數。
2模塊間介面
從圖一中我們可以看出,各個模塊之間分界線很清晰,並且模塊間相互透明不可見。模塊之間一般不會相互影響。
舉個例子,我們在WiFi設備驅動做修改(如,打補丁、添加新的WiFi驅動等),這些變更並不會影響到mac80211模塊,
所以我們根本不用改動mac80211的代碼。再如,昆明北大青鳥http://www.kmbdqn.cn/建議添加一個新的網路協議理論上是不用修改套接字層以及設備無關層代碼。一般情況下,內核通過一系列的函數指針實現各層之間相互透明。
D. Linux內核API完全參考手冊的內容簡介
linux作為源碼開放的操作系統已經廣泛應用於計算機與嵌入式設備,因此學會linux內核開發與編程顯得越來越重要。本書以最新的linux內核版本2.6.30為依據,對常用的內核api作了系統分析和歸納,設計了典型實例並對開發場景進行了詳細講解。本書中分析的內核api模塊包括:內核模塊機制api、進程管理內核api、進程調度內核api、中斷機制內核api、內存管理內核api、內核定時機制api、內核同步機制api、文件系統內核api和設備驅動及設備管理api。
本書立足linux內核api分析,深入實踐,內容翔實,讀者可以從低起點進行高效的內核分析與編程實踐。本書可作為高等院校計算機、電子、信息類大學生及研究生進行linux操作系統學習和編程的教材或參考書,也可作為linux開發人員和廣大linux編程開發愛好者的參考用書。
E. linux下netlink的使用簡介
Netlink套接字是用以實現 用戶進程 與 內核進程 通信的一種特殊的進程間通信(IPC) ,也是網路應用程序與內核通信的最常用的介面。
在Linux 內核中,使用netlink 進行應用與內核通信的應用有很多,如
Netlink 是一種在內核與用戶應用間進行雙向數據傳輸的非常好的方式,用戶態應用使用標準的 socket API 就可以使用 netlink 提供的強大功能,內核態需要使用專門的內核 API 來使用 netlink。
一般來說用戶空間和內核空間的通信方式有三種: /proc、ioctl、Netlink 。而前兩種都是單向的,而Netlink可以實現雙工通信。
Netlink 相對於系統調用,ioctl 以及 /proc文件系統而言,具有以下優點:
Netlink協議基於BSD socket和 AF_NETLINK 地址簇,使用32位的埠號定址,每個Netlink協議通常與一個或一組內核服務/組件相關聯,如 NETLINK_ROUTE 用於獲取和設置路由與鏈路信息、 NETLINK_KOBJECT_UEVENT 用於內核向用戶空間的udev進程發送通知等。
用戶態應用使用標準的 socket API有sendto(),recvfrom(), sendmsg(), recvmsg()。
Netlink通信跟常用UDP Socket通信類似, struct sockaddr_nl 是netlink通信地址,跟普通 socket struct sockaddr_in 類似。
netlink_kernel_create內核函數用於創建內核socket與用戶態通信
首先將編譯出來的Netlink內核模塊插入到系統當中(insmod netlink_test.ko),然後運行應用程序,可以看到如下輸出:
F. linux 系統api 和kernel api 一樣么
linux kernel只提供一種叫系統調用給應用程序,linux系統提供了glibc這樣的函數庫專門封裝了內核提供的系統調用,所以應用程序的開發就直接調用glibc庫提供的庫函數就可以了。
註:1、linux系統包括linux kernel、glibc庫等。
2、因為應用程序調用系統調用是通過匯編指令完成的,所以才有了glibc的封裝,簡化了應用開發的難度。
kernel中提供的系統調用處理函數
sys_socket、sys_open、sys_close、sys_read、sys_write等
glibc中對應的是
socket、open、close、read、write等
glibc中的socket函數就是調用了int $0x80這條匯編指令,從而使cpu切換到內核態,執行sys_socket這個函數的。
函數調用流程:
socket->int $0x80->sys_socket。
現在2.6版本的內核提供了300多個系統調用:
glibc的下載地址:
http://ftp.gnu.org/gnu/glibc/
linux kernel的下載地址:
http://www.kernel.org/pub/linux/kernel/