原创 linux內核編程基磯

2010-6-23 11:36 1941 2 2 分类: MCU/ 嵌入式

linux內核的發展與演變


版本  時間         特點


0.1     1991.10    最初原型


1.0     1994.3      包含了對386的官方支持,僅支持單CPU系統


1.2     1995.3      第一個多平台支持的官方版本


2.0      1996.6     包含更多的新平台支持,第一個支持SMP體系的內核版本


2.2       1999.1    極大提升了SMP系統的性能,並支持更多的硬件


2.4        2001.1   進一步提升了SMP的擴展性,同時也集成了很多用於支持桌面系


                            統的特性,如USB,PC卡(PCMCIA)的支持和內置的即插即用


2.6        2003.12  


Linux 2.6 內核的特點


linux 2.6相對於linux2.4有相當大的改進,主要體現如下幾個方面:


1.新的調度器


2.6版本內核使用新的進程高度算法,它在高負載的情況下執行極其出色,並且多處理器時也可以很好的擴展


2 內核搶占


2.6 內核中, 內核任務可以被搶占,從而提高系統的實時性。可以極大地增強用戶的交互性。


3 改進的線程模型


2.6 的內核中線程的操作速度得以提高,可以處理任意數目的線程,PID最大可以到2,000,000,000。


4 虛擬內存的變化


2.6內核融合了r-map(反向映射)技朮,顯著改善虛擬內存在一定程度負載下的性能。


5 文件系統


2.6 版本內核增加了對日志文件系統功能的支持,解決了2.4版本的linux內核在這方面性能的不足。2.6版本的內核在文件系統上的關鍵變化還包括對擴展屬性及POSIX標准訪控制的支持。Ext2/Ext3作為大多數linux系統缺省安裝的文件系統,在2.6版本的linux內核中增加了對擴展屬性的支持,可以給指定的文件在文件系統中嵌入元數據。


6 音頻


新的linux音頻體系結構ALSA取代缺陷很多的舊的OSS。親的聲音體系結構支持USB音頻和MIDI設備,並支持全雙工重放等功能。


7 總線


SCSI/IDE子系統經過大幅度的重寫,解決和改善了以前的一些問題。比如2.6的內核可以直接通過IDE驅動程序來支持IDE CD/RW設備,而不必像以前那樣使用一個特別的SCSI模擬驅動程序。


8 電源管理


支持ACPI,用於調整CPU在不同的負載下工作於不同的時鐘頻率以降低功耗。


9 聯網和IPSec


2.6 內核加入了對IPSec的支持,刪除了原來內核內置的HTTP服務器kttpd,加入了對新的NFSv4客戶機/服務器的支持,並改進了對IPv6的支持。


10 用戶界面層


2.6 內核重寫了幀緩沖/控制臺層,人機界面層還增加了對大多數接口設備的支持(從觸摸屏到盲人用的設備和各種各樣的鼠標)。


在設備驅動程序方面,2.6相對2.4也有軿大的改動,主要表現在內核API中增加了不少新功能(例如內存池),sysfs文件系統,內核模塊從.o變為.ko,驅動模塊編譯方式,模塊使用計數,模塊加載和卸載函數的定義等方面。


Linux 內核的組成


Linux 內核源代碼目錄結構


arch: 包含和硬件体系結构相關的代碼,每种平台占一個相應的目錄,如i386,ARM,PowrPC,MIPS等。


block:塊設備驅動程序和I/O調度。


cyrpto:常用加密和散列算法(如AES,SHA等),還有一些壓縮各和CRC校驗算法。


Documentation:內核各部分的通用解釋和注釋。


drivers:設備驅動程序,每個不同的驅動程序占一個目錄,如char,block,net,mtd,i2c等。


fs:支持的各種文件系統,如EXT,FAT,NFS,JFFS2等。


include: 頭文件,與系統相關的頭文件被放置在include/linux下。


init:內核初始化代碼。


ipc:進程間通信的代碼。


kernel:內核最核心部分,包括進程調度,定時器等,而和平臺相關的一部分代碼放在arch/*/kernel目錄下。


lib:庫文件代碼。


mm:內存管理代碼,和平台相關的一部分代碼放在arch/*/mm目錄下。


net:網絡相關代碼,實現了各種常見的網絡協議。


scripts:包含用于配置內核的腳本文件。


security:主要包含SELinux模塊。


sound:ALSA,OSS音頻設備的驅動核心代碼和常用設備驅動。


usr:實現了用於打包和壓縮的cpio等。


Linux內核的組成部分


linux內核主要由進程高度(SCHED),內存管理(MM),虛擬文件系統(VFS),網絡接口(NET起),進程間通信(IPC)行動5個子系組成。


1.進程調度


精度調控系統中多個進程對CPU的訪問使得多個進程能在CPU中微觀串行,宏觀並行地執行。進程調度處于系統的中心位置,內核中的其它子系統都依賴它,因為每個子系統都需要挂起或恢復進程。


2.內存管理


內存管理的主要作用是控制多個進程安全地共享主內存區域。當CPU提供MMU時,linux內存管理完成為每個進程進行虛擬內存到熱物理內存的轉換。linux 2.6引入 對無MMU CPU的支持。


一般,linux每個進程享有4GB的內存空間,0~3GB屬于用戶空間,3~4GB屬于內核空間,內核空間對常規內存,I/O設備內存以及高端內存存在不同的處理方式。


3.虛擬文件系統


VFS隱藏了各種硬件的具體細節,為所有的設備提供了統一的接口。而且,它獨立於各個具體的文件系統,是對各種文件系統的一個抽象,它使用超級塊super block存放文件系統的相關信息,使用索引節點inoded存放文件的物理信息,使用目錄項dentry存放文件的邏輯信息。


4.網絡接口


網絡接口提供了對各種網絡的標准的存取和各種網絡硬件的支持。網絡接口可分為網絡協議和網絡驅動程序,網絡協議部分負責實現每一種可能的網絡傳輸協議,網絡設備驅動程序負責與硬件設備進行通信,每一種可能的硬件都有相應的設備驅動程序。


5.進程通信


Linux支持進程間的多種通信機制,包含信號量,共享內存,管道等,這些機制可協助多個進程,多資源的互斥訪問,進程間的同步操作和消息傳遞。


Linux 內核空間與用空間


現代CPU內部往往實現了不同的操作模式(級別)。


ARM處理器的7種工作模式:


用戶模式(user):大多數的應用程序運行在用戶模式下,當處理器運行在用戶模式下時,某些被保護的系統資源是不能被訪問的。


快速模式(frq):用於高速數據傳輸或通道處理。


外部中斷模式(irq):用于通用的中斷處理。


管理模式(srvc):操作系統使用的保護模式。


數據訪問終止模式(abt):當數據或指令預取終止時進入該模式,可用於虛擬存儲及存儲保護。


系統模式(sys):運行具有特權的操作系統任務。


未定義模式(und):當未定義的指令執行時進入該模式,可用於支持硬件協處理器的軟件仿真。


linux系統充分利用CPU這一硬件特性,但它只使用兩級。內核空間和用戶空間被用來區分程序執行的兩種不同狀態,它們使用 不同的地址空間。linux系統只能通過系統調用和硬件中斷完成從用戶空間到內核空間的控制轉移。


Linux內核編譯和加載


Linux內核編譯


linux 2.6.15.5編譯過程


(1)下載內核原碼到/usr/src目錄


(2)下載modutils工具


module-init-tools:httlp://www.kernel.org/pub/linux/utils/kernel/module-init-tools/


modutils:http://www.kernel.org/pub/linux/utils/kernel/modutils/


(3)安裝modutils


#rpm -e --nodeps modutils(強行卸載modutils RPM包)


#rpm -ivh modutils-2.4.5-1.src.rpm(源代碼包安裝到/usr/src/redhat)


#cd /usr/src/redhat/SPECS(進入規范文件目錄)


#rpmbuild --bb modutils.spec(生成二井制的RPM包)


#cd ../RPMS/i386(轉入剛生成的二進制的RPM包的所在位置)


#rpm -ivh modutils*.rpm(安裝生成的modutils-2.4.5-1.i386.rpm和modutils-debuginfo-2.4.5-1.i386.rpm二進制RPM包)


(4)安裝modutils-init-tools,它會替代depmod和其它工具


#tar -jxvf module-init-tools-3.2.2.tar.bz2


#cd module-init-tools


#./configure --prefix=/sbin


#make


#make install


#./generate-modprobe.conf  /etc/modprobe.conf


(5)解壓縮內核代碼,


#cd /usr/src


#tar -jxvf linux-2.6.15.5.tar.bz2


#ln -s linux-2.6.15.5 linux


#cd linux


(6)執行make mrprober,確保源代碼目錄下沒有不正確的.o文件以及文件的互相依賴。源程序如果多次被使用過,編譯前應運行這步。


(7)配置內核


make config,make menuconfig,make xconfig,make gconfig.


常用配置項目:


Code maturity level option 代碼成熟等級。"prompt for development and/or incomplete code/drivers,如實驗階段,設為"Y"


Loadable module support(內核模塊支持)


5個子項,,"Enable loadable module support","Module versioning support","Automoatic Kernel module loading"3項默認選中。


General setup(通用設置)


File system:包含多種文件系統的設置徒勞項。


Processor type and features 處理器類型和特征。


Device drivers


(8)編譯內核,並復制至相應目錄


#make bzImage(gzip壓縮內核,位於/usr/src/linux/arch/i386/boot)


#make modules modules_install(編譯內核模塊並安裝到/lib/modules/2.6.15.5)


#cd /usr/src/linux


#mv arch/i386/boot/bzImage /boot/bzImage2.6.15.5


#cd /boot


#mv System.map System.map.bak


#ln -s System.map-2.6.15.5 System.map 換掉內核符號表


(9)針對新舊內核差異修改腳本和配置文件


2.6增加了sysfs文件系統,修改啟動腳本,fstab,新增sysfs的挂載;內核符號文件/proc/ksysms在2.6改為/proc/kallsyms,修改啟動腳本/etc/rc.sysinit;usb鍵盤和鼠標


模塊名稱的變換,修改啟動腳本。


(10)設置initrd


若SCSI,EXT3等編譯成模塊,必須設置initrd否則啟動時會提示"VFS:unable to mounting root fs".


initrd (Bootloader initialized RAM disk)是由Bootloader初始化的內存盤。linux內核啟動前,Bootloader會將存儲介質中的initrd文件加載到內存,內核會先訪問initrd文件系統,完成驅動模塊加載,主要完成文件系統存儲介質的驅動模塊,再訪問根文件系統,執行/sbin/init進程。


為配置initrd,需下載mkinitrd->(依賴於)->device-mapper->lvm2


 


(11)修改grub文件,新增啟動項


title linux-2.6.15.5


      root (hdx,x)


     kernel /boot/bzImage2.6.15.5 ro root="/dev/sda1 hdc="ide-scsi""


Kconfig和Makefile


內核配置系統由3部分組成,


Makefile:分布在Linux內核源代碼中的Makefile,定義Linux內核編譯規則。


配置文件Kconfig:給用戶提供配置選擇的功能。


配置工具:包括配置命令解釋器和配置用戶界面。使用make config,make menuconfig等命令後, 會生成一個.config配置文件(隱含在頂層Makefile中),記錄哪些部分被編譯入內核,哪些部分被編譯成內核模塊。


make menuconfig->arch/XXX/Kconfig->source "xxx/Kconfig"->xxx/Kconfig->source "xxx/Kconfig"


make zImage->Makefile(arch/xxx/Makefile,頂層,補充體系結构相關信息)->xxx/Makefile(遞歸).


在內核中增加程序需要完成3項工作:


1.在內核源代碼中新增源代碼程序文件


2.在目錄的Kconfig文件中增加源代碼對應的項目的編譯選項


3.在新增目錄的Makefile文件中增加對新源代碼的編譯規則


Kconfig 語法規則


(1)菜單入口


config MODEXX


      bool "modexx"


       depends on MODEDEP


        help


            Help notice 


"config"關鍵字定義新的配置選項,之後的几行定義了該配置選項的屬性。配置選項的屬性包括類型,數據范圍,輸入提示,依賴關系(及反向依賴關系),幫助信息和默認值等。


每個配置選項必須指定類型,bool,tristate,string,hext,init,tristate和string是基本類型,其他類型基於這兩種類型。類型定義後跟輸入提示:


bool "prompt"


等價於


bool


prompt "prompt"


輸入提示一般格式:prompt <prompt> [if <expt>]


if 可選項用來提示依賴關系。


默認值的格式:default <expr> [if <expr>]


一個配置選項可以存在多個默認值,這種情況下,只有第一個被定義的值是可用的。如果用戶不設對應的選 項,配置選項的值就是默認值。


依賴關系的格式如下所示:depends on(或requires) <expr>


如果定義了多個依賴關系,它之間用"&&"間隔。依賴關系也可以用到該菜單中所有的其他選項中,


bool "prompt" if expr1


default y if  exprt1


等價於


de[ends on expr1


bool "prompt"


default y


反向依賴關系的格式:select <symbol> [if <expr>]


depends能定義一個symbol的上限,如果A依賴於B,B為“Y"時,A可為"Y"/"M"


/"N";若B為"M",A可選"M"/"N";B為"N",A只能為"N"


select能限定一個symbol的下限,若A反依賴於B,A的值會高於或等於B,與depends相反。如若symbol依賴於多個對象,則symbol是所有依賴對象的最大值。


Makefile的expr(表達式)是由symbol,兩 個symbol相等,不等,以及expr的賦值,與,或,非運算构成的。symbol分為兩 類,一類是由菜單入口定義配置的非常數symbol,另一類是作為expr組成部分的常數symbol.


數據范圍格式:rang <symbol> <symbol> [if <expr>]


為init和hex類型的選項設置可以接受的輸入值范圍,用戶只能輸入一個大於等於第一個symbol,小於等於第二個symbol的值。


menuconfig關鍵字的作用與config 類似,但它在config基磯上要求所有的子選項作為獨立的行顯示。


(2)菜單結構


菜單入口在菜單結構中的位置可由兩種方法決定。第一種方式如下:


menu "conifg-menu"


        depends on DEPEND


config CONFIG


        ...


endmenu


位於menu和endmenu之間的菜單入口都會成為"config-menu"的子菜單。而且所有子菜單都會繼承父菜單的依賴關系。


另一種方式是通過分析依賴關系生成菜單結構。如果菜單一定程度上依賴於前面的選項,它就能成為該選項的子菜單。如果父選項為"N",則子選項不可見。如:


config MODULES


        bool "Enable ..."


config MODVERSION


       bool "Set ..."


       depends on MODULES


comment "nodule support disabled"


          depends on !MODULES


除此之外,Kconfig還可能使用"choices ... endchoice","comment","if ... endif"這樣的語法結構。


choice


<choice options>


<choice block>


endchoice


Makefile語法


(1)目標定義


目標定義哪些內容以模塊編譯或編譯連接進內核中。


obj-y += module.o 連接進內核中


obj-m += module.o 模塊編譯


obj-$(CONFIG_ISDN) += isdn.o 以CONFIG_變量決定編譯方式。


(2)多文件模塊定義


如果一個模塊由多個文件組成,這時候應采用模塊名加-objs或-y後綴的形式來定義模塊的組成文件。


obj-$(CONFIG_EXT2_FS) += ext2.o


ext2-y := balloc.o bitmap.o


ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o


(3)目錄層次的迭代


obj-$(CONFIG_EXT2_FS) += ext2/


當CONFIG_EXt2_FS為y或m時,kBuild將會把ext2目錄列入向下迭代的目標中,ext2目錄下文件的編譯規則由ext2目錄下的Makefile決定。


Linux內核的引導


1.引導過程


上電復位->系統啟動(BIOS)->MBR(Bootloader第一階段)->LILO,gurb(Bootloader第二階段)->內核->運行init進程(用戶空間)


 


 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
2
关闭 站长推荐上一条 /2 下一条