欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
uClinux上的應用程序設計||操作系統|
uClinux上的應用程序設計  

            Luojia, Tsinghua Motorola MCU & DSP Center

     uClinux以其優(yōu)異的性能、免費開(kāi)放的代碼等優(yōu)點(diǎn),博得眾多嵌入式開(kāi)發(fā)者的青睞。和過(guò)去基于簡(jiǎn)單RTOS甚至沒(méi)有使用任何操作系統的嵌入式程序設計相比,基于Linux這樣的成熟的、高效的、健壯的、可靠的、模塊化的、易于配置的操作系統來(lái)開(kāi)發(fā)自己的應用程序,無(wú)疑能進(jìn)一步提高效率,并具有很好的可移植性。
    在前面的章節中,我們已介紹了硬件平臺、內核編譯、開(kāi)發(fā)環(huán)境等內容。如果僅僅有Hardware和OS,這個(gè)系統所能做的事情還非常有限。對于一個(gè)實(shí)際的嵌入式產(chǎn)品而言,所提供的功能和應用是關(guān)系到產(chǎn)品成敗的重要因素。


     我們知道,在主流的Linux平臺上,已經(jīng)有了非常豐富的、開(kāi)源的應用程序,使得開(kāi)發(fā)者很容易獲得前人的成果作為參考,編寫(xiě)更適合自己的程序。
然而,對于很多已經(jīng)在標準Linux環(huán)境中工作得很好的程序,并不能直接在uCLinux環(huán)境上運行。一方面,是由于嵌入式的uCLinux所使用的處理器和普通PC不同,指令集、CPU結構上的差異導致uClinux上運行的程序需要專(zhuān)門(mén)為該類(lèi)型處理器交叉編譯產(chǎn)生;另一方面,uCLinux是為了沒(méi)有內存管理單元(MMU)的處理器、控制器設計,并做了較大幅度的精簡(jiǎn),所以,在標準Linux上可以使用的一些函數和系統調用在uCLinux上有可能就行不通了。
因此,我們有必要了解,在uCLinux上的應用程序設計和標準Linux程序設計存在哪些不同之處?應該如何修改,才能讓標準Linux程序可以移植到uCLinux上并正常工作呢?如何才能高效地開(kāi)發(fā)uclinux上的應用程序呢?本文旨在對這些問(wèn)題進(jìn)行初步的探討。

1 uClinux和Linux的異同
    uClinux是針對控制領(lǐng)域的嵌入式linux操作系統,它從Linux 2.0/2.4內核派生而來(lái),沿襲了主流Linux的絕大部分特性。適合不具備內存管理單元(MMU)的微處理器/微控制器。沒(méi)有MMU支持是uClinux與主流Linux的基本差異。
    標準Linux是針對有MMU的處理器設計的。在這種處理器上,虛擬地址被送到MMU,把虛擬地址映射為物理地址。通過(guò)賦予每個(gè)任務(wù)不同的虛擬-物理地址轉換映射,支持不同任務(wù)之間的保護。
對uCLinux來(lái)說(shuō),其設計針對沒(méi)有MMU的處理器,不能使用處理器的虛擬內存管理技術(shù)。uCLinux仍然采用存儲器的分頁(yè)管理,系統在啟動(dòng)時(shí)把實(shí)際存儲器進(jìn)行分頁(yè)。在加載應用程序時(shí)程序分頁(yè)加載。但是由于沒(méi)有MMU管理,所以實(shí)際上uCLinux采用實(shí)存儲器管理策略。uCLinux系統對于內存的訪(fǎng)問(wèn)是直接的,所有程序中訪(fǎng)問(wèn)的地址都是實(shí)際的物理地址。操作系統對內存空間沒(méi)有保護,各個(gè)進(jìn)程實(shí)際上共享一個(gè)運行空間。一個(gè)進(jìn)程在執行前,系統必須為進(jìn)程分配足夠的連續地址空間,然后全部載入主存儲器的連續空間中。
    同時(shí),uClinux有著(zhù)特別小的內核和用戶(hù)軟件空間。熟悉主流Linux的開(kāi)發(fā)者會(huì )注意到在uClinux下工作的微小差異,但同樣也可以很快熟悉uclinux的一些特性。對于設計內核或系統空間的應用程序的開(kāi)發(fā)者,要特別注意uClinux既沒(méi)有內存保護,也沒(méi)有虛擬內存模型,另外,有些內核系統調用也有差異。

1.1 內存保護
    沒(méi)有內存保護(MemoryProtection)的操作會(huì )導致這樣的結果:即使由無(wú)特權的進(jìn)程來(lái)調用一個(gè)無(wú)效指針,也會(huì )觸發(fā)一個(gè)地址錯誤,并潛在地引起程序崩潰,甚至導致系統的掛起。顯然,在這樣的系統上運行的代碼必須仔細編程,并深入測試來(lái)確保健壯性和安全。
對于普通的Linux來(lái)說(shuō),需要運行不同的用戶(hù)程序,如果沒(méi)有內存保護將大大降低系統的安全性和可靠性;然而對于嵌入式uClinux系統而言,由于所運行的程序往往是在出廠(chǎng)前已經(jīng)固化的,不存在危害系統安全的程序侵入的隱患,因此只要應用程序經(jīng)過(guò)較完整的測試,出現問(wèn)題的概率就可以控制在有限的范圍內。

1.2 虛擬內存
    沒(méi)有虛擬內存(Virtual Memory)主要導致下面幾個(gè)后果:
    首先,由內核所加載的進(jìn)程必須能夠獨立運行,與它們在內存中的位置無(wú)關(guān)。實(shí)現這一目標的第一種辦法是一旦程序被加載到RAM中,那么程序的基準地址就“固定”下來(lái);另一種辦法是產(chǎn)生只使用相對尋址的代碼(稱(chēng)為“位置無(wú)關(guān)代碼”,Position IndependentCode,簡(jiǎn)稱(chēng)PIC)。uClinux對這兩種模式都支持。
  其次,要解決在扁平(flat)的內存模型中的內存分配和釋放問(wèn)題。非常動(dòng)態(tài)的內存分配會(huì )造成內存碎片,并可能耗盡系統的資源。對于使用了動(dòng)態(tài)內存分配的那些應用程序來(lái)說(shuō),增強健壯性的一種辦法是用預分配緩沖區池(Preallocated bufferpool)的辦法來(lái)取代malloc()調用。由于uclinux中不使用虛擬內存,進(jìn)出內存的頁(yè)面交換也沒(méi)有實(shí)現,因為不能保證頁(yè)面會(huì )被加載到RAM中的同樣位置。在普通計算機上,操作系統允許應用程序使用比物理內存(RAM)更大的內存空間,這往往是通過(guò)在硬盤(pán)上設立交換分區來(lái)實(shí)現的。但是,在嵌入式系統中,通常都用FLASH存儲器來(lái)代替硬盤(pán),很難高效地實(shí)現內存頁(yè)面交換的存取,因此,對運行的應用程序都限制其可分配空間不大于系統的RAM空間。
    最后,uClinux目標板處理器缺乏內存管理的硬件單元,使得Linux的系統接口需要作些改變。有可能最大的不同就是沒(méi)有fork()和brk()系統調用。調用fork()將復制出進(jìn)程來(lái)創(chuàng )建一個(gè)子進(jìn)程。在Linux下,fork()是使用copy-on-write頁(yè)面來(lái)實(shí)現的。由于沒(méi)有MMU,uclinux不能完整、可靠地復制一個(gè)進(jìn)程,也沒(méi)有對copy-on-write的存取。為了彌補這一缺陷,uClinux實(shí)現了vfork(),當父進(jìn)程調用vfork()來(lái)創(chuàng )建子進(jìn)程時(shí),兩個(gè)進(jìn)程共享它們的全部?jì)却婵臻g,包括堆棧。子進(jìn)程要么代替父進(jìn)程執行(此時(shí)父進(jìn)程已經(jīng)sleep)直到子進(jìn)程調用exitI()退出,要么調用exec()執行一個(gè)新的進(jìn)程,這個(gè)時(shí)候將產(chǎn)生可執行文件的加載。即使這個(gè)進(jìn)程只是父進(jìn)程的拷貝,這個(gè)過(guò)程也不能避免。當子進(jìn)程執行exit()或exec()后,子進(jìn)程使用wakeup把父進(jìn)程喚醒,父進(jìn)程繼續往下執行。
    注意,多任務(wù)并沒(méi)有受影響。哪些舊式的、廣泛使用fork()的網(wǎng)絡(luò )后臺程序(daemon)的確是需要修改的。由于子進(jìn)程運行在和父進(jìn)程同樣的地址空間內,在一些情況下,也需要修改兩個(gè)進(jìn)程的行為。
很多現代的程序依賴(lài)子進(jìn)程來(lái)執行基本任務(wù),使得即時(shí)在進(jìn)程負載很重時(shí),系統仍可以保持一種“可交互”的狀態(tài),這些程序可能需要實(shí)質(zhì)上的修改來(lái)在uClinux下完成同樣的任務(wù)。如果一個(gè)關(guān)鍵的應用程序非常依賴(lài)這樣的結構,那就不得不對它重新編寫(xiě)了。
    假設有一個(gè)簡(jiǎn)單的網(wǎng)絡(luò )后臺程序(daemon),大量使用了fork()。這個(gè)daemon總監聽(tīng)一個(gè)知名端口(或套接字)等待網(wǎng)絡(luò )客戶(hù)端來(lái)連接。當客戶(hù)端連接時(shí),這個(gè)daemon給它一個(gè)新的連接信息(新的socket編號),并調用fork()。子進(jìn)程接下來(lái)就會(huì )和客戶(hù)端在新的socket上進(jìn)行連接,而父進(jìn)程被釋放,可以繼續監聽(tīng)新的連接。
uClinux 既沒(méi)有自動(dòng)生長(cháng)的堆棧,也沒(méi)有brk()函數,這樣,用戶(hù)空間的程序必須使用mmap() 命令來(lái)分配內存。為了方便,在uclinux的C語(yǔ)言庫中所實(shí)現的malloc()實(shí)質(zhì)上就是一個(gè)mmap()。在編譯時(shí),可以指定程序的堆棧大小。

1.3 通用架構的內核變化
    在uClinux的發(fā)布中,/linux/mmnommu目錄取代了/linux/mm目錄。前者就是修改后的內存管理子系統被修改,去除了MMU硬件的依賴(lài),并在內核軟件自身提供基本的內存管理函數。
很多子系統需要被重新修改、添加或者重寫(xiě)。內核和用戶(hù)內存分配和釋放進(jìn)程必須重新實(shí)現。對透明交互/頁(yè)面調度的支持也被去除。
   內核中,加入了支持“位置無(wú)關(guān)代碼(PIC)”的程序加載模塊,并使用了新的二進(jìn)制目標碼格式,稱(chēng)為“扁平”格式(flat),用來(lái)支持PIC(有非常緊湊的頭部)。內核也提供了支持ELF格式的程序加載模塊,用來(lái)支持使用固定基準地址的可執行程序。兩種模式各有利弊,傳統的PIC運行快,代碼緊湊,但是有代碼大小限制。例如Motorola68K架構的16位相對跳轉限制了PIC程序不能超過(guò)32kbyte大小。而采用運行期固定基址的方法使得沒(méi)有了代碼大小限制,不過(guò)當程序被內核加載后招致了較多的系統開(kāi)銷(xiāo)。

1.4 uCLinux的內核加載方式
    uCLinux的內核有兩種可選的運行方式:可以在flash上直接運行,也可以加載到RAM中運行。
    Flash運行方式:把內核的可執行映像文件燒到flash上,系統啟動(dòng)時(shí)從flash的某個(gè)地址開(kāi)始逐句執行。這種方法實(shí)際上是很多嵌入式系統采用的方法。
    內核加載RAM方式:把內核的壓縮文件存放在flash上,系統啟動(dòng)時(shí)讀取壓縮文件在內存里解壓,然后開(kāi)始執行,這種方式相對復雜一些,但是運行速度可能更快。同時(shí)這也是標準Linux系統采用的啟動(dòng)方式。

1.5 uCLinux的文件系統
    uCLinux系統采用ROMFS文件系統,這種文件系統相對于一般的ext2文件系統要求更少的空間??臻g的節約來(lái)自于兩個(gè)方面:首先內核支持ROMFS文件系統比支持ext2文件系統需要更少的代碼;其次ROMFS文件系統相對簡(jiǎn)單,在建立文件系統超級塊(superblock)需要更少的存儲空間。ROMFS文件系統不支持動(dòng)態(tài)擦寫(xiě)保存,對于系統需要動(dòng)態(tài)保存的數據采用虛擬RAM盤(pán)的方法進(jìn)行處理(RAM盤(pán)將采用ext2文件系統)。
應用程序如果需要以文件方式交換數據,可以將它存儲在/tmp目錄下。這一目錄實(shí)質(zhì)上就是虛擬的RAM盤(pán)。不過(guò)在掉電時(shí),這些數據就會(huì )丟失。
   如果希望在掉電時(shí),信息仍然可以保持,那么就要把它寫(xiě)到FLASH中。這時(shí),就可以使用JFFS這一文件系統,在uClinux的發(fā)布中,文件“/linux/drivers/block/flash.c”中提供的JFFS代碼可以參考。
另外,還需要修改/linux/.config和include/linux/autoconf.h中的有關(guān)內容,增加對FLASH和JFFS的編譯。

2 uClinux程序設計要點(diǎn)

2.1 軟件開(kāi)發(fā)工具
    可以免費獲得的GCC(GNU C Compiler)無(wú)疑是uClinux上最佳的開(kāi)發(fā)工具。
uClinux系統的軟件開(kāi)發(fā)需要在標準Linux平臺上用交叉編譯工具來(lái)完成。除了前面所提到的一些涉及內存和系統調用的程序之外,在x86版本的gcc編譯器下編譯通過(guò)的軟件通常不需要做大的改動(dòng)就可以用交叉編譯工具編譯到uClinux上運行。
    交叉編譯器可以從下面網(wǎng)址獲得:
    http:/www.uclinux.org/pub/uClinux/m68k-elf-tools/
    目前最新的版本是2.95.3:m68k-elf-tools-20020410.tar.gz
交叉編譯器直接解在根目錄(/)下就行了:(注意當前目錄是/,而且m68k-elf-tools-20020218.tar.gz要在/下)
    tar xzf m68k-elf-tools-20020218.tar.gz
它會(huì )自動(dòng)在/usr/local/下建立起整套m68k的ELF交叉編譯器,要編譯自己的簡(jiǎn)單C程序就可以用/usr/local/bin/m68k-elf-gcc,例如,源代碼為test.c,那么可以這樣編譯:
/usr/local/bin/m68k-elf-gcc –Wall -elf2flt -m5307 test.c –lc –o test.out
參數“-Wall”指定產(chǎn)生全部的警告;-elf2flt指定自動(dòng)調用elf轉換flat格式的工具;-m5307指定了處理器的指令集;-lc指定了鏈接信息(ld);-o指定輸出文件的名字。
編譯成功后得到的test.out就可以在uClinux環(huán)境上運行(通過(guò)nfsmount、smbmount,或者直接放到內核映像中都可以)。
    也可以建立一個(gè)簡(jiǎn)單的Makefile來(lái)做這件事情:
    CC = /usr/local/bin/m68k-elf-gcc
    all:
    $(CC) -Wall -elf2flt -m5307 test.c -lc -o test.out

    通過(guò)GDB可以調試目標板,Coldfire處理器可以通過(guò)Motorola的BDM作為調試接口,可以在不干擾程序正常運行的情況下調試目標板上的內核。如果處理器不支持,那么在內核中需要插樁(stub),GDB和stub通過(guò)串行口或者以太網(wǎng)通訊。

2.2 可執行文件格式
    先解釋幾種可執行文件格式。
     coff(common object file format):一種通用的對象文件格式;
     elf(excutive linked file):一種為L(cháng)inux系統所采用的通用文件格式,支持動(dòng)態(tài)連接和重定位;
     flat:扁平格式。elf格式有很大的文件頭,flat格式對文件頭和一些段信息做了簡(jiǎn)化,可執行程序小。
     uCLinux系統目前支持flat和elf兩種可執行文件格式。

2.3 uCLinux的應用程序庫
    uCLinux小型化的另一個(gè)做法是重寫(xiě)了應用程序庫,相對于越來(lái)越大且越來(lái)越全的glibc庫,uClibc對libc做了精簡(jiǎn)。
    最新版本的程序庫可以從這個(gè)網(wǎng)址獲得:
    http:/uclibc.org/download/uClibc-0.9.10.tar.gz
    uCLinux對用戶(hù)程序采用靜態(tài)鏈接的形式,這種做法會(huì )使應用程序變大,但是基于內存管理的問(wèn)題,也就是基于沒(méi)有MMU的特性,只能這樣做,同時(shí)這種做法也更接近于通常嵌入式系統的做法。
    uClibc提供大多數的類(lèi)UNIX的C程序調用。如果應用程序需要用到uClibc中沒(méi)有提供的函數,這些函數可以加到uClibc中、或者作為一個(gè)獨立的庫、或者加到應用程序上面來(lái)進(jìn)行鏈接。

2.4 裁減uCLinux以適合自己的應用
    不同的嵌入式系統之間的根文件系統內容差異很大。uClinux的發(fā)布包括一個(gè)根文件系統,實(shí)現了一個(gè)小型的類(lèi)UNIX服務(wù)器,在串口上有控制臺,telnet daemon,web server,NFS客戶(hù)端支持和一些可選的常用工具。
但是,有的系統設計可能不需要控制臺,例如,如果設計一個(gè)可以播放MP3的隨身CD機,內核只需要支持CD驅動(dòng)、并行I/O和音頻DAC。而在用戶(hù)空間可能只包括一個(gè)接口程序來(lái)驅動(dòng)按鈕、LED、來(lái)控制CD播放,并調用MP3的解碼程序。

2.5 關(guān)于uClinux 2.4內核
    2001年發(fā)布了uClinux2.4,支持龍珠和coldfire處理器,基于2.4內核的一些增強特性同樣做到了uclinux2.0系列上。目前一些應用仍然基于2.0.x空間的。然而2.4內核使得開(kāi)發(fā)者可以訪(fǎng)問(wèn)很多新的特性,例如支持USB、IEEE火線(xiàn)、IrDA和新的網(wǎng)絡(luò )特點(diǎn),例如帶寬分配、QoS、IPv6等等。
    如果在應用程序中需要使用2.4的新特性,可以在編譯uClinux內核時(shí),選擇2.4的版本。不過(guò),2.4畢竟是較新的內核,有可能不穩定的風(fēng)險。

3 高效的程序開(kāi)發(fā)
    總的來(lái)說(shuō),在uClinux上的開(kāi)發(fā)和標準Linux還是很類(lèi)似的。通??梢园凑障旅娴牟襟E去設計和調試:
    1. 建立基于以太網(wǎng)的開(kāi)發(fā)環(huán)境;
    2. 如果所設計的程序和硬件的關(guān)聯(lián)不大,那么一定要在標準Linux上先編譯和調試通過(guò)。靈活地使用gcc和gdb將大大節省時(shí)間;
    3. 將x86上的GCC編譯好的應用程序用交叉編譯工具來(lái)編譯;如果編譯時(shí)發(fā)現錯誤,那么很可能存在以下問(wèn)題:
    n 交叉編譯器或庫文件的路徑不正確;最徹底的解決辦法是重新裝一次編譯器;
    n 遇到庫不支持的函數;此時(shí)需要自己把函數的實(shí)現做成另外一個(gè)庫供應用程序使用。如果是uClinux本身不支持的調用,那么就需要改寫(xiě)代碼了。
    n C++的一些寫(xiě)法不太標準,需要修改;
    4. 通過(guò)網(wǎng)絡(luò )(nfsmount)運行交叉編譯成功的應用程序;
    5. 如果程序工作初步正常,那么就可以進(jìn)一步在板子上測試了;否則,需做修改重新編譯,尤其要檢查與uClinux的內存特性有關(guān)的代碼。

    如果程序較小,設計時(shí)就可以比較靈活。如果是一個(gè)比較龐大的工程,那么,建立一個(gè)好的編譯環(huán)境非常重要。下面,給出一個(gè)較為復雜的工程中所建立的一系列編譯文件例子,用好它們可以提高效率。
    例如,在編譯x86平臺上的程序時(shí),可以這樣輸入:
    >make config
    出現提示:
    Target Platform Selection
    Choose a Vendor/Product combination.
    Vendor/Product [Intel/i386| Motorola/M5307C3]
    如果我們輸入i386,那么就可以編譯出PC上運行的程序;而輸入M5307C3,就可以編譯出uClinux上運行的程序。這對于經(jīng)常需要在標準Linux和uClinux之間進(jìn)行交叉編譯和查找錯誤的程序來(lái)說(shuō)非常方便。

   首先,建立圖 2所示的整個(gè)工程目錄結構。



圖 2 整個(gè)工程的目錄結構

    在config中,存放一些編譯有關(guān)的配置文件;src目錄下,按照各個(gè)程序模塊分別創(chuàng )建一個(gè)目錄。
    在Project目錄下,是整個(gè)工程的Makefile文件,如下:
###########################################################
#
# Makefile – Whole Project makefile.
#
# Copyright (c) 2001-2002, Tsinghua MAC
#
###########################################################
#
# Get the core stuff worked out
#

ROOT_DIR = $(shell pwd)
SRC_DIR = $(ROOT_DIR)/src
CONFIG_DIR = $(ROOT_DIR)/config
SCRIPTS_DIR = $(ROOT_DIR)/scripts

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

HPATH = $(TOPDIR)/include
FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net

export ROOT_DIR SRC_DIR CONFIG_DIR SCRIPTS_DIR HPATH FINDHPATH

###########################################################
# normal make targets
#
#
.PHONY: all
all:
$(MAKE) -C $(SRC_DIR) all
###########################################################

#
# Config stuff, we recall ourselves to load the new config.arch before
# running the kernel and other config scripts
#
.PHONY: config
config: $(CONFIG_DIR)/config.in
cd $(CONFIG_DIR); $(CONFIG_SHELL) $(SCRIPTS_DIR)/Configure $(CONFIG_DIR)/config.in
@rm -f $(SRC_DIR)/arch.config
@if egrep "^CONFIG_DEFAULTS_INTEL_I386" $(CONFIG_DIR)/.config > /dev/null; then \
ln -s "$(CONFIG_DIR)/arch.i386" $(SRC_DIR)/arch.config; \
fi
@if egrep "^CONFIG_DEFAULTS_MOTOROLA_M5272C3" $(CONFIG_DIR)/.config > /dev/null; then \
ln -s "$(CONFIG_DIR)/arch.m68k" $(SRC_DIR)/arch.config; \
fi
@echo "#This dir.config file is automaticly generated by make config!" > $(SRC_DIR)/dir.config
@echo "ROOT_DIR="$(ROOT_DIR) >> $(SRC_DIR)/dir.config
@echo "CONFIG_DIR="$(CONFIG_DIR) >> $(SRC_DIR)/dir.config
@echo "SRC_DIR="$(SRC_DIR) >> $(SRC_DIR)/dir.config
@echo "SCRIPTS_DIR="$(SCRIPTS_DIR) >> $(SRC_DIR)/dir.config
@echo "HPATH="$(HPATH) >> $(SRC_DIR)/dir.config
@echo "FINDPATH="$(FINDPATH) >> $(SRC_DIR)/dir.config

###########################################################
#
# normal make dependancy
#
#
.PHONY: dep
dep:
$(MAKE) -C $(SRC_DIR) dep

# This one removes all executables from the tree and forces their relinking
clean:
$(MAKE) -C $(SRC_DIR) clean

test:
$(MAKE) -C $(SRC_DIR) test

run:
$(MAKE) -C $(SRC_DIR) run

config_error:
@echo "*************************************************"
@echo "You have not run make config."
@echo "The build sequence for this source tree is:"
@echo "1. ‘make config‘ or ‘make xconfig‘"
@echo "2. ‘make dep‘"
@echo "3. ‘make‘"
@echo "*************************************************"
@exit 1
###########################################################

src目錄下的Makefile文件,如下:

VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 39
UCRELEASE = uc2

.EXPORT_ALL_VARIABLES:

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

TARGET = ESGateway

all: $(TARGET)

# Include the make variables (CC, etc...)
#

SUBDIRS = public serial packet cal xml fifo main interface

$(TARGET):
@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i all_targets; done

linuxsubdirs: dummy
set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

clean:
@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean; done

dep:
@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done

.PHONY: test
test:
@set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i test; done

run:
# @set -e; for i in $(SUBDIRS); do $(MAKE) -i -C $$i run; read junk; done
make -C main run

src目錄下的Rules.make文件給出了編譯的一些規則,如下:
#
# This file contains rules which are shared between multiple Makefiles.
#

#
# False targets.
#
.PHONY: dummy

#
# Special variables which should not be exported
#
unexport EXTRA_ASFLAGS
unexport EXTRA_CFLAGS
ifneq "$(ARCH)" "h8300"
unexport EXTRA_LDFLAGS
endif
unexport EXTRA_ARFLAGS
unexport SUBDIRS
unexport SUB_DIRS
unexport ALL_SUB_DIRS
unexport MOD_SUB_DIRS
unexport O_TARGET
unexport O_OBJS
unexport L_OBJS
unexport M_OBJS
unexport MI_OBJS
unexport ALL_MOBJS
# objects that export symbol tables
unexport OX_OBJS
unexport LX_OBJS
unexport MX_OBJS
unexport MIX_OBJS
unexport SYMTAB_OBJS

unexport MOD_LIST_NAME

include ../dir.config
include $(SRC_DIR)/arch.config

#
# Get things started.
#
first_rule: sub_dirs
$(MAKE) all_targets

#
# Common rules
#
INC_DIR = -I$(SRC_DIR)/cal-I$(SRC_DIR)/xml -I$(SRC_DIR)/serial -I$(SRC_DIR)/packet-I$(SRC_DIR)/fifo -I$(SRC_DIR)/ping -I$(SRC_DIR)/interface-I$(SRC_DIR)/public

%.o: %.c
@echo "Compiling..."
@echo "$<"
$(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<

%.o: %.cpp
@echo "Compiling..."
@echo "$<"
$(CXX) $(INC_DIR) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<

# Rule to compile a set of .o files into one .o file
#

ifeq (.depend,$(wildcard .depend))
include .depend
else
.depend: fastdep
endif

ifneq ($(O_TARGET),$(O_OBJS))
$(O_TARGET): .depend $(O_OBJS)
@echo "Linking..."
@echo $(O_OBJS) " --> " $@
@$(LD) $(EXTRA_LDFLAGS) -r -o $@ $(O_OBJS)
else
$(O_TARGET): .depend
endif
#
#
#

all: $(O_OBJS)
echo all

all_targets: $(O_OBJS) $(O_TARGET)

#

#
# Rule to compile a set of .o files into one .a file
#
ifdef L_TARGET
$(L_TARGET): $(LX_OBJS) $(L_OBJS)
rm -f $@
$(AR) $(EXTRA_ARFLAGS) rcs $@ $(LX_OBJS) $(L_OBJS)
endif

#
# This make dependencies quickly
#
fastdep: dummy
@echo "make fastdep"
if [ -n "$(wildcard *.[chS])" ]; then \
$(SCRIPTS_DIR)/mkdep *.[chS] > .depend; fi
if [ -n "$(wildcard *.cpp)" ]; then \
$(SCRIPTS_DIR)/mkdep *.cpp >> .depend; fi

#
# A rule to make subdirectories
#
sub_dirs: dummy
ifdef SUB_DIRS
set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done
endif
#
# A rule to do nothing
#
dummy:

config:
cd $(ROOT_DIR); make config

c clean:
rm -f *.o
rm -f *.gdb
rm -f .depend
rm -f test
rm -f core
rm -f *.elf
rm -f *.elf2flt

#
# This is useful for testing
#
script:
$(SCRIPT)

run: test
@echo ... running ...
@echo `pwd`/test
@./test

#
# This sets version suffixes on exported symbols
# Uses SYMTAB_OBJS
# Separate the object into "normal" objects and "exporting" objects
# Exporting objects are: all objects that define symbol tables
#


$(MX_OBJS):
$(CC) $(CFLAGS) -DEXPORT_SYMTAB -c $(@:.o=.c)

$(LX_OBJS) $(OX_OBJS):
$(CC) $(CFLAGS) -DMODVERSIONS -DEXPORT_SYMTAB -c $(@:.o=.c)

$(M_OBJS):
ifdef MAKING_MODULES
$(O_OBJS) $(L_OBJS):
endif


在config 目錄下,編寫(xiě)兩個(gè)和架構有關(guān)的文件,對于x86平臺,是arch.i386,如下:
.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#

CONSOLE_BAUD_RATE = 19200

###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#

# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE = i386
ARCH = i386
CROSS_COMPILE =
CROSS = $(CROSS_COMPILE)

# We‘ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS =
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
RANLIB = $(CROSS_COMPILE)ranlib

STRIPTOOL = $(CROSS_COMPILE)strip
STRIP = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0 # have we set a special config below

###################################################################
#
# General purpose lib building rules, uClibc.config uses these when
# possible
#


###################################################################
# Settings for building user apps
#
CFLAGS = -Wall -Wstrict-prototypes -O2 -g
#CFLAGS = -Wstrict-prototypes -g
LDFLAGS = -m elf_i386
###################################################################
# fall through, do other config options perhaps
#
ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目錄下,對于嵌入式平臺,是arch.m68k,如下:

.EXPORT_ALL_VARIABLES:
###################################################################
#
# Vendor specific settings
#
CONSOLE_BAUD_RATE = 19200
###################################################################
#
# The makefiles need to know how to do things in different contexts
# To save some pain we put it all here
#
# First settings we always want for all build
#
# ARCH = kernel, TARGET_ARCH = uClibc

MACHINE = m68k
ARCH = m68knommu
CROSS_COMPILE = m68k-elf-
CROSS = $(CROSS_COMPILE)

# We‘ve used -m5307 here because the bulk of the 5272 instruction timings
# happen to be closer to the 5307 than the 5200 series. Luckily, the
# actual instructions on the two processors are essentially identical.
# This should be fixed at some stage.
CPUFLAGS = -m5200
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
RANLIB = $(CROSS_COMPILE)ranlib
ELF2FLT = elf2flt
STRIPTOOL = $(CROSS_COMPILE)strip
STRIP = $(STRIPTOOL)

UCLINUX_BUILD_SET = 0 # have we set a special config below


###################################################################
#
# Settings for building user apps
#
#CFLAGS = -m5200 -msep-data -g
CFLAGS = -m5200 -msep-data
LDFLAGS = -Wl,-elf2flt
SYSLIBS = -lc -lstdc++ -lgcc
###################################################################
#
# fall through, do other config options perhaps
#

ifeq ($(UCLINUX_BUILD_SET),1)
endif
###################################################################

在config 目錄下的config.in文件如下:

mainmenu_name ‘uClinux Configuration‘
mainmenu_option next_comment
comment ‘Target Platform Selection‘
comment ‘Choose a Vendor/Product combination.‘
choice ‘Vendor/Product [Intel/i386 | Motorola/M5307C3] ‘ "1 CONFIG_DEFAULTS_INTEL_I386 \
2 CONFIG_DEFAULTS_MOTOROLA_M5307C3 \
" Intel/i386
endmenu

4 結語(yǔ)
    本文討論了uClinux平臺上程序設計必須關(guān)注的一些特點(diǎn),并對在uClinux進(jìn)行高效程序開(kāi)發(fā)做了一些討論。
由于uClinux是開(kāi)源的,在uClinux上的開(kāi)發(fā)努力永遠不會(huì )停止。世界范圍的技術(shù)專(zhuān)家在使用uClinux來(lái)構造商業(yè)化的產(chǎn)品,他們的工作的重要部分反過(guò)來(lái)對開(kāi)源的社區作出了貢獻。每當我們訪(fǎng)問(wèn)uClinux的網(wǎng)站,看到又出現了更新的源碼發(fā)布或者更好的工具時(shí),就會(huì )感覺(jué)到這個(gè)開(kāi)發(fā)團體的熱情和能力,并鞭策自己努力工作,爭取為這個(gè)自由軟件的發(fā)展作出自己的創(chuàng )造性貢獻。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Linux內核配置文件之解讀Makefile
在Cygwin中運行UC/OS-II 和uclinux
在ubuntu7.10上搭建uClinux編譯開(kāi)發(fā)環(huán)境并用Skyeye進(jìn)行仿真
Minigui V1.3.3在uClinux中的移植經(jīng)驗總結 [轉]
單獨編譯linux-3.9.2-301的bonding內核模塊
SkyEye詳細安裝使用指南
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久