2016-2022 All Rights Reserved.平安財(cái)經(jīng)網(wǎng).復(fù)制必究 聯(lián)系QQ280 715 8082 備案號(hào):閩ICP備19027007號(hào)-6
本站除標(biāo)明“本站原創(chuàng)”外所有信息均轉(zhuǎn)載自互聯(lián)網(wǎng) 版權(quán)歸原作者所有。
今天來(lái)說(shuō)一下關(guān)于uCLinux是什么及uCLinux有什么用這方面的一些訊息,不少朋友對(duì)于uCLinux是什么及uCLinux有什么用這方面的信息頗感興趣的。小編今天就為此整理一些相關(guān)的訊息,希望對(duì)有需要的朋友有所幫助。
uCLinux 表示 micro-control linux.即“微控制器領(lǐng)域中的 Linux 系統(tǒng)”,是 Lineo 公司的主打產(chǎn)品,同時(shí)也是開放源碼的嵌入式 Linux 的典范之作。uCLinux 主要是針對(duì)目標(biāo)處理器沒有存儲(chǔ)管理單元 MMU(Memory Management Unit)的嵌入式系統(tǒng)而設(shè)計(jì)的。它已經(jīng)被成功地移植到了很多平臺(tái)上。由于沒有 MMU,其多任務(wù)的實(shí)現(xiàn)需要一定技巧。
uclinux
簡(jiǎn)介
Linux 是一種很受歡迎的操作系統(tǒng),它與 UNIX 系統(tǒng)兼容,開放源代碼。它原本被設(shè)計(jì)為桌面系統(tǒng),現(xiàn)在廣泛應(yīng)用于服務(wù)器領(lǐng)域。而更大的影響在于它正逐漸的應(yīng)用于嵌入式設(shè)備。uClinux 正是在這種氛圍下產(chǎn)生的。在 uClinux 這個(gè)英文單詞中 u 表示 Micro,小的意思,C 表示 Control,控制的意思,所以 uClinux 就是 Micro-Control-Linux,字面上的理解就是”針對(duì)微控制領(lǐng)域而設(shè)計(jì)的 Linux 系統(tǒng)”。
uClinux 是嵌入式 Linux 領(lǐng)域非常重要的分支,已成功應(yīng)用于路由器、機(jī)頂盒、PDA 等領(lǐng)域,與標(biāo)準(zhǔn) Linux 在內(nèi)存管理方面有著本質(zhì)的區(qū)別。
uCLinux 是一種優(yōu)秀的嵌入式 Linux 版本,是 micro-Controller-Linux 的縮寫。它秉承了標(biāo)準(zhǔn) Linux 的優(yōu)良特性, 經(jīng)過各方面的小型化改造,形成了一個(gè)高度優(yōu)化的、代碼緊湊的嵌入式 Linux。雖然它的體積很小,卻仍然保留了 Linux 的大多數(shù)的優(yōu)點(diǎn):穩(wěn)定、良好的移植性、優(yōu)秀的網(wǎng)絡(luò)功能、對(duì)各種文件系統(tǒng)完備的支持和標(biāo)準(zhǔn)豐富的 API。它專為嵌入式系統(tǒng)做了許多小型化的工作,目前已支持多款 CPU。 其編譯后目標(biāo)文件可控制在幾百 KB 數(shù)量級(jí),并已經(jīng)被成功地移植到很多平臺(tái)上。
uClinux 從 Linux 2.0/2.4 內(nèi)核派生而來(lái),沿襲了 Linux 的絕大部分特性。它是專門針對(duì)沒有 MMU(內(nèi)存管理單元)的 CPU,并且為嵌入式系統(tǒng)做了許多小型化的工作。它通常用于具有很少內(nèi)存或 Flash 的嵌入式操作系統(tǒng)。在 GNU 通用許可證的保證下,運(yùn)行 uClinux 操作系統(tǒng)的用戶可以使用幾乎所有的 Linux API 函數(shù)。由于經(jīng)過了裁剪和優(yōu)化,它形成了一個(gè)高度優(yōu)化,代碼緊湊的嵌入式 Linux。它具有體積小、穩(wěn)定、良好的移植性、優(yōu)秀的網(wǎng)絡(luò)功能、完備的對(duì)各種文件系統(tǒng)的支持,以及豐富的 API 函數(shù)等優(yōu)點(diǎn)。uClinux 與 Linux 在兼容性方面表現(xiàn)出色,uClinux 除了不能實(shí)現(xiàn) fork()外,其余 uClinux 的 API 函數(shù)與標(biāo)準(zhǔn) Linux 完全相同。
針對(duì)沒有 MMU 的 CPU
全球每年生產(chǎn)的 CPU 的數(shù)量大概在二十億顆左右,其中大部分是應(yīng)用于專用性很強(qiáng)的各類嵌入式系統(tǒng)。大部分嵌入式系統(tǒng)為了減少系統(tǒng)復(fù)雜程度、降低硬件及開發(fā)成本和運(yùn)行功耗,在硬件設(shè)計(jì)中取消了內(nèi)存管理單元(MMU)模塊。最初,運(yùn)行于這類沒有 MMU 的 CPU 之上的都是一些很簡(jiǎn)單的單任務(wù)操作系統(tǒng),或者更簡(jiǎn)單的控制程序,甚至根本就沒有操作系統(tǒng)而直接運(yùn)行應(yīng)用程序。在這種情況下,系統(tǒng)無(wú)法運(yùn)行復(fù)雜的應(yīng)用程序,或者效率很低,并且所有的應(yīng)用程序需要重新開發(fā),還要求開發(fā)人員十分了解硬件特性。這些都阻礙了不含 MMU 的嵌入式產(chǎn)品開發(fā)的速度和應(yīng)用水平。
uClinux 專門針對(duì)沒有 MMU 的 CPU,并且為嵌入式系統(tǒng)做了許多小型化的工作。uClinux 是一個(gè)完全符合 GNU/GPL 公約的項(xiàng)目,完全開放代碼。
最初的 uClinux 僅僅支持 Palm 硬件系統(tǒng),基于 Linux 2.0 內(nèi)核。隨著系統(tǒng)的日益改進(jìn),支持的內(nèi)核版本從 2.0、2.2、2.4 一直到現(xiàn)在最新的 2.6。系統(tǒng)的開發(fā)人員從兩人增加到了目前的 12 人,支持的硬件系統(tǒng)也從一種增加到了目前的十余種(支持的硬件平臺(tái)如 Motorola 公司的 M68328、M68EN322、MC68360、DragonBall 系列如 68EZ328、68VZ328,ColdFire 系列的如 5272、5307,ARM 7TDMI、MC68EN302、ETRAX、Intel i960、PRISMA、Atari 68k 等等。)
根據(jù) Linuxdevices 網(wǎng)站 2004 年 3 月的調(diào)查,uClinux 在全球嵌入式 Linux 市場(chǎng)所占的份額已位居第二,僅僅落后于定制 Linux(即自己下載源碼進(jìn)行修改定制)。同時(shí) Linux 在全球嵌入式操作系統(tǒng)的市場(chǎng)份額依然處于統(tǒng)治地位(占 40%以上),領(lǐng)先第二名微軟公司的嵌入式操作系統(tǒng)三倍以上(市場(chǎng)份額約 13%)。
特點(diǎn)
標(biāo)準(zhǔn) Linux 可能采用的小型化方法
1. 重新編譯內(nèi)核
Linux 內(nèi)核采用模塊化的設(shè)計(jì),即很多功能塊可以獨(dú)立的加上或卸下,開發(fā)人員在設(shè)計(jì)內(nèi)核時(shí)把這些內(nèi)核模塊作為可選的選項(xiàng),可以在編譯系統(tǒng)內(nèi)核時(shí)指定。因此一種較通用的做法是對(duì) Linux 內(nèi)核重新編譯,在編譯時(shí)仔細(xì)的選擇嵌入式設(shè)備所需要的功能支持模塊,同時(shí)刪除不需要的功能。通過對(duì)內(nèi)核的重新配置,可以使系統(tǒng)運(yùn)行所需要的內(nèi)核顯著減小,從而縮減資源使用量。
2. 制作 root 文件系統(tǒng)映象
Linux 系統(tǒng)在啟動(dòng)時(shí)必須加載根(root)文件系統(tǒng),因此剪裁系統(tǒng)同時(shí)包括 root file system 的剪裁。在 x86 系統(tǒng)下,Linux 可以在 Dos 下,使用 Loadlin 文件加載啟動(dòng),
uClinux 采用的小型化方法
1.uClinux 的內(nèi)核加載方式
uClinux 的內(nèi)核有兩種可選的運(yùn)行方式:可以在 flash 上直接運(yùn)行,也可以加載到內(nèi)存中運(yùn)行。這種做法可以減少內(nèi)存需要。
Flash 運(yùn)行方式:把內(nèi)核的可執(zhí)行映象燒寫到 flash 上,系統(tǒng)啟動(dòng)時(shí)從 flash 的某個(gè)地址開始逐句執(zhí)行。這種方法實(shí)際上是很多嵌入式系統(tǒng)采用的方法。
內(nèi)核加載方式:把內(nèi)核的壓縮文件存放在 flash 上,系統(tǒng)啟動(dòng)時(shí)讀取壓縮文件在內(nèi)存里解壓,然后開始執(zhí)行,這種方式相對(duì)復(fù)雜一些,但是運(yùn)行速度可能更快(ram 的存取速率要比 flash 高)。同時(shí)這也是標(biāo)準(zhǔn) Linux 系統(tǒng)采用的啟動(dòng)方式。
2.uClinux 的根(root)文件系統(tǒng)
uClinux 系統(tǒng)采用 romfs 文件系統(tǒng),這種文件系統(tǒng)相對(duì)于一般的 ext2 文件系統(tǒng)要求更少的空間??臻g的節(jié)約來(lái)自于兩個(gè)方面,首先內(nèi)核支持 romfs 文件系統(tǒng)比支持 ext2 文件系統(tǒng)需要更少的代碼,其次 romfs 文件系統(tǒng)相對(duì)簡(jiǎn)單,在建立文件系統(tǒng)超級(jí)塊(superblock)需要更少的存儲(chǔ)空間。Romfs 文件系統(tǒng)不支持動(dòng)態(tài)擦寫保存,對(duì)于系統(tǒng)需要?jiǎng)討B(tài)保存的數(shù)據(jù)采用虛擬 ram 盤的方法進(jìn)行處理(ram 盤將采用 ext2 文件系統(tǒng))。
3.uClinux 的應(yīng)用程序庫(kù)
uClinux 小型化的另一個(gè)做法是重寫了應(yīng)用程序庫(kù),相對(duì)于越來(lái)越大且越來(lái)越全的 glibc 庫(kù),uClibc 對(duì) libc 做了精簡(jiǎn)。
uClinux 對(duì)用戶程序采用靜態(tài)連接的形式,這種做法會(huì)使應(yīng)用程序變大,但是基于內(nèi)存管理的問題,不得不這樣做(這將在下文對(duì) uClinux 內(nèi)存管理展開分析時(shí)進(jìn)行說(shuō)明),同時(shí)這種做法也更接近于通常嵌入式系統(tǒng)的做法。
系統(tǒng)特點(diǎn)
嵌入式操作系統(tǒng)比較
由表 1 可以看出,對(duì)于嵌入式應(yīng)用,高端平臺(tái)可直接采用 Linux 系統(tǒng),其兼容性和可移植度都較高,但對(duì)硬件處理速度和存儲(chǔ)空間要求較高。
低端平臺(tái)的最佳選擇是 uClinux,其性能穩(wěn)定、移植性好、功能強(qiáng)大。
低端平臺(tái)如果對(duì)實(shí)時(shí)性要求較高、應(yīng)用相對(duì)簡(jiǎn)單,則可采用 uc/os 或其他操作系統(tǒng)。
基本架構(gòu)
uClinux 的系統(tǒng)與標(biāo)準(zhǔn) Linux 的架構(gòu)完全一致。
文件系統(tǒng)
uClinux 系統(tǒng)多采用 Romfs 文件系統(tǒng),Romfs 是一種相對(duì)簡(jiǎn)單、占用空間較少的文件系統(tǒng)??臻g的節(jié)約來(lái)自于兩個(gè)方面:首先內(nèi)核支持 Romfs 文件系統(tǒng)比支持 ext2 文件系統(tǒng)需要更少的代碼;其次 romfs 文件系統(tǒng)相對(duì)簡(jiǎn)單,在建立文件系統(tǒng)超級(jí)塊(Superblock)需要更少的存儲(chǔ)空間。Romfs 是只讀的文件系統(tǒng),禁止寫操作,因此系統(tǒng)同時(shí)需要虛擬盤(RAMDISK)支持臨時(shí)文件和數(shù)據(jù)文件的存儲(chǔ)。
隨著技術(shù)的發(fā)展,近年來(lái)日志文件系統(tǒng)在 uClinux 系統(tǒng)上得到了較多的應(yīng)用,其中以支持 NOR FLASH 的 JFFS、JFFS2 文件系統(tǒng)和支持 NAND FLASH 的 YAFFS 最為流行。這些文件系統(tǒng)都支持掉電文件保護(hù),同時(shí)支持標(biāo)準(zhǔn)的 MTD 驅(qū)動(dòng)。
開發(fā)環(huán)境
GNU 開發(fā)套件
Gnu 開發(fā)套件作為通用的 Linux 開放套件,包括一系列的開發(fā)調(diào)試工具。主要組件:
Gcc: 編譯器,可以做成交叉編譯的形式,即在宿主機(jī)上開發(fā)編譯目標(biāo)上可運(yùn)行的二進(jìn)制文件。
Binutils:一些輔助工具,包括 objdump(可以反編譯二進(jìn)制文件),as(匯編編譯器),ld(連接器)等等。
Gdb:調(diào)試器,可使用多種交叉調(diào)試方式,gdb-bdm(背景調(diào)試工具),gdbserver(使用以太網(wǎng)絡(luò)調(diào)試)。
uClinux 的打印終端
通常情況下,uClinux 的默認(rèn)終端是串口,內(nèi)核在啟動(dòng)時(shí)所有的信息都打印到串口終端(使用 printk 函數(shù)打印),同時(shí)也可以通過串口終端與系統(tǒng)交互。
uClinux 在啟動(dòng)時(shí)啟動(dòng)了 telnetd(遠(yuǎn)程登錄服務(wù)),操作者可以遠(yuǎn)程登錄上系統(tǒng),從而控制系統(tǒng)的運(yùn)行。至于是否允許遠(yuǎn)程登錄可以通過燒寫 romfs 文件系統(tǒng)時(shí)有用戶決定是否啟動(dòng)遠(yuǎn)程登錄服務(wù)。
交叉編譯調(diào)試工具
支持一種新的處理器,必須具備一些編譯,匯編工具,使用這些工具可以形成可運(yùn)行于這種處理器的二進(jìn)制文件。對(duì)于內(nèi)核使用的編譯工具同應(yīng)用程序使用的有所不同。在解釋不同點(diǎn)之前,需要對(duì) gcc 連接做一些說(shuō)明:
.ld(link description)文件:ld 文件是指出連接時(shí)內(nèi)存映象格式的文件。
crt0.S:應(yīng)用程序編譯連接時(shí)需要的啟動(dòng)文件,主要是初始化應(yīng)用程序棧。
pic:position independence code ,與位置無(wú)關(guān)的二進(jìn)制格式文件,在程序段中必須包括 reloc 段,從而使的代碼加載時(shí)可以進(jìn)行重新定位。
內(nèi)核編譯連接時(shí),使用 ucsimm.ld 文件,形成可執(zhí)行文件映象,所形成的代碼段既可以使用間接尋址方式(即使用 reloc 段進(jìn)行尋址),也可以使用絕對(duì)尋址方式。這樣可以給編譯器更多的優(yōu)化空間。因?yàn)閮?nèi)核可能使用絕對(duì)尋址,所以內(nèi)核加載到的內(nèi)存地址空間必須與 ld 文件中給定的內(nèi)存空間完全相同。
應(yīng)用程序的連接與內(nèi)核連接方式不同。應(yīng)用程序由內(nèi)核加載(可執(zhí)行文件加載器將在后面討論),由于應(yīng)用程序的 ld 文件給出的內(nèi)存空間與應(yīng)用程序?qū)嶋H被加載的內(nèi)存位置可能不同,這樣在應(yīng)用程序加載的過程中需要一個(gè)重新地位的過程,即對(duì) reloc 段進(jìn)行修正,使得程序進(jìn)行間接尋址時(shí)不至于出錯(cuò)。(這個(gè)問題在 i386 等高級(jí)處理器上方法有所不同,本文將在后面進(jìn)一步分析)。
由上述討論,至少需要兩套編譯連接工具。在討論過 uClinux 的內(nèi)存管理后本文將給出整個(gè)系統(tǒng)的工作流程以及系統(tǒng)在 flash 和 ram 中的空間分布。
可執(zhí)行文件格式
先對(duì)一些名詞作一些說(shuō)明:
coff(common object file format):一種通用的對(duì)象文件格式
elf(excutive linked file):一種為 Linux 系統(tǒng)所采用的通用文件格式,支持動(dòng)態(tài)連接
flat:elf 格式有很大的文件頭,flat 文件對(duì)文件頭和一些段信息做了簡(jiǎn)化
uClinux 系統(tǒng)使用 flat 可執(zhí)行文件格式,gcc 的編譯器不能直接形成這種文件格式,但是可以形成 coff 或 elf 格式的可執(zhí)行文件,這兩種文件需要 coff2flt 或 elf2flt 工具進(jìn)行格式轉(zhuǎn)化,形成 flat 文件。
當(dāng)用戶執(zhí)行一個(gè)應(yīng)用時(shí),內(nèi)核的執(zhí)行文件加載器將對(duì) flat 文件進(jìn)行進(jìn)一步處理,主要是對(duì) reloc 段進(jìn)行修正(可執(zhí)行文件加載器的詳見 fs/binfmt_flat.c)。以下對(duì) reloc 段進(jìn)一步討論。
需要 reloc 段的根本原因是,程序在連接時(shí)連接器所假定的程序運(yùn)行空間與實(shí)際程序加載到的內(nèi)存空間不同。假如有這樣一條指令:
jsr app_start;
這一條指令采用直接尋址,跳轉(zhuǎn)到 app_start 地址處執(zhí)行,連接程序?qū)⒃诰幾g完成是計(jì)算出 app_start 的實(shí)際地址(設(shè)若實(shí)際地址為 0x10000),這個(gè)實(shí)際地址是根據(jù) ld 文件計(jì)算出來(lái)(因?yàn)檫B接器假定該程序?qū)⒈患虞d到由 ld 文件指明的內(nèi)存空間)。但實(shí)際上由于內(nèi)存分配的關(guān)系,操作系統(tǒng)在加載時(shí)無(wú)法保證程序?qū)?ld 文件加載。這時(shí)如果程序仍然跳轉(zhuǎn)到絕對(duì)地址 0x10000 處執(zhí)行,通常情況這是不正確的。一個(gè)解決辦法是增加一個(gè)存儲(chǔ)空間,用于存儲(chǔ) app_start 的實(shí)際地址,設(shè)若使用變量 addr 表示這個(gè)存儲(chǔ)空間。則以上這句程序?qū)⒏臑椋?/p>
movl addr, a0;
jsr (a0);
增加的變量 addr 將在數(shù)據(jù)段中占用一個(gè) 4 字節(jié)的空間,連接器將 app_start 的絕對(duì)地址存儲(chǔ)到該變量。在可執(zhí)行文件加載時(shí),可執(zhí)行文件加載器根據(jù)程序?qū)⒁虞d的內(nèi)存空間計(jì)算出 app_start 在內(nèi)存中的實(shí)際位置,寫入 addr 變量。系統(tǒng)在實(shí)際處理是不需要知道這個(gè)變量的確切存儲(chǔ)位置(也不可能知道),系統(tǒng)只要對(duì)整個(gè) reloc 段進(jìn)行處理就可以了(reloc 段有標(biāo)識(shí),系統(tǒng)可以讀出來(lái))。處理很簡(jiǎn)單只需要對(duì) reloc 段中存儲(chǔ)的值統(tǒng)一加上一個(gè)偏置(如果加載的空間比預(yù)想的要靠前,實(shí)際上是減去一個(gè)偏移量)。偏置由實(shí)際的物理地址起始值同 ld 文件指定的地址起始值相減計(jì)算出。
這種 reloc 的方式部分是由 uClinux 的內(nèi)存分配問題引起的,這一點(diǎn)將在 uClinux 內(nèi)存管理分析時(shí)說(shuō)明。
針對(duì)實(shí)時(shí)性的解決方案
uClinux 本身并沒有關(guān)注實(shí)時(shí)問題,它并不是為了 Linux 的實(shí)時(shí)性而提出的。另外有一種 Linux–Rt-linux 關(guān)注實(shí)時(shí)問題。Rt-linux 執(zhí)行管理器把普通 Linux 的內(nèi)核當(dāng)成一個(gè)任務(wù)運(yùn)行,同時(shí)還管理了實(shí)時(shí)進(jìn)程。而非實(shí)時(shí)進(jìn)程則交給普通 Linux 內(nèi)核處理。這種方法已經(jīng)應(yīng)用于很多的操作系統(tǒng)用于增強(qiáng)操作系統(tǒng)的實(shí)時(shí)性,包括一些商用版 UNIX 系統(tǒng),Windows NT 等等。這種方法優(yōu)點(diǎn)之一是實(shí)現(xiàn)簡(jiǎn)單,且實(shí)時(shí)性能容易檢驗(yàn)。優(yōu)點(diǎn)之二是由于非實(shí)時(shí)進(jìn)程運(yùn)行于標(biāo)準(zhǔn) Linux 系統(tǒng),同其它 Linux 商用版本之間保持了很大的兼容性。優(yōu)點(diǎn)之三是可以支持硬實(shí)時(shí)時(shí)鐘的應(yīng)用。uClinux 可以使用 Rt-linux 的 patch,從而增強(qiáng) uClinux 的實(shí)時(shí)性,使得 uClinux 可以應(yīng)用于工業(yè)控制、進(jìn)程控制等一些實(shí)時(shí)要求較高的應(yīng)用。
內(nèi)存管理
應(yīng)該說(shuō) uClinux 同標(biāo)準(zhǔn) Linux 的最大區(qū)別就在于內(nèi)存管理,同時(shí)也由于 uClinux 的內(nèi)存管理引發(fā)了一些標(biāo)準(zhǔn) Linux 所不會(huì)出現(xiàn)的問題。本文將把 uClinux 內(nèi)存管理同標(biāo)準(zhǔn) Linux 的內(nèi)存管理部分進(jìn)行比較分析。
標(biāo)準(zhǔn) Linux 使用的虛擬存儲(chǔ)器技術(shù)
標(biāo)準(zhǔn) Linux 使用虛擬存儲(chǔ)器技術(shù),這種技術(shù)用于提供比計(jì)算機(jī)系統(tǒng)中實(shí)際使用的物理內(nèi)存大得多的內(nèi)存空間。使用者將感覺到好像程序可以使用非常大的內(nèi)存空間,從而使得編程人員在寫程序時(shí)不用考慮計(jì)算機(jī)中的物理內(nèi)存的實(shí)際容量。為了支持虛擬存儲(chǔ)管理器的管理,Linux 系統(tǒng)采用分頁(yè)(paging)的方式來(lái)載入進(jìn)程。所謂分頁(yè)既是把實(shí)際的存儲(chǔ)器分割為相同大小的段,例如每個(gè)段 1024 個(gè)字節(jié),這樣 1024 個(gè)字節(jié)大小的段便稱為一個(gè)頁(yè)面(page)。
虛擬存儲(chǔ)器由存儲(chǔ)器管理機(jī)制及一個(gè)大容量的快速硬盤存儲(chǔ)器支持。它的實(shí)現(xiàn)基于局部性原理,當(dāng)一個(gè)程序在運(yùn)行之前,沒有必要全部裝入內(nèi)存,而是僅將那些當(dāng)前要運(yùn)行的那些部分頁(yè)面或段裝入內(nèi)存運(yùn)行(copy-on-write),其余暫時(shí)留在硬盤上程序運(yùn)行時(shí)如果它所要訪問的頁(yè)(段)已存在,則程序繼續(xù)運(yùn)行,如果發(fā)現(xiàn)不存在的頁(yè)(段),操作系統(tǒng)將產(chǎn)生一個(gè)頁(yè)錯(cuò)誤(page fault),這個(gè)錯(cuò)誤導(dǎo)致操作系統(tǒng)把需要運(yùn)行的部分加載到內(nèi)存中。必要時(shí)操作系統(tǒng)還可以把不需要的內(nèi)存頁(yè)(段)交換到磁盤上。利用這樣的方式管理存儲(chǔ)器,便可把一個(gè)進(jìn)程所需要用到的存儲(chǔ)器以化整為零的方式,視需求分批載入,而核心程序則憑借屬于每個(gè)頁(yè)面的頁(yè)碼來(lái)完成尋址各個(gè)存儲(chǔ)器區(qū)段的工作。
標(biāo)準(zhǔn) Linux 是針對(duì)有內(nèi)存管理單元的處理器設(shè)計(jì)的。在這種處理器上,虛擬地址被送到內(nèi)存管理單元(MMU),把虛擬地址映射為物理地址。
通過賦予每個(gè)任務(wù)不同的虛擬–物理地址轉(zhuǎn)換映射,支持不同任務(wù)之間的保護(hù)。地址轉(zhuǎn)換函數(shù)在每一個(gè)任務(wù)中定義,在一個(gè)任務(wù)中的虛擬地址空間映射到物理內(nèi)存的一個(gè)部分,而另一個(gè)任務(wù)的虛擬地址空間映射到物理存儲(chǔ)器中的另外區(qū)域。計(jì)算機(jī)的存儲(chǔ)管理單元(MMU)一般有一組寄存器來(lái)標(biāo)識(shí)當(dāng)前運(yùn)行的進(jìn)程的轉(zhuǎn)換表。在當(dāng)前進(jìn)程將 CPU 放棄給另一個(gè)進(jìn)程時(shí)(一次上下文切換),內(nèi)核通過指向新進(jìn)程地址轉(zhuǎn)換表的指針加載這些寄存器。MMU 寄存器是有特權(quán)的,只能在內(nèi)核態(tài)才能訪問。這就保證了一個(gè)進(jìn)程只能訪問自己用戶空間內(nèi)的地址,而不會(huì)訪問和修改其它進(jìn)程的空間。當(dāng)可執(zhí)行文件被加載時(shí),加載器根據(jù)缺省的 ld 文件,把程序加載到虛擬內(nèi)存的一個(gè)空間,因?yàn)檫@個(gè)原因?qū)嶋H上很多程序的虛擬地址空間是相同的,但是由于轉(zhuǎn)換函數(shù)不同,所以實(shí)際所處的內(nèi)存區(qū)域也不同。而對(duì)于多進(jìn)程管理當(dāng)處理器進(jìn)行進(jìn)程切換并執(zhí)行一個(gè)新任務(wù)時(shí),一個(gè)重要部分就是為新任務(wù)切換任務(wù)轉(zhuǎn)換表。我們可以看到 Linux 系統(tǒng)的內(nèi)存管理至少實(shí)現(xiàn)了以下功能:
運(yùn)行比內(nèi)存還要大的程序。理想情況下應(yīng)該可以運(yùn)行任意大小的程序
◇可以運(yùn)行只加載了部分的程序,縮短了程序啟動(dòng)的時(shí)間
◇可以使多個(gè)程序同時(shí)駐留在內(nèi)存中提高 CPU 的利用率
◇可以運(yùn)行重定位程序。即程序可以方于內(nèi)存中的任何一處,而且可以在執(zhí)行過程中移動(dòng)。
◇寫機(jī)器無(wú)關(guān)的代碼。程序不必事先約定機(jī)器的配置情況。
◇減輕程序員分配和管理內(nèi)存資源的負(fù)擔(dān)。
◇可以進(jìn)行共享–例如,如果兩個(gè)進(jìn)程運(yùn)行同一個(gè)程序,它們應(yīng)該可以共享程序代碼的同一個(gè)副本。
◇提供內(nèi)存保護(hù),進(jìn)程不能以非授權(quán)方式訪問或修改頁(yè)面,內(nèi)核保護(hù)單個(gè)進(jìn)程的數(shù)據(jù)和代碼以防止其它進(jìn)程修改它們。否則,用戶程序可能會(huì)偶然(或惡意)的破壞內(nèi)核或其它用戶程序。
虛存系統(tǒng)并不是沒有代價(jià)的。內(nèi)存管理需要地址轉(zhuǎn)換表和其他一些數(shù)據(jù)結(jié)構(gòu),留給程序的內(nèi)存減少了。地址轉(zhuǎn)換增加了每一條指令的執(zhí)行時(shí)間,而對(duì)于有額外內(nèi)存操作的指令會(huì)更嚴(yán)重。當(dāng)進(jìn)程訪問不在內(nèi)存的頁(yè)面時(shí),系統(tǒng)發(fā)生失效。系統(tǒng)處理該失效,并將頁(yè)面加載到內(nèi)存中,這需要極耗時(shí)間的磁盤 I/O 操作。總之內(nèi)存管理活動(dòng)占用了相當(dāng)一部分 cpu 時(shí)間(在較忙的系統(tǒng)中大約占 10%)。
uClinux 針對(duì) NOMMU 的特殊處理
對(duì)于 uClinux 來(lái)說(shuō),其設(shè)計(jì)針對(duì)沒有 MMU 的處理器,即 uClinux 不能使用處理器的虛擬內(nèi)存管理技術(shù)(應(yīng)該說(shuō)這種不帶有 MMU 的處理器在嵌入式設(shè)備中相當(dāng)普偏)。uClinux 仍然采用存儲(chǔ)器的分頁(yè)管理,系統(tǒng)在啟動(dòng)時(shí)把實(shí)際存儲(chǔ)器進(jìn)行分頁(yè)。在加載應(yīng)用程序時(shí)程序分頁(yè)加載。但是由于沒有 MMU 管理,所以實(shí)際上 uClinux 采用實(shí)存儲(chǔ)器管理策略(real memeory management)。這一點(diǎn)影響了系統(tǒng)工作的很多方面。
uClinux 系統(tǒng)對(duì)于內(nèi)存的訪問是直接的,(它對(duì)地址的訪問不需要經(jīng)過 MMU,而是直接送到地址線上輸出),所有程序中訪問的地址都是實(shí)際的物理地址。操作系統(tǒng)對(duì)內(nèi)存空間沒有保護(hù)(這實(shí)際上是很多嵌入式系統(tǒng)的特點(diǎn)),各個(gè)進(jìn)程實(shí)際上共享一個(gè)運(yùn)行空間(沒有獨(dú)立的地址轉(zhuǎn)換表)。
一個(gè)進(jìn)程在執(zhí)行前,系統(tǒng)必須為進(jìn)程分配足夠的連續(xù)地址空間,然后全部載入主存儲(chǔ)器的連續(xù)空間中。與之相對(duì)應(yīng)的是標(biāo)準(zhǔn) Linux 系統(tǒng)在分配內(nèi)存時(shí)沒有必要保證實(shí)際物理存儲(chǔ)空間是連續(xù)的,而只要保證虛存地址空間連續(xù)就可以了。另外一個(gè)方面程序加載地址與預(yù)期(ld 文件中指出的)通常都不相同,這樣 relocation 過程就是必須的。此外磁盤交換空間也是無(wú)法使用的,系統(tǒng)執(zhí)行時(shí)如果缺少內(nèi)存將無(wú)法通過磁盤交換來(lái)得到改善。
uClinux 對(duì)內(nèi)存的管理減少同時(shí)就給開發(fā)人員提出了更高的要求。如果從易用性這一點(diǎn)來(lái)說(shuō),uClinux 的內(nèi)存管理是一種倒退,退回了到了 UNIX 早期或是 Dos 系統(tǒng)時(shí)代。開發(fā)人員不得不參與系統(tǒng)的內(nèi)存管理。從編譯內(nèi)核開始,開發(fā)人員必須告訴系統(tǒng)這塊開發(fā)板到底擁有多少的內(nèi)存(假如你欺騙了系統(tǒng),那將在后面運(yùn)行程序時(shí)受到懲罰),從而系統(tǒng)將在啟動(dòng)的初始化階段對(duì)內(nèi)存進(jìn)行分頁(yè),并且標(biāo)記已使用的和未使用的內(nèi)存。系統(tǒng)將在運(yùn)行應(yīng)用時(shí)使用這些分頁(yè)內(nèi)存。
由于應(yīng)用程序加載時(shí)必須分配連續(xù)的地址空間,而針對(duì)不同硬件平臺(tái)的可一次成塊(連續(xù)地址)分配內(nèi)存大小限制是不同(目前針對(duì) ez328 處理器的 uClinux 是 128k,而針對(duì) coldfire 處理器的系統(tǒng)內(nèi)存則無(wú)此限制),所以開發(fā)人員在開發(fā)應(yīng)用程序時(shí)必須考慮內(nèi)存的分配情況并關(guān)注應(yīng)用程序需要運(yùn)行空間的大小。另外由于采用實(shí)存儲(chǔ)器管理策略,用戶程序同內(nèi)核以及其它用戶程序在一個(gè)地址空間,程序開發(fā)時(shí)要保證不侵犯其它程序的地址空間,以使得程序不至于破壞系統(tǒng)的正常工作,或?qū)е缕渌绦虻倪\(yùn)行異常。
從內(nèi)存的訪問角度來(lái)看,開發(fā)人員的權(quán)利增大了(開發(fā)人員在編程時(shí)可以訪問任意的地址空間),但與此同時(shí)系統(tǒng)的安全性也大為下降。此外,系統(tǒng)對(duì)多進(jìn)程的管理將有很大的變化,這一點(diǎn)將在 uClinux 的多進(jìn)程管理中說(shuō)明。
雖然 uClinux 的內(nèi)存管理與標(biāo)準(zhǔn) Linux 系統(tǒng)相比功能相差很多,但應(yīng)該說(shuō)這是嵌入式設(shè)備的選擇。在嵌入式設(shè)備中,由于成本等敏感因素的影響,普偏的采用不帶有 MMU 的處理器,這決定了系統(tǒng)沒有足夠的硬件支持實(shí)現(xiàn)虛擬存儲(chǔ)管理技術(shù)。從嵌入式設(shè)備實(shí)現(xiàn)的功能來(lái)看,嵌入式設(shè)備通常在某一特定的環(huán)境下運(yùn)行,只要實(shí)現(xiàn)特定的功能,其功能相對(duì)簡(jiǎn)單,內(nèi)存管理的要求完全可以由開發(fā)人員考慮。
標(biāo)準(zhǔn) Linux 系統(tǒng)的進(jìn)程、線程
進(jìn)程:進(jìn)程是一個(gè)運(yùn)行程序并為其提供執(zhí)行環(huán)境的實(shí)體,它包括一個(gè)地址空間和至少一個(gè)控制點(diǎn),進(jìn)程在這個(gè)地址空間上執(zhí)行單一指令序列。進(jìn)程地址空間包括可以訪問或引用的內(nèi)存單元的集合,進(jìn)程控制點(diǎn)通過一個(gè)一般稱為程序計(jì)數(shù)器(program counter,PC)的硬件寄存器控制和跟蹤進(jìn)程指令序列。
fork:由于進(jìn)程為執(zhí)行程序的環(huán)境,因此在執(zhí)行程序前必須先建立這個(gè)能”跑”程序的環(huán)境。Linux 系統(tǒng)提供系統(tǒng)調(diào)用拷貝現(xiàn)行進(jìn)程的內(nèi)容,以產(chǎn)生新的進(jìn)程,調(diào)用 fork 的進(jìn)程稱為父進(jìn)程;而所產(chǎn)生的新進(jìn)程則稱為子進(jìn)程。子進(jìn)程會(huì)承襲父進(jìn)程的一切特性,但是它有自己的數(shù)據(jù)段,也就是說(shuō),盡管子進(jìn)程改變了所屬的變量,卻不會(huì)影響到父進(jìn)程的變量值。
父進(jìn)程和子進(jìn)程共享一個(gè)程序段,但是各自擁有自己的堆棧、數(shù)據(jù)段、用戶空間以及進(jìn)程控制塊。換言之,兩個(gè)進(jìn)程執(zhí)行的程序代碼是一樣的,但是各有各的程序計(jì)數(shù)器與自己的私人數(shù)據(jù)。
當(dāng)內(nèi)核收到 fork 請(qǐng)求時(shí),它會(huì)先查核三件事:首先檢查存儲(chǔ)器是不是足夠;其次是進(jìn)程表是否仍有空缺;最后則是看看用戶是否建立了太多的子進(jìn)程。如果上述說(shuō)三個(gè)條件滿足,那么操作系統(tǒng)會(huì)給子進(jìn)程一個(gè)進(jìn)程識(shí)別碼,并且設(shè)定 cpu 時(shí)間,接著設(shè)定與父進(jìn)程共享的段,同時(shí)將父進(jìn)程的 inode 拷貝一份給子進(jìn)程運(yùn)用,最終子進(jìn)程會(huì)返回?cái)?shù)值 0 以表示它是子進(jìn)程,至于父進(jìn)程,它可能等待子進(jìn)程的執(zhí)行結(jié)束,或與子進(jìn)程各做個(gè)的。
exec 系統(tǒng)調(diào)用:該系統(tǒng)調(diào)用提供一個(gè)進(jìn)程去執(zhí)行另一個(gè)進(jìn)程的能力,exec 系統(tǒng)調(diào)用是??序的堆棧、數(shù)據(jù)段與程序段都會(huì)被修改,只有用戶區(qū)維持不變。
vfork 系統(tǒng)調(diào)用:由于在使用 fork 時(shí),內(nèi)核會(huì)將父進(jìn)程拷貝一份給子進(jìn)程,但是這樣的做法相當(dāng)浪費(fèi)時(shí)間,因?yàn)榇蠖鄶?shù)的情形都是程序在調(diào)用 fork 后就立即調(diào)用 exec,這樣剛拷貝來(lái)的進(jìn)程區(qū)域又立即被新的數(shù)據(jù)覆蓋掉。因此 Linux 系統(tǒng)提供一個(gè)系統(tǒng)調(diào)用 vfork,vfork 假定系統(tǒng)在調(diào)用完成 vfork 后會(huì)馬上執(zhí)行 exec,因此 vfork 不拷貝父進(jìn)程的頁(yè)面,只是初始化私有的數(shù)據(jù)結(jié)構(gòu)與準(zhǔn)備足夠的分頁(yè)表。這樣實(shí)際在 vfork 調(diào)用完成后父子進(jìn)程事實(shí)上共享同一塊存儲(chǔ)器(在子進(jìn)程調(diào)用 exec 或是 exit 之前),因此子進(jìn)程可以更改父進(jìn)程的數(shù)據(jù)及堆棧信息,因此 vfork 系統(tǒng)調(diào)用完成后,父進(jìn)程進(jìn)入睡眠,直到子進(jìn)程執(zhí)行 exec。當(dāng)子進(jìn)程執(zhí)行 exec 時(shí),由于 exec 要使用被執(zhí)行程序的數(shù)據(jù),代碼覆蓋子進(jìn)程的存儲(chǔ)區(qū)域,這樣將產(chǎn)生寫保護(hù)錯(cuò)誤(do_wp_page)(這個(gè)時(shí)候子進(jìn)程寫的實(shí)際上是父進(jìn)程的存儲(chǔ)區(qū)域),
這個(gè)錯(cuò)誤導(dǎo)致內(nèi)核為子進(jìn)程重新分配存儲(chǔ)空間。當(dāng)子進(jìn)程正確開始執(zhí)行后,將喚醒父進(jìn)程,使得父進(jìn)程繼續(xù)往后執(zhí)行。
uClinux 的多進(jìn)程處理
uClinux 沒有 mmu 管理存儲(chǔ)器,在實(shí)現(xiàn)多個(gè)進(jìn)程時(shí)(fork 調(diào)用生成子進(jìn)程)需要實(shí)現(xiàn)數(shù)據(jù)保護(hù)。
uClinux 的 fork 和 vfork:uClinux 的 fork 等于 vfork。實(shí)際上 uClinux 的多進(jìn)程管理通過 vfork 來(lái)實(shí)現(xiàn)。這意味著 uClinux 系統(tǒng) fork 調(diào)用完程后,要么子進(jìn)程代替父進(jìn)程執(zhí)行(此時(shí)父進(jìn)程已經(jīng) sleep)直到子進(jìn)程調(diào)用 exit 退出,要么調(diào)用 exec 執(zhí)行一個(gè)新的進(jìn)程,這個(gè)時(shí)候?qū)a(chǎn)生可執(zhí)行文件的加載,即使這個(gè)進(jìn)程只是父進(jìn)程的拷貝,這個(gè)過程也不能避免。當(dāng)子進(jìn)程執(zhí)行 exit 或 exec 后,子進(jìn)程使用 wakeup 把父進(jìn)程喚醒,父進(jìn)程繼續(xù)往下執(zhí)行。
uClinux 的這種多進(jìn)程實(shí)現(xiàn)機(jī)制同它的內(nèi)存管理緊密相關(guān)。uClinux 針對(duì) nommu 處理器開發(fā),所以被迫使用一種 flat 方式的內(nèi)存管理模式,啟動(dòng)新的應(yīng)用程序時(shí)系統(tǒng)必須為應(yīng)用程序分配存儲(chǔ)空間,并立即把應(yīng)用程序加載到內(nèi)存。缺少了 MMU 的內(nèi)存重映射機(jī)制,uClinux 必須在可執(zhí)行文件加載階段對(duì)可執(zhí)行文件 reloc 處理,使得程序執(zhí)行時(shí)能夠直接使用物理內(nèi)存。
uClinux 是專門針對(duì)沒有 MMU 的處理器而設(shè)計(jì)的,即 uClinux 無(wú)法使用處理器的虛擬內(nèi)存管理技術(shù)。實(shí)際上 uClinux 采用實(shí)存儲(chǔ)器管理策略,通過地址總線對(duì)物理內(nèi)存進(jìn)行直接訪問。所有程序中訪問的地址都是實(shí)際的物理地址,所有的進(jìn)程都在一個(gè)運(yùn)行空間中運(yùn)行(包括內(nèi)核進(jìn)程),這樣的運(yùn)行機(jī)制給程序員帶來(lái)了不小的挑戰(zhàn),在操作系統(tǒng)不提供保護(hù)的情況下必需小心設(shè)計(jì)程序和數(shù)據(jù)空間,以免引起應(yīng)用程序進(jìn)程甚至是內(nèi)核的崩潰。
uClinux 仍然采用存儲(chǔ)器的分頁(yè)管理,系統(tǒng)在啟動(dòng)時(shí)把實(shí)際存儲(chǔ)器進(jìn)行分頁(yè),在加載應(yīng)用程序時(shí)程序分頁(yè)加載。一個(gè)進(jìn)程在執(zhí)行前,系統(tǒng)必須為進(jìn)程分配足夠的連續(xù)地址空間,然后全部載入主存儲(chǔ)器的連續(xù)空間中。系統(tǒng)不含 MMU 帶來(lái)的另外一個(gè)問題是磁盤交換空間無(wú)法使用,對(duì)于資源有限的嵌入式系統(tǒng)而言,系統(tǒng)執(zhí)行時(shí)如果缺少內(nèi)存將無(wú)法通過磁盤交換來(lái)得到改善。
MMU 的省略雖然帶來(lái)了系統(tǒng)及應(yīng)用程序開發(fā)的限制,但對(duì)于成本和體積敏感的嵌入式設(shè)備而言,其應(yīng)用環(huán)境和應(yīng)用需求并不要求復(fù)雜和相對(duì)昂貴的硬件體系,對(duì)于功能簡(jiǎn)單的專用嵌入式設(shè)備,內(nèi)存的分配和管理完全可以由開發(fā)人員考慮。
多進(jìn)程管理
由于 uClinux 沒有 MMU 管理存儲(chǔ)器,在實(shí)現(xiàn)多個(gè)進(jìn)程時(shí)需要實(shí)現(xiàn)數(shù)據(jù)保護(hù)。uClinux 的雖然支持 fork 函數(shù),但其實(shí)質(zhì)是和 vfork:實(shí)際上 uClinux 所有的多進(jìn)程管理都通過 vfork 來(lái)實(shí)現(xiàn)。
vfork 不拷貝父進(jìn)程的頁(yè)面,只是初始化私有的數(shù)據(jù)結(jié)構(gòu)與準(zhǔn)備足夠的分頁(yè)表。調(diào)用完成后父子進(jìn)程事實(shí)上共享同一塊存儲(chǔ)器,因此子進(jìn)程可以更改父進(jìn)程的數(shù)據(jù)及堆棧信息,所有父進(jìn)程進(jìn)入睡眠,直到子進(jìn)程執(zhí)行 exec。當(dāng)子進(jìn)程正確開始執(zhí)行后,將喚醒父進(jìn)程,使得父進(jìn)程繼續(xù)往后執(zhí)行。這意味著 uClinux 系統(tǒng) fork 調(diào)用完成后,要么子進(jìn)程代替父進(jìn)程執(zhí)行(此時(shí)父進(jìn)程已經(jīng)休眠)直到子進(jìn)程調(diào)用 exit 退出,要么調(diào)用 exec 執(zhí)行一個(gè)新的進(jìn)程。
vfork 是 uClinux 與標(biāo)準(zhǔn) Linux 應(yīng)用程序的開發(fā)中最重要的不同之處,只有對(duì) vfork 與 fork 兩個(gè)函數(shù)的差異和程序處理有詳細(xì)的了解才能順利地完成從 Linux 到 uClinux 的程序移植。
缺點(diǎn)
正如古語(yǔ)云“人無(wú)完人”,uClinux 也有一些不足之處:
文檔的不足
與 Linux 及其他自由軟件類似,uClinux 的文檔十分不足:缺乏組織和一致的文檔、熱門技術(shù)和分類文檔眾多而雜亂無(wú)章、非熱點(diǎn)部分文檔缺失甚至沒有文檔。對(duì)于開發(fā)人員而言,往往要深入程序的源代碼找尋有用的資料。
Bug 問題
uClinux 與硬件平臺(tái)直接相關(guān)。對(duì)于有商業(yè)公司贊助的硬件平臺(tái),其相關(guān)代碼和 Bug 更新較快,編譯和執(zhí)行都十分順利;但對(duì)于非商業(yè)支持的硬件平臺(tái),其內(nèi)核和應(yīng)用程序代碼都得不到及時(shí)更新和排錯(cuò)。這種現(xiàn)象在內(nèi)核源代碼樹還不是十分普遍,但在 uClinux 自帶的應(yīng)用程序庫(kù)中卻經(jīng)常發(fā)生編譯錯(cuò)誤,往往是增加了一個(gè)應(yīng)用程序或改變了運(yùn)行庫(kù)便導(dǎo)致無(wú)法編譯。這就需要開發(fā)者投入足夠的時(shí)間和精力進(jìn)行排錯(cuò)和修改,也會(huì)導(dǎo)致開發(fā)進(jìn)度的延誤。
以上就是關(guān)于uCLinux是什么及uCLinux有什么用這方面的一些信息了 小編整理的這些訊息希望對(duì)童鞋們有所幫助
2016-2022 All Rights Reserved.平安財(cái)經(jīng)網(wǎng).復(fù)制必究 聯(lián)系QQ280 715 8082 備案號(hào):閩ICP備19027007號(hào)-6
本站除標(biāo)明“本站原創(chuàng)”外所有信息均轉(zhuǎn)載自互聯(lián)網(wǎng) 版權(quán)歸原作者所有。