1,linux內核的基礎知識
1.1 linux內核版本
從內核源碼頂層目錄Makefile中可以看到:
- VERSION和PATCHLEVEL組成主版本號,比如2.4、2.5、2.6等,穩定版本的德主版本號用偶數表示(比如2.6的內核),開發中的版本號用奇數表示(比如2.5),它是下一個穩定版本內核的前身。
- SUBLEVEL稱為次版本號,它不分奇偶,順序遞增,每隔1~2個月發布一個穩定版本。
- EXTRAVERSION稱為擴展版本號,它不分奇偶,順序遞增,每周發布幾次擴展本版號。
1.2 什么是標准內核
按照資料上的習慣說法,標准內核(或稱基礎內核)就是指主要在http://www.kernel.org/維護和獲取的內核,實際上它也有平台屬性的。這些linux內核並不總是適用於所有linux支持的體系結構。實際上,這些內核版本很多時候並不是為一些流行的嵌入式linux系統開發的,也很少運行於這些嵌入式linux系統上,這個站點上的內核首先確保的是在Intel X86體系結構上可以正常運行,它是基於X86處理器的內核,如對 linux-2.4.18.tar.bz2的配置make menuconfig時就可以看到,Processor type and features--->中只有386、486、586/K5/5x86/6x86/6x86MX、Pentium-Classic、Pentium-MMX、Pentium-Pro/Celeron/Pentium-II、Pentium-III/Celeron(Coppermine)、Pentium-4、K6/K6-II/K6-III 、Athlon/Duron/K7 、Elan 、Crusoe、Winchip-C6 、Winchip-2 、Winchip-2A/Winchip-3 、CyrixIII/C3 選項,而沒有類似Samsun 2410等其他芯片的選擇。如果需要用在其他特定的處理器平台上就需要對內核進行打補丁,形成不同的嵌入式內核。實際上,不同處理器系統的內核下載站點中提供的也往往是補丁patch而已,故原x86平台上的內核變成了基礎內核,也被稱為標准內核了。
ARM用的RISC精簡指令集,每條指令長度固定32bit;常用的100條匯編指令
X86的CISC復雜指令集,每條指令長度不固定。指令比上面多太多,但是常用的也差不多。
比如要移動內存里的一個數據,CISC可以一條實現,但是,精簡指令至少兩條或更多。
因此x86的內核就要比ARM內核的結構復雜很多,因此貴很多。
1.3 Linux操作系統的分類
第一種分類:以主要功能差異和發行組織區分(即基礎linux系統/內核是不同的)
- 標准linux
- μClinux(無MMU支持的linux系統,運行在無MMU的CPU上)
- Linux-RT(是最早在linux上實現硬實時支持的linux發行版本)
- Embedix(由Lineo公司開發,基於PowerPC和x86平台開發的)
- 其他
第二層分類中的linux系統/內核相對於第一層分類的標准內核來說,也可以稱為嵌入式linxu系統/內核。如應用在ARM平台上的嵌入式Linux系統通常有arm-linux(常運行在arm9平台上),μClinux(常用在arm7平台上),在標准linux基礎上擴展對其他的平台的支持往往通過安裝patch實現,如armlinux就是對linux安裝rmk補丁(如patch-2.4.18-rmk7.bz2)形成的,只有安裝了這些補丁,內核才能順利地移植到ARM Linux上。也有些是已經安裝好補丁的內核源碼包,如linux-2.4.18-rmk7.tar.bz2。
不同處理器系統的內核/內核補丁下載站點:
處理器系統 適合的內核站點 下載方式
x86 http://www.kernel.org/ ftp, http, rsync
ARM http://www.arm.linux.org.uk/developer/ ftp, rsync
PowerPC http://penguinppc.org/ ftp, http, rsync, BitKeeper
MIPS http://www.linux-mips.org/ ftp, cvs
SuperH http://linuxsh.sourceforge.net/ cvs, BitKeeper
M68K http://linux-m68k.org/ ftp, http
non-MMU CPUs http://www.uclinux.org/ ftp, http
這些站點不僅僅是linux內核站點,它們可能直接提供了針對你的目標硬件系統的linux內核版本。
1.4 linux內核的選擇
ARM Linux的移植,建議使用2.4.x或2.6.x版本。當然大部分你使用的硬件平台會提供linux內核的說明。
2,linux內核啟動過程
一個嵌入式 Linux 系統從軟件角度看可以分為四個部分:引導加載程序(Bootloader),Linux 內核,文件系統,應用程序。其中 Bootloader是系統啟動或復位以后執行的第一段代碼,它主要用來初始化處理器及外設,然后調用 Linux 內核。Linux 內核在完成系統的初始化之后需要掛載某個文件系統做為根文件系統(Root Filesystem)。根文件系統是 Linux 系統的核心組成部分,它可以做為Linux 系統中文件和數據的存儲區域,通常它還包括系統配置文件和運行應用軟件所需要的庫。應用程序可以說是嵌入式系統的“靈魂”,它所實現的功能通常就是設計該嵌入式系統所要達到的目標。如果沒有應用程序的支持,任何硬件上設計精良的嵌入式系統都沒有實用意義。
2.1Bootloader啟動過程
1)Bootloader概念和作用
Bootloader是嵌入式系統的引導加載程序,它是系統上電后運行的第一段程序,其作用類似於 PC 機上的 BIOS。
在完成對系統的初始化任務之后,它會將非易失性存儲器(通常是Flash或DOC等)中的Linux 內核拷貝到 RAM 中去,然后跳轉到內核的第一條指令處繼續執行,從而啟動 Linux 內核。
2)Bootloader的執行過程
實際應用中的 Bootloader根據所需功能的不同可以設計得很復雜,除完成基本的初始化系統和調用 Linux 內核等基本任務外,還可以執行很多用戶輸入的命令,比如設置 Linux 啟動參數,給 Flash 分區等;也可以設計得很簡單,只完成最基本的功能。但為了能達到啟動Linux 內核的目的,所有的 Bootloader都必須具備以下功能:
2.2linux啟動過程
Linux 內核有兩種映像:一種是非壓縮內核,叫 Image,另一種是它的壓縮版本,叫 zImage。根據內核映像的不同,Linux 內核的啟動在開始階段也有所不同。zImage 是 Image經過壓縮形成的,所以它的大小比 Image 小。但為了能使用 zImage,必須在它的開頭加上解壓縮的代碼,將 zImage 解壓縮之后才能執行,因此它的執行速度比 Image 要慢。但考慮到嵌入式系統的存儲空容量一般比較小,采用 zImage 可以占用較少的存儲空間,因此犧牲一點性能上的代價也是值得的。所以一般的嵌入式系統均采用壓縮內核的方式。
__lookup_processor_type調用結束返回原程序時,會將返回結果保存到寄存器中。其中r8 保存了頁表的標志位,r9 保存了處理器的 ID 號,r10 保存了與處理器相關的 stru proc_info_list 結構地址。
- 調用 setup_arch()函數進行與體系結構相關的第一個初始化工作;對不同的體系結構來說該函數有不同的定義。對於 ARM 平台而言,該函數定義在arch /arm/ kernel/Setup.c。它首先通過檢測出來的處理器類型進行處理器內核的初始化,然后通過 bootmem_init()函數根據系統定義的 meminfo 結構進行內存結構的初始化,最后調用paging_init()開啟 MMU,創建內核頁表,映射所有的物理內存和 IO空間。
- 創建異常向量表和初始化中斷處理函數;
- 初始化系統核心進程調度器和時鍾中斷處理機制;
- 初始化串口控制台(serial-console);ARM-Linux 在初始化過程中一般都會初始化一個串口做為內核的控制台,這樣內核在啟動過程中就可以通過串口輸出信息以便開發者或用戶了解系統的啟動進程。
- 創建和初始化系統 cache,為各種內存調用機制提供緩存,包括;動態內存分配,虛擬文件系統(VirtualFile System)及頁緩存。初始化內存管理,檢測內存大小及被內核占用的內存情況;
- 初始化系統的進程間通信機制(IPC);
execve("/sbin/init",argv_init,envp_init)
execve("/etc/init",argv_init,envp_init)
execve("/bin/init",argv_init,envp_init)
execve("/bin/sh",argv_init,envp_init)
當所有的初始化工作結束后,cpu_idle()函數會被調用來使系統處於閑置(idle)狀態並等待用戶程序的執行。至此,整個 Linux 內核啟動完畢。
通過對Linux 的啟動過程的分析,我們可以看出哪些是和硬件相關的,哪些是Linux 內核內部已實現的功能,這樣在移植Linux 的過程中便有所針對。而Linux內核的分層設計將使Linux 的移植變得更加容易。
大部分轉載自:https://blog.csdn.net/kelsey11/article/details/74075143