導航:首頁 > 編程語言 > linuxkernel編程

linuxkernel編程

發布時間:2024-05-10 03:01:35

linux內核編程的目錄

目錄
第1章概述1
1.1UNIX的歷史2
1.2標准和通用介面3
1.3自由軟體和開放源碼3
1.4Linux發布版概覽3
1.41Debian4
1.42Red Hat/Fedora 4
1.43Mandriva4
1.44SUSE4
1.45Gentoo4
1.46Yellow Dog5
1.47其他發布版5
1.5內核版本信息5
1.6基於Power的Linux5
1.7什麼是操作系統6
1.8內核組織7
1.9Linux內核概述7
1.9.1用戶介面7
1.9.2用戶標識符8
1.9.3文件和文件系統8
1.9.4進程12
1.9.5系統調用15
1.9.6Linux調度程序15
1.9.7Linux設備驅動程序15
1.10可移植性和體系結構的相關性16
1.11小結16
1.12習題16
第2章內核探索工具集18
2.1內核中常見的數據類型18
2.1.1鏈表18
2.1.2查找21
2.1.3樹22
2.2匯編24
2.2.1PowerPC24
2.2.2x8627
2.3匯編語言示例29
2.3.1x86中的匯編示例30
2.3.2PowerPC中的匯編示例31
2.4內聯匯編33
2.4.1輸出操作數34
2.4.2輸入操作數34
2.4.3已修改過的寄存器(已修改的元素列表) 34
2.4.4參數的編號方式34
2.4.5約束條件34
2.4.6asm35
2.4.7__volatile__35
2.5特殊的C 語言用法38
2.5.1asmlinkage38
2.5.2UL39
2.5.3內聯39
2.5.4const和volatile39
2.6內核探索工具一覽40
2.6.1objmp/readelf40
2.6.2hexmp41
2.6.3nm41
2.6.4obj42
2.6.5ar42
2.7內核發言:傾聽來自內核的消息42
2.7.1printk()42
2.7.2dmesg42
2.7.3/var/log/messages42
2.8其他奧秘43
2.8.1__init43
2.8.2likely()和unlikely()43
2.8.3IS_ERR和PTR_ERR44
2.8.4通告程序鏈44
2.9小結45
2.9.1項目:Hellomod45
2.9.2第一步:構造Linux模塊的框架45
2.9.3第二步:編譯模塊46
2.9.4第三步:運行代碼47
2.10習題48
第3章進程:程序執行的基本模型49
3.1程序51
3.2進程描述符52
3.2.1與進程屬性相關的欄位54
3.2.2與調度相關的欄位55
3.2.3涉及進程間相互關系的欄位58
3.2.4與進程信任狀相關的欄位59
3.2.5與進程權能相關的欄位60
3.2.6與進程限制相關的欄位61
3.2.7與文件系統及地址空間相關的欄位63
3.3進程的創建:系統調用fork()、vfork 和clone()64
3.3.1fork()函數65
3.3.2vfork()函數66
3.3.3clone()函數67
3.3.4do_fork()函數68
3.4進程的生命周期70
3.4.1進程的狀態70
3.4.2進程狀態的轉換71
3.5進程的終止74
3.5.1sys_exit()函數75
3.5.2do_exit()函數75
3.5.3通知父進程和sys_wait4()77
3.6了解進程的動態:調度程序的基本構架80
3.6.1基本結構80
3.6.2從等待中醒來或者激活81
3.7等待隊列86
3.7.1添加到等待隊列88
3.7.2等待事件89
3.7.3喚醒進程91
3.8非同步執行流程93
3.8.1異常93
3.8.2中斷95
3.9小結114
3.9.1項目:系統變數current114
3.9.2項目源碼115
3.9.3運行代碼116
3.10習題116
第4章內存管理117
4.1頁119
4.2內存管理區121
4.2.1內存管理區描述符122
4.2.2內存管理區操作輔助函數124
4.3頁面124
4.3.1請求頁面的函數124
4.3.2釋放頁面的函數126
4.3.3夥伴系統126
4.4Slab分配器130
4.4.1緩存描述符133
4.4.2通用緩存描述符135
4.4.3Slab描述符136
4.5Slab分配器的生命周期138
4.5.1與Slab分配器有關的全局變數138
4.5.2創建緩存139
4.5.3創建slab與cache_grow()144
4.5.4Slab的銷毀:退還內存與kmem_cache_destroy()146
4.6內存請求路徑147
4.6.1kmalloc()147
4.6.2kmem_cache_alloc()148
4.7Linux進程的內存結構149
4.7.1mm_struct150
4.7.2vm_area_struct152
4.8進程映像的分布及線性地址空間153
4.9頁表155
4.10缺頁156
4.10.1x86缺頁異常156
4.10.2缺頁處理程序157
4.10.3PowerPC缺頁異常164
4.11小結164
4.12項目:進程內存映射165
4.13習題166
第5章輸入/輸出167
5.1匯流排、橋、埠和介面的硬體實現167
5.2設備171
5.2.1塊設備概述172
5.2.2請求隊列和I/O 調度173
5.2.3示例:「通用」塊設備驅動程序180
5.2.4設備操作182
5.2.5字元設備183
5.2.6網路設備184
5.2.7時鍾設備184
5.2.8終端設備184
5.2.9直接存儲器存取184
5.3小結185
5.4項目:創建並口驅動程序185
5.4.1並口的硬體185
5.4.2運行在並口上的軟體187
5.5習題192
第6章文件系統194
6.1文件系統的基本概念194
6.1.1文件和文件名194
6.1.2文件類型195
6.1.3文件的附加屬性195
6.1.4目錄和路徑名196
6.1.5文件操作197
6.1.6文件描述符197
6.1.7磁碟塊、磁碟分區以及實現197
6.1.8性能198
6.2Linux虛擬文件系統198
6.2.1VFS的數據結構200
6.2.2全局鏈表和局部鏈表的引用211
6.3與VFS相關的結構212
6.3.1fs_struct結構212
6.3.2files_struct結構213
6.4頁緩存216
6.4.1address_space結構217
6.4.2buffer_head結構219
6.5VFS的系統調用和文件系統層221
6.5.1open()221
6.5.2close()227
6.5.3read()229
6.5.4write()244
6.6小結246
6.7習題246
第7章進程調度和內核同步247
7.1Linux的調度程序248
7.1.1選擇下一個進程248
7.1.2上下文切換253
7.1.3讓出CPU261
7.2內核搶佔269
7.2.1顯式內核搶佔269
7.2.2隱式用戶搶佔270
7.2.3隱式內核搶佔270
7.3自旋鎖和信號量272
7.4系統時鍾:關於時間和定時器274
7.4.1實時時鍾:現在幾點了274
7.4.2讀取PPC的實時時鍾276
7.4.3讀取x86的實時時鍾278
7.5小結280
7.6習題280
第8章內核引導281
8.1BIOS和Open Firmware282
8.2引導載入程序282
8.2.1GRUB283
8.2.2LILO286
8.2.3PowerPC和Yaboot286
8.3與體系結構相關的內存初始化287
8.3.1PowerPC的硬體內存管理287
8.3.2基於Intel x86體系結構的硬體內存管理296
8.3.3PowerPC和x86的代碼匯集305
8.4原始的RAM盤305
8.5開始:start_kernel()306
8.5.1調用lock_kernel()307
8.5.2調用page_address_init()309
8.5.3調用printk(linux_banner)311
8.5.4調用setup_arch311
8.5.5調用setup_per_cpu_areas()315
8.5.6調用smp_prepare_boot_cpu()316
8.5.7調用sched_init()317
8.5.8調用build_all_zonelists()319
8.5.9調用page_alloc_init319
8.5.10調用parse_args()320
8.5.11調用trap_init()322
8.5.12調用rcu_init()323
8.5.13調用init_IRQ()323
8.5.14調用softirq_init()324
8.5.15調用time_init()325
8.5.16調用console_init()326
8.5.17調用profile_init()326
8.5.18調用local_irq_enable()327
8.5.19配置initrd327
8.5.20調用mem_init()327
8.5.21調用late_time_init()333
8.5.22調用calibrate_delay()333
8.5.23調用pgtable_cache_init()334
8.5.24調用buffer_init()335
8.5.25調用security_scaffolding_startup()336
8.5.26調用vfs_caches_init()336
8.5.27調用radix_tree_init()343
8.5.28調用signal_init()344
8.5.29調用page_writeback_init()344
8.5.30調用proc_root_init()346
8.5.31調用init_idle()347
8.5.32調用rest_init()348
8.6init線程(或進程1)349
8.7小結353
8.8習題353
第9章構建Linux內核354
9.1工具鏈354
9.1.1編譯程序355
9.1.2交叉編譯355
9.1.3鏈接程序356
9.1.4ELF二進制目標文件356
9.2內核源代碼的構建360
9.2.1解釋源代碼360
9.2.2構建內核映像364
9.3小結369
9.4習題369
第10章向內核添加代碼371
10.1瀏覽源代碼371
10.11熟悉文件系統371
10.12filp和fops372
10.13用戶空間和內核空間374
10.14等待隊列375
10.15工作隊列及中斷378
10.16系統調用380
10.17其他類型的驅動程序380
10.18設備模型和sysfs文件系統383
10.2編寫代碼386
10.2.1設備基礎386
10.2.2符號輸出388
10.2.3IOCTL388
10.2.4輪詢與中斷391
10.2.5工作隊列和tasklet395
10.2.6增加系統調用的代碼396
10.3構建和調試398
10.4小結399
10.5習題400

⑵ Linux Kernel是什麼

Linux kernel 譯為linux 內核,其基礎為linux平台,linux為C語言編寫的內核,基於此內核又衍生出了具體的Red hat linux 、open suse linux等具體的操作系統,一套基於Linux內核的完整操作系統叫作Linux操作系統,或是GNU/Linux。

對於linux kernel,先看它的目錄結構,這里只挑幾個重要的說明。
arch 包括所有和體系結構相關的核心代碼。從裡面我們能看到arm、alpha、i386、mips、ia64這些文件夾,每種處理器架構都有不一樣的硬體模塊,這里就是要針對不同的架構進行不同的初始化。
init包含內核的初始化代碼(不是系統的引導代碼),其中有一個main.c文件,用於執行內核所有的初始化工作(包括初始化內存、初始化所有硬體、創建第一個任務task0,設置中斷允許標志位),然後移到用戶模式調用fork()函數創建新進程,並在控制台運行shell。
kernel 包含內核管理的核心代碼,瞅這名就知道,這貨是個重量級目錄,所有的處理任務的程序,包括fork、exit、調度程序(sched.c)以及一些系統調用(sys.c)、信號處理(signal.c)、時間函數(time.c),還有中斷異常處理、電源管理等等一系列調用關系錯綜復雜的函數。
mm 包含所有的內存管理代碼。其中包括實現進程的邏輯地址到實際物理地址的映射,實現分頁、分段機制,實現內存頁面異常中斷處理程序等。
drivers包含系統中所有的設備驅動程序,比如什麼cdrom啊bluetooth啊pci、i2c這些。
ipc 包含核心進程間的通信代碼。
fs 存放Linux支持的文件系統代碼,裡面有ext2、ext3、ext4、fat、ntfs等等一堆目錄。
net 內核的網路部分代碼,其每個子目錄對應於網路的一個方面,比如ieee80211、ipv4、ipv6這些目錄。
lib 包含核心的庫代碼,什麼strcpy、sprintf、sort這些函數都在裡面。更多Linux知識可參考《Linux就該這么學》。

⑶ 什麼是linux kernel有什麼作用

Linux內核(英語:Linux kernel)是一種開源的類Unix操作系統宏內核。

工作於平板電腦、智能手機及智能手錶的Android操作系統同樣通過Linux內核提供的服務完成自身功能。

一個計算機系統是一個硬體和軟體的共生體,它們互相依賴,不可分割。計算機的硬體,含有外圍設備、處理器、內存、硬碟和其他的電子設備組成計算機的發動機。但是沒有軟體來操作和控制它,自身是不能工作的。

完成這個控制工作的軟體就稱為操作系統,在Linux的術語中被稱為「內核」,也可以稱為「核心」。Linux內核的主要模塊(或組件)分以下幾個部分:存儲管理、CPU和進程管理、文件系統、設備管理和驅動、網路通信,以及系統的初始化(引導)、系統調用等。

整個Linux操作系統家族基於該內核部署在傳統計算機平台(如個人計算機和伺服器,以Linux發行版的形式)和各種嵌入式平台,如路由器、無線接入點、專用小交換機、機頂盒、FTA接收器、智能電視、數字視頻錄像機、網路附加存儲(NAS)等。

工作於平板電腦、智能手機及智能手錶的Android操作系統同樣通過Linux內核提供的服務完成自身功能。盡管於桌面電腦的佔用率較低,基於Linux的操作系統統治了幾乎從移動設備到主機的其他全部領域。截至2017年11月,世界前500台最強的超級計算機全部使用Linux。

(3)linuxkernel編程擴展閱讀:

編程語言

Linux是用C語言中的GCC版(這種C語言有對標准C進行擴展)寫的,還有幾個用匯編語言(用的是GCC的"AT&T風格")寫的目標架構短段。因為要支持擴展的C語言,GCC在很長的時間里是唯一一個能正確編譯Linux的編譯器。

有許多其他的語言用在一些方面上,主要集中在內核構建過程中(這里指從源代碼創建可引導鏡像)。包括Perl、Python和多種腳本語言。有一些驅動可能是用C++、Fortran或其他語言寫的,但是這樣是強烈不建議的。

編譯器兼容性

GCC是Linux內核源代碼的預設編譯器。在2004年,Intel主張通過修改內核,以便Intel C++編譯器能正確編譯內核。在2009年,有通過修改內核2.6.22版而成功編譯的報告(並帶來平均8-9%性能增長)。

自從2010年,已經開始進行使用Clang建造Linux內核的努力,Clang是一個可作為替代的C語言編譯器;截止2014年4月12日,官方內核幾乎可以完全用Clang編譯。致力於這個目標的計劃叫做「LLVMLinux」,得名於Clang所基於的LLVM編譯器下部構造。

LLVMLinux不意圖復制Linux內核或LLVM,因此它是由最終提交給上游計劃的補丁構成的一個元計劃。使Linux內核可以用Clang編譯最大的好處是比GCC有更快的編譯速度,內核開發者可以得益於由此而來的更快的工作流程

⑷ 什麼是LINUX內核編程

真佩服樓上的2位對「內核編程」的理解力!
簡單說,Linux內核編程就是開發Linux驅動程序,學會內核編程後,將會對操作系統的內部機制和工作原理有充分了解,可以從事硬體驅動開發、嵌入式系統開發等。內核編程的語言仍是傳統的C語言,但其編寫方法和調用介面與傳統應用程序的差別較大,你必須了解如何處理中斷、如何在內核態和用戶態之間轉換、PCI、DMA、內核地址映射、內核I/O等,這不是《UNIX高級編程》所涉及的內容,可以找一本專門講Linux驅動編程的書看看,或在網上搜尋相關資料(關鍵詞:Linux DDK)。不過先提醒一句,學習內核編程的難度很大,必須做好長期心理准備

⑸ linux編譯內核步驟

一、准備工作
a) 首先,你要有一台PC(這不廢話么^_^),裝好了Linux。
b) 安裝好GCC(這個指的是host gcc,用於編譯生成運行於pc機程序的)、make、ncurses等工具。
c) 下載一份純凈的Linux內核源碼包,並解壓好。

注意,如果你是為當前PC機編譯內核,最好使用相應的Linux發行版的源碼包。

不過這應該也不是必須的,因為我在我的Fedora 13上(其自帶的內核版本是2.6.33.3),就下載了一個標準的內核linux-2.6.32.65.tar.xz,並且順利的編譯安裝成功了,上電重啟都OK的。不過,我使用的.config配置文件,是Fedora 13自帶內核的配置文件,即/lib/moles/`uname -r`/build/.config

d) 如果你是移植Linux到嵌入式系統,則還要再下載安裝交叉編譯工具鏈。

例如,你的目標單板CPU可能是arm或mips等cpu,則安裝相應的交叉編譯工具鏈。安裝後,需要將工具鏈路徑添加到PATH環境變數中。例如,你安裝的是arm工具鏈,那麼你在shell中執行類似如下的命令,假如有類似的輸出,就說明安裝好了。
[root@localhost linux-2.6.33.i686]# arm-linux-gcc --version
arm-linux-gcc (Buildroot 2010.11) 4.3.5
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for ing conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
註:arm的工具鏈,可以從這里下載:回復「ARM」即可查看。

二、設置編譯目標

在配置或編譯內核之前,首先要確定目標CPU架構,以及編譯時採用什麼工具鏈。這是最最基礎的信息,首先要確定的。
如果你是為當前使用的PC機編譯內核,則無須設置。
否則的話,就要明確設置。
這里以arm為例,來說明。
有兩種設置方法():

a) 修改Makefile
打開內核源碼根目錄下的Makefile,修改如下兩個Makefile變數並保存。
ARCH := arm
CROSS_COMPILE := arm-linux-

注意,這里cross_compile的設置,是假定所用的交叉工具鏈的gcc程序名稱為arm-linux-gcc。如果實際使用的gcc名稱是some-thing-else-gcc,則這里照葫蘆畫瓢填some-thing-else-即可。總之,要省去名稱中最後的gcc那3個字母。

b) 每次執行make命令時,都通過命令行參數傳入這些信息。
這其實是通過make工具的命令行參數指定變數的值。
例如
配置內核時時,使用
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
編譯內核時使用
make ARCH=arm CROSS_COMPILE=arm-linux-

注意,實際上,對於編譯PC機內核的情況,雖然用戶沒有明確設置,但並不是這兩項沒有配置。因為如果用戶沒有設置這兩項,內核源碼頂層Makefile(位於源碼根目錄下)會通過如下方式生成這兩個變數的值。
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
ARCH?= $(SUBARCH)
CROSS_COMPILE ?=

經過上面的代碼,ARCH變成了PC編譯機的arch,即SUBARCH。因此,如果PC機上uname -m輸出的是ix86,則ARCH的值就成了i386。

而CROSS_COMPILE的值,如果沒配置,則為空字元串。這樣一來所使用的工具鏈程序的名稱,就不再有類似arm-linux-這樣的前綴,就相當於使用了PC機上的gcc。

最後再多說兩句,ARCH的值還需要再進一步做泛化。因為內核源碼的arch目錄下,不存在i386這個目錄,也沒有sparc64這樣的目錄。

因此頂層makefile中又構造了一個SRCARCH變數,通過如下代碼,生成他的值。這樣一來,SRCARCH變數,才最終匹配到內核源碼arch目錄中的某一個架構名。

SRCARCH := $(ARCH)

ifeq ($(ARCH),i386)
SRCARCH := x86
endif

ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif

ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif

ifeq ($(ARCH),sh64)
SRCARCH := sh
endif

三、配置內核

內核的功能那麼多,我們需要哪些部分,每個部分編譯成什麼形式(編進內核還是編成模塊),每個部分的工作參數如何,這些都是可以配置的。因此,在開始編譯之前,我們需要構建出一份配置清單,放到內核源碼根目錄下,命名為.config文件,然後根據此.config文件,編譯出我們需要的內核。

但是,內核的配置項太多了,一個一個配,太麻煩了。而且,不同的CPU架構,所能配置的配置項集合,是不一樣的。例如,某種CPU的某個功能特性要不要支持的配置項,就是與CPU架構有關的配置項。所以,內核提供了一種簡單的配置方法。

以arm為例,具體做法如下。

a) 根據我們的目標CPU架構,從內核源碼arch/arm/configs目錄下,找一個與目標系統最接近的配置文件(例如s3c2410_defconfig),拷貝到內核源碼根目錄下,命名為.config。

注意,如果你是為當前PC機編譯內核,最好拷貝如下文件到內核源碼根目錄下,做為初始配置文件。這個文件,是PC機當前運行的內核編譯時使用的配置文件。
/lib/moles/`uname -r`/build/.config
這里順便多說兩句,PC機內核的配置文件,選擇的功能真是多。不編不知道,一編才知道。Linux發行方這樣做的目的,可能是想讓所發行的Linux能夠滿足用戶的各種需求吧。

b) 執行make menuconfig對此配置做一些需要的修改,退出時選擇保存,就將新的配置更新到.config文件中了。

閱讀全文

與linuxkernel編程相關的資料

熱點內容
怎麼殺掉伺服器上所有進程 瀏覽:177
c語言中水仙花數的演算法分析 瀏覽:493
心煩時玩兒的解壓神器 瀏覽:494
linux安裝的庫文件 瀏覽:915
加密貨幣架構分析 瀏覽:521
我的世界怎麼把材料包加到伺服器里 瀏覽:755
平板內存卡新建文件夾失敗 瀏覽:203
python模塊打包 瀏覽:360
騰訊雲伺服器centos沒有桌面 瀏覽:890
冒泡排序演算法實驗心得 瀏覽:686
php入侵教程 瀏覽:102
航電伺服器地址 瀏覽:23
pdf是撒 瀏覽:487
五格數學演算法 瀏覽:171
伺服器怎麼添加連接 瀏覽:16
排列組合a演算法 瀏覽:985
伺服器迷你號是什麼 瀏覽:779
有什麼免費的雲伺服器地址 瀏覽:576
微信為什麼總是連接伺服器失敗 瀏覽:642
伯里曼手pdf 瀏覽:769