基于ARM9和Linux嵌入式系統(tǒng)設(shè)計.ppt_第1頁
基于ARM9和Linux嵌入式系統(tǒng)設(shè)計.ppt_第2頁
基于ARM9和Linux嵌入式系統(tǒng)設(shè)計.ppt_第3頁
基于ARM9和Linux嵌入式系統(tǒng)設(shè)計.ppt_第4頁
基于ARM9和Linux嵌入式系統(tǒng)設(shè)計.ppt_第5頁
已閱讀5頁,還剩131頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第9章 基于ARM9和Linux嵌入式系統(tǒng)設(shè)計,9.1 嵌入式Linux的開發(fā)環(huán)境 9.2 Linux開發(fā)工具的使用 9.3 GNU make命令和makefile 文件 9.4 嵌入式Linux引導(dǎo)程序 9.5 嵌入式Linux 下程序調(diào)試應(yīng)用舉例,9.1 嵌入式Linux的開發(fā)環(huán)境,9.1.1 嵌入式Linux開發(fā)環(huán)境建立 嵌入式Linux 開發(fā)環(huán)境有幾個方案: (1)在WINDOWS 下安裝Linux虛擬機后,目前大多情況下使用VWare軟件; (2)直接安裝 Linux 操作系統(tǒng)。,9.1.2 嵌入式Linux開發(fā)的一般過程,1.了解硬件 ; 2.準備需要使用的Linux工具以及其他工具 ; 3.安排內(nèi)存地址 ; 4.編寫啟動代碼和機器相關(guān)代碼 ; 5.編寫驅(qū)動程序; 6.C庫、GUI和系統(tǒng)程序的移植; 7.調(diào)試 .,9.2 Linux開發(fā)工具的使用 9.2.1 Linux開發(fā)工具GNU gcc的使用,1. GCC簡介 GCC是GNU Compiler Collection的簡稱,GCC是Linux平臺下最常用的編譯程序,是Linux平臺編譯器的事實標準。 GCC支持的體系結(jié)構(gòu)有40余種,常見的有x86系列、Arm、PowerPC等。同時,GCC還能運行在不同的操作系統(tǒng)上,如Linux、Solaris、Windows等。 GCC除了支持C語言外,還支持多種其他語言,例如C+、Ada、Java、Objective-C、Fortram、Pascal等。,2. GCC常用模式及選項 gcc最基本的用法是: gcc options file. 其中option是以“-”開始的各種選項,file是相關(guān)的文件名。在使用gcc的時,必須給出必要的選項和文件名。gcc的整個編譯過程分別是:預(yù)處理、編譯,匯編和鏈接。,例如,$ gcc -o hello hello.c gcc編譯器就會生成一個hello的可執(zhí)行文件。在hello.c的當前目錄下執(zhí)行./hello。 gcc編譯器生成的目標文件默認格式為elf(executive linked file)格式,是Linux系統(tǒng)所采用的可執(zhí)行鏈接文件的通用文件格式。elf格式由若干個段(section)組成,由標準c源代碼生成的目標文件中包含以下段: .text(正文段)包含程序的指令代碼。 .data(數(shù)據(jù)段)包含固定的數(shù)據(jù),如常量,字符串等。 .bss(未初始化數(shù)據(jù)段)包含未初始化的變量和數(shù)組等。 GCC常用兩種模式:編譯模式和編譯連接模式。,例:假設(shè)全部的源代碼都在一個文件test.c中。 $ gcc -o test 此命令是把源文件test.c直接編譯成可執(zhí)行程序test。 $ gcc -c test.c 此命令是把源文件test.c編譯成不可執(zhí)行目標文件test.o。默認情況下,生成的目標文件名為test.o,但也可以為輸出文件指定名稱,如下所示: $ gcc -c test.c o mytest.o 此命令是把源文件test.c編譯成不可執(zhí)行目標文件mytest.o。 下面的命令將同時編譯3個源文件,即first.c、second.c和 third.c,然后將它們連接成一個可執(zhí)行程序test。命令如下: $ gcc -o test first.c second.c third.c,3其他常用選項的使用 $ gcc test.c I/inc -o test 此命令告訴GCC包含文件存放在./inc 目錄下,在當前目錄的上一級。如果在編譯時需要的包含文件存放在多個目錄下,可使用多個-I 來指定各個目錄。如: $ gcc test.c I/inc I/inc2 -o test 此命令指出了另一個包含子目錄inc2,較之前目錄它還要在再上兩級才能找到。另外,還可在編譯命令行中定義符號常量。可簡單的在命令行中使用-D選項即可,如下例所示: $ gcc D TEST_CONFIGURATION test.c -o test 上面的命令與在源文件中加入下列命令是等效的: #define TEST_CONFIGURATION,3其他常用選項的使用 $ gcc test.c I/inc -o test 此命令告訴GCC包含文件存放在./inc 目錄下,在當前目錄的上一級。若在編譯時需要的包含文件存放在多個目錄下,可使用多個-I 來指定各個目錄: $ gcc test.c I/inc I/inc2 -o test 上面命令告訴GCC包含文件存放在./inc 目錄下,在當前目錄的上一級。若在編譯時需的包含文件存放在多個目錄下,可使用多個-I 來指定各個目錄: $ gcc test.c I/inc I/inc2 -o test 這里指出了另一個包含子目錄inc2,較之前目錄它還要在再上兩級才能找到. 另外,我們還可以在編譯命令行中定義符號常量。為此,我們可以簡單的 在命令行中使用-D選項即可,如下例所示: $ gcc -DTEST_CONFIGURATION test.c -o test 上面的命令與在源文件中加入下列命令是等效的: #define TEST_CONFIGURATION,4. 警告功能 當GCC在編譯過程中檢查出錯誤,則中止編譯;但檢測到警告時卻能繼續(xù)編譯生成可執(zhí)行程序。 在眾多的警告選項之中,最常用的是-Wall選項。該選項能發(fā)現(xiàn)程序中一系列的常見錯誤警告,舉例如下: $ gcc -Wall test.c -o test 該選項相當于同時使用了下列所有的選項: unused-function:遇到僅聲明過但尚未定義的靜態(tài)函數(shù)時發(fā)出警告。 unused-label:遇到聲明過但不使用的標號的警告。 unused-parameter:從未用過的函數(shù)參數(shù)的警告。 ,9.2.2 GDB調(diào)試器簡介 Linux系統(tǒng)中包含了GNU 調(diào)試程序gdb,用來調(diào)試C和 C+ 程序的調(diào)試器。gdb 提供如下功能: 運行程序,設(shè)置所有的能影響程序運行的參數(shù)和環(huán)境。 控制程序在指定的條件下停止運行。 當程序停止時,可以檢查程序的狀態(tài)。 修改程序的錯誤,并重新運行程序。 動態(tài)監(jiān)視程序中變量的值。 可以單步執(zhí)行代碼,觀察程序的運行狀態(tài)。,1gdb的啟動 在終端窗口中,有兩種方法運行g(shù)db,即在終端窗口的命令行中直接輸入gdb命令或gdb filename命令運行g(shù)db。 方法1: 先啟動gdb后執(zhí)行file filename命令。即 gdb file filename 執(zhí)行上述兩條命令就可啟動gdb,并裝入可執(zhí)行的程序filename。 方法2: 啟動gdb的同時裝入可執(zhí)行的程序。即 gdb filename 其中,filename是要調(diào)試的可執(zhí)行文件。這和啟動gdb后執(zhí)行file filename命令效果完全一樣。 啟動gdb后,就可以使用gdb的命令調(diào)試程序。,2gdb的基本命令 gdb中的命令分為以下幾類:工作環(huán)境相關(guān)命令、設(shè)置斷點與恢復(fù)命令、源代碼查看命令、查看運行數(shù)據(jù)相關(guān)命令及修改運行參數(shù)命令。gdb的命令可以通過help命令進行查找命令所屬的種類(class),可以從相關(guān)class找到相應(yīng)命令。如下所示: (gdb) help 此命令可列出命令的種類。 (gdb) help data 此命令查找data類種的命令,并列出data類種的所有命令。 (gdb) help call 此命令查找call命令。 直接鍵入“help command”來查看命令。,(1)工作環(huán)境相關(guān)命令,(2) 設(shè)置斷點與恢復(fù)命令,(3)gdb中源碼查看相關(guān)命令,(4) gdb中查看運行數(shù)據(jù)相關(guān)命令,(5)其他gdb命令 run命令:執(zhí)行當前被調(diào)試的程序。 kill命令:停止正在調(diào)試的應(yīng)用程序。 watch命令:設(shè)置監(jiān)視點,監(jiān)視表達式的變化。 awatch命令:設(shè)置讀寫監(jiān)視點。當要監(jiān)視的表達式被讀或?qū)憰r將應(yīng)用程序掛起。它的語法與watch命令相同。 rwatch命令:設(shè)置讀監(jiān)視點,當監(jiān)視表達式被讀時將程序掛起,等侍調(diào)試。此命令的語法與watch相同。, info break命令:顯示當前斷點列表,包括每個斷點到達的次數(shù)。 info files命令:顯示調(diào)試文件的信息。 info func命令:顯示所有的函數(shù)名。 info local命令:顯示當前函數(shù)的所有局部變量的信息。 info prog命令:顯示調(diào)試程序的執(zhí)行狀態(tài)。 Shell命令:執(zhí)行Linux Shell命令。 make命令:不退出gdb而重新編譯生成可執(zhí)行文件。 Quit命令:退出gdb。,(6) gdb中修改運行參數(shù)相關(guān)命令 gdb可修改運行時的參數(shù),并使該變量按照用戶當前輸入的值繼續(xù)運行。 方法為:在單步執(zhí)行的過程中,鍵入命令: set 變量設(shè)定值 在此之后,程序就會按照該設(shè)定的值運行了。 特別注意,在gcc編譯選項中一定要加入”-g”。只有在代碼處于“運行”或“暫?!睜顟B(tài)時才能查看變量值,設(shè)置斷點后程序在指定行之前停止。,9.3 GNU make命令和makefile 文件 顯式規(guī)則 隱晦規(guī)則 文件指示。其包括3個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中的include一樣;另一個是指根據(jù)某些情況指定Makefile中的有效部分,就像C語言中的預(yù)編譯#if一樣;還有就是定義一個多行的命令。 注釋。Makefile中只有行注釋,用“#”字符 在Makefile中的命令,必須要以Tab鍵開始。,GNU的make工作時的執(zhí)行步驟如下: 1. 讀入所有的Makefile。 2. 讀入被include的其它Makefile。 3. 初始化文件中的變量。 4. 推導(dǎo)隱晦規(guī)則,并分析所有規(guī)則。 5. 為所有的目標文件創(chuàng)建依賴關(guān)系鏈。 6. 根據(jù)依賴關(guān)系,決定哪些目標要重新生成。 7. 執(zhí)行生成命令。,9.3.1 Makefile文件的規(guī)則 1Makefile書寫規(guī)則 Makefile文件含有一系列的規(guī)則,規(guī)則內(nèi)容: 一個目標(target),即make最終需要創(chuàng)建的文件,如可執(zhí)行文件和目標文件;目標也可以是要執(zhí)行的動作,如clean。 一個或多個依賴文件(dependency)列表,通常是編譯目標文件所需要的其他文件。 一系列命今(command),是make執(zhí)行的動作,通常是把指定的相關(guān)文件編譯成目標文件的編譯命令,每個命令占一行,且每個命令行起始字符必須為TAB字符。,Makefile規(guī)則的一般形式如下: target:dependency dependency (tab) 例如:有以下的Makefile文件: test:prog.o code.o gcc o test prog.o code.o prog.o:prog.c prog.h code.h gcc c prog.c o prog.o code.o:code.c code.h gcc c code.c o code.o clean: rm f *.o,一般情況下,調(diào)用make命令可輸入: # make target target是Makefile文件中定義的目標之一,如果省略target,make就將生成Makefile文件中定義的第一個目標。對于上面Makefile的例子,單獨的一個make命令等價于: # make test 因為test是Makefile文件中定義的第一個目標,make首先將其讀入,然后從第一行開始執(zhí)行,把第一個目標test作為它的最終目標,所有后面的目標的更新都會影響到test的更新。,內(nèi)核源代碼中Makefile被分布在目錄樹中,與Makefile直接相關(guān)的文件有配置文件.config和規(guī)則文件Rules.make。頂層Makefile是整個內(nèi)核配置、編譯的總體控制文件。在頂層Makefile中的語句: include arch/$(ARCH)/Makefile 包含了特定CPU體系結(jié)構(gòu)下的Makefile,這個Makefile中包含了平臺相關(guān)的信息。配置文件.config包含由用戶選擇項,用來存放內(nèi)核配置后的結(jié)果(如make config)。位于各種CPU體系目錄下的Makefile,比如drivers/Makefile,負責所在子目錄下源代碼的管理。規(guī)則文件Rules.make,則被所有的Makefile使用。,用戶通過make config配置后,產(chǎn)生了.config。頂層Makefile讀入.config中的配置選擇。頂層Makefile有兩個主要的任務(wù):產(chǎn)生壓縮的內(nèi)核鏡像vmlinux文件和內(nèi)核模塊module。為了達到此目的,頂層Makefile遞歸的進入到內(nèi)核的各個子目錄中,分別調(diào)用位于子目錄中的Makefile。至于到底進入哪些子目錄,取決于內(nèi)核的配置。位于各個子目錄下的Makefile同樣也根據(jù).config給出的配置信息,構(gòu)造出當前配置下需要的源文件列表,并在文件的最后有include $(TOPDIR)/ Rules.make。,2. 在規(guī)則中使用通配符 make支持3種通配符:“*”,“?”和“.”。 波浪號(“”)字符在文件名中有特殊的用途。如“test”表示當前用戶的$HOME目錄下的test目錄。而“hchen/test”則表示用戶hchen的宿主目錄下的 test目錄。通配符 “*.c”表示所有以后綴為c的文件。 例如: print: *.c lpr -p $? touch print 該例說明目標print依賴于所有的.c文件。其中的“$?”是一個自動化變量。,3.偽目標 偽目標又稱假想目標,如: clean: rm *.o temp 這里并不生成“clean”這個文件?!皞文繕恕辈⒉皇且粋€文件,只是一個標簽,由于“偽目標”不是文件,所以make無法生成它的依賴關(guān)系和決定它是否要執(zhí)行。 可使用“make clean”來使用該目標。 如果你的Makefile需要生成若干個可執(zhí)行文件,可把所有的目標文件都寫在一個Makefile中,可聲明了一個“all”的偽目標。,聲明了一個“all”的偽目標 例如: all : prog1 prog2 prog3 prog1 : prog1.o utils.o cc -o prog1 prog1.o utils.o prog2 : prog2.o cc -o prog2 prog2.o prog3 : prog3.o sort.o utils.o cc -o prog3 prog3.o sort.o utils.o,9.3.2 Makefile文件中隱含規(guī)則 1常用的隱含規(guī)則 編譯C程序的隱含規(guī)則:.o的目標的依賴目標會自動推導(dǎo)為.c,并且其生成命令是 $(CC) c $(CPPFLAGS) $(CFLAGS)。 編譯C+程序的隱含規(guī)則:.o的目標的依賴目標會自動推導(dǎo)為.cc或是.C,并且其生成命令是$(CXX) c $(CPPFLAGS) $(CFLAGS)。(建議使用.cc作為C+源文件的后綴,而不是.C), 匯編和匯編預(yù)處理的隱含規(guī)則:.o的目標的依賴目標會自動推導(dǎo)為.s,默認使用編譯器as,并且其生成命令是:$(AS) $(ASFLAGS)。.s的目標的依賴目標會自動推導(dǎo)為.S,默認使用C預(yù)編譯器cpp,并且其生成命令是:$(AS) $(ASFLAGS)。 鏈接Object文件的隱含規(guī)則目標依賴于.o,通過運行C 的編譯器來運行鏈接程序生成(一般是ld),其生成命令是:$(CC) $(LDFLAGS) .o $(LOADLIBES) $(LDLIBS)。這個規(guī)則對于只有一個源文件的工程有效,同時也對多個Object文件(由不同的源文件生成)也有效。,2隱含規(guī)則使用的變量 (1)關(guān)于命令的變量。 AR :函數(shù)庫打包程序。默認命令是ar。 AS :匯編語言編譯程序。默認命令是as。 CC :C語言編譯程序。默認命令是cc。 CXX :C+語言編譯程序。默認命令是g+。 CPP :C程序的預(yù)處理器(輸出是標準輸出設(shè)備)。默認命令是$(CC) E。 RM :刪除文件命令。默認命令是rm f。,(2)關(guān)于命令參數(shù)的變量 以下變量都是相關(guān)上面的命令的參數(shù)。若沒有指明其默認值,則其默認值都是空。 ARFLAGS :函數(shù)庫打包程序AR命令的參數(shù)。默認值是rv。 ASFLAGS :匯編語言編譯器參數(shù)。(當明顯地調(diào)用“.s”或“.S”文件時)。 CFLAGS :C語言編譯器參數(shù)。 CXXFLAGS :C+語言編譯器參數(shù)。 CPPFLAGS :C預(yù)處理器參數(shù)。( C 和 Fortran 編譯器也會用到)。 FFLAGS :Fortran語言編譯器參數(shù)。 GFLAGS :SCCS get程序參數(shù)。 LDFLAGS :鏈接器參數(shù)。(如:ld),3自動化變量 常用的自動化變量如下。 $ :表示規(guī)則中的目標文件集。在模式規(guī)則中,如果有多個目標,那么,“$“就是匹配于目標中模式定義的集合。 $% :僅當目標在函數(shù)庫文件中,表示規(guī)則中的目標成員名。例如,如果一個目標是 foo.a (bar.o),那么,$%就是bar.o,$就是foo.a。如果目標不是函數(shù)庫文件(Unix下是.a,Windows下是.lib),那么,其值為空。, $ :依賴目標中的第一個目標名字。如果依賴目標是以模式(即“%“)定義的,那么“$“將是符合模式的一系列的文件集。注意,是一個一個取出來的。 $? :所有比目標新的依賴目標的集合,以空格分隔。 $ :所有的依賴目標的集合,以空格分隔。如果在依賴目標中有多個重復(fù)的,那個這個變量會去除重復(fù)的依賴目標,只保留一份。 $+ :這個變量很像“$“,也是所有依賴目標的集合。只是它不去除重復(fù)的依賴目標。, $* :表示不包含擴展名的目標文件名,即目標模式中“%”及其之前的部分。 例:目標是dir/a.foo.b,并且目標的模式是a.%.b,那么,$*的值就是dir/a.foo。 如果目標中沒有模式的定義,那么$*也就不能被推導(dǎo)出。 如果目標文件的后綴是make 所識別的,那么$*就是除了后綴的那一部分。 例如:如果目標是foo.c,因為.c是make所能識別的后綴名,所以,$*的值就是foo。,對于上面的七個變量都可以分別加上D或是F,表示取文件的目錄部分和文件部分。下面以$為例說明其含義: $(D) :表示$的目錄部分(不以斜杠作為結(jié)尾),如果$值是dir/foo.o,那么$(D)就是dir,若$中沒有包含斜杠,其值是“.”(當前目錄)。 $(F) :表示$的文件部分,如果$值是dir/foo.o,那么$(F) 就是foo.o,$(F)相當于函數(shù)$(notdir $)。,9.3.3 Makefile文件的命令 1顯示命令 echo 正在編譯XXX模塊 當make執(zhí)行時,會輸出“正在編譯XXX模塊”字符串,但不會輸出命令,如果沒有“”,那么,make將輸出: echo 正在編譯XXX模塊 正在編譯XXX模塊 如果make執(zhí)行時,帶入make參數(shù)-n或-just-print,則只是顯示命令,而不會執(zhí)行命令,這個功能很有利于調(diào)試Makefile文件。 而make參數(shù)-s或-slient則是全面禁止命令的顯示。,2命令執(zhí)行 當依賴目標新于目標時,也就是當規(guī)則的目標需要被更新時,make會一條一條的執(zhí)行其后的命令。如果要讓上一條命令的結(jié)果應(yīng)用到下一條命令時,應(yīng)該使用分號分隔這兩條命令。比如第一條命令是cd命令,希望第二條命令得在cd之后的基礎(chǔ)上運行,那么就不能把這兩條命令寫在兩行上,而應(yīng)該把這兩條命令寫在一行上,用分號分隔。如: exec: cd /home/hchen; pwd 當執(zhí)行“make exec”時,cd就起作用了,pwd會打印出“/home/hchen”。,3命令出錯 在Makefile命令行前加減號“-”(在Tab鍵之后),標記為不管命令出不出錯都認為是成功的。例如: clean: -rm -f *.o 若給make加上-i或是-ignore-errors參數(shù),那么,Makefile中所有命令都會忽略錯誤。而如果一個規(guī)則是以.IGNORE作為目標的,那么這個規(guī)則中的所有命令將會忽略錯誤。 若make的參數(shù)的是-k或是-keep-going,如果某規(guī)則中的命令出錯了,那么就終止該規(guī)則的執(zhí)行,但繼續(xù)執(zhí)行其它規(guī)則。,9.3.4 Makefile文件的變量 1Makefile中的變量 頂層Makefile定義并向環(huán)境中輸出了許多變量,并為各個子目錄下的Makefile傳遞一些信息。常用的變量有以下幾類: (1)版本信息 版本信息有VERSION、PATCHLEVEL、SUBLEVEL、EXTRAVERSION和KERNELRE LEASE等變量,用來定義當前內(nèi)核的版本。比如,VERSION = 2,PATCHLEVEL = 4,SUBLEVEL = 18,EXTRAVERSION = -rmk7,共同構(gòu)成內(nèi)核的發(fā)行版本KERNELRELEASE:2.4.18-rmk7。,(2)CPU體系結(jié)構(gòu)ARCH 在頂層Makefile的開頭,用ARCH定義目標CPU的體系結(jié)構(gòu),比如,ARCH:=arm。許多子目錄的Makefile中,要根據(jù)ARCH的定義選擇編譯源文件的列表。 (3)路徑信息TOPDIR和SUBDIRS TOPDIR定義了Linux內(nèi)核源代碼所在的根目錄。例如,各個子目錄下的Makefile通過$(TOPDIR)/Rules.make就可以找到Rules.make的位置。 SUBDIRS定義了一個目錄列表,在編譯內(nèi)核或模塊時,頂層Makefile根據(jù)SUBDIRS來決定進入哪些子目錄。SUBDIRS的值取決于內(nèi)核的配置,在頂層Makefile中SUBDIRS賦值為kernel drivers mm fs net ipc lib;根據(jù)內(nèi)核的配置情況,在arch/*/Makefile中擴充了SUBDIRS的值,可參考arch/arm/Makefile的例子。,(4)內(nèi)核組成信息HEAD,CORE_FILES,NETWORKS,DRIVERS,LIBS。 Linux內(nèi)核文件vmlinux是由以下規(guī)則產(chǎn)生的: vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o -start-group $(CORE_FILES) $(DRIVERS) $(NETWORKS) $(LIBS) -end-group -o vmlinux 可以看出,vmlinux是由HEAD、main.o、version.o、CORE_FILES、DRIVERS、NETWORKS和LIBS組成的。,這些變量(如HEAD)都是用來定義鏈接生成vmlinux所需的目標文件和庫文件列表。其中,HEAD在arch/arm/Makefile中定義,用來確定最先鏈接進vmlinux的文件列表。比如,對于ARM系列HEAD的定義為: HEAD := arch/arm/kernel/head-$(PROCESSOR).o arch/arm/kernel/init_task.o 表明head-$(PROCESSOR).o和init_task.o需要最先被鏈接到vmlinux中。PROCESSOR為armv或armo,取決于目標CPU。,(5)編譯信息CPP,CC,AS,LD,AR,CFLAGS,LINKFLAGS 在Rules.make中定義的是編譯的通用規(guī)則,具體到特定的場合,需明確給出編譯環(huán)境,編譯環(huán)境是在以上的變量中定義的。針對交叉編譯的要求,定義了CROSS_COMPILE。比如: CROSS_COMPILE = arm-linux- CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld ,由于CROSS_COMPILE定義了交叉編譯器前綴arm-linux-,表明所有的交叉編譯工具都是以arm-linux-開頭的,所以在各個交叉編譯器工具之前,都加入了$(CROSS_COMPILE),以組成一個完整的交叉編譯工具文件名,比如,arm-linux-gcc。 CFLAGS定義了傳遞給C編譯器的參數(shù)。 LINKFLAGS是鏈接生成vmlinux時,由鏈接器使用的參數(shù)。LINKFLAGS在arm/*/ Makefile中定義,比如: #arch/arm/Makefile LINKFLAGS:=-p-X-Tarch/arm/vmlinux.lds,(6)配置變量CONFIG_* .config文件中有許多的配置變量等式,用來說明用戶配置的結(jié)果。 例如,CONFIG_MODULES=y 表明用戶選擇了Linux內(nèi)核的模塊功能。 .config被頂層Makefile包含后,就形成許多的配置變量,每個配置變量具有確定的值:y表示本編譯選項對應(yīng)的內(nèi)核代碼被靜態(tài)編譯進Linux內(nèi)核;m表示本編譯選項對應(yīng)的內(nèi)核代碼被編譯成模塊;n表示不選擇此編譯選項;如果沒有賦值,那么配置變量的值為空。,2Rules.make變量 Rules.make定義了所有Makefile共用的編譯規(guī)則。 Rules.make文件定義了許多編譯、鏈接列表變量。 O_OBJS、L_OBJS、OX_OBJS和LX_OBJS:這些變量代表的是本級目錄下需要編譯進Linux內(nèi)核vmlinux的目標文件列表,其中OX_OBJS和LX_OBJS中的“X”表明目標文件使用了EXPORT_SYMBOL輸出符號。 M_OBJS和MX_OBJS:定義本級目錄下需要被編譯成可裝載模塊的目標文件列表。同樣,MX_OBJS中的“X”表明目標文件使用了EXPORT_SYMBOL輸出符號。 O_TARGET和L_TARGET:每個子目錄下都有一個O_TARGET或L_TARGET,Rules.make首先從源代碼編譯生成O_OBJS和OX_OBJS中所有的目標文件,然后使用$(LD) -r把它們鏈接成一個O_TARGET或L_TARGET。O_TARGET以.o結(jié)尾,而L_TARGET以.a結(jié)尾。,3. 追加變量值 可以使用“+=”操作符給變量追加值,例如: objects = main.o foo.o bar.o utils.o objects += another.o 于是,$(objects)值變成:“main.o foo.o bar.o utils.o another.o”,等價于: objects = main.o foo.o bar.o utils.o objects := $(objects) another.o 若變量之前沒有定義過,那么“+=”會自動變成“=”;若前面有變量定義,那么“+=”會繼承于前次操作的賦值符;若前一次的是“:=”,那么“+=”會以“:=”作為其賦值符。,4目標變量 其語法是: : 可以是各種賦值表達式,如“=”、“:=”、“+=”或是“?=”。 第二個語法是針對于make命令行帶入的變量,或是系統(tǒng)環(huán)境變量。這個特性非常的有用,當設(shè)置了這樣一個變量,這個變量會作用到由這個目標所引發(fā)的所有的規(guī)則中去。,如:prog : CFLAGS = -g prog : prog.o foo.o bar.o $(CC) $(CFLAGS) prog.o foo.o bar.o prog.o : prog.c $(CC) $(CFLAGS) prog.c foo.o : foo.c $(CC) $(CFLAGS) foo.c bar.o : bar.c $(CC) $(CFLAGS) bar.c 在這個示例中,不管全局的$(CFLAGS)的值是什么,在prog目標以及其所引發(fā)的所有規(guī)則中(prog.o foo.o bar.o的規(guī)則),$(CFLAGS)的值都是“-g”。,9.3.5 Makefile文件的條件判斷 條件表達式的語法1: Endif 條件表達式的語法2: Else Endif,9.3.5 Makefile文件的條件判斷 例如: bar = foo = $(bar) ifdef foo frobozz = yes else frobozz = no endif 這個例子中,條件為真,“$(frobozz)”值是“yes”。,9.3.6 Makefile文件中常用函數(shù) 函數(shù)的調(diào)用語法 函數(shù)調(diào)用,很像變量的使用,也是以“$”來標識的,其語法如下: $( ) 或是: $ 其中:就是函數(shù)名;是函數(shù)的參數(shù),參數(shù)間以逗號“,”分隔,而函數(shù)名和參數(shù)之間以“空格”分隔。函數(shù)調(diào)用以“$”開頭,以圓括號或花括號把函數(shù)名和參數(shù)括起。如:$(subst a,b,$(x)。,2字符串函數(shù) (1) 字符串處理函數(shù) $(subst , ) 名稱:字符串替換函數(shù)subst。 功能:把字串中的字符串替換成。 返回:函數(shù)返回被替換過后的字符串。 (2)查找字符串函數(shù)findstring $(findstring , ) 功能:在字串中查找字串。 返回:若找到,那么返回,否則返回空字符串。,(3)過濾函數(shù)filter $(filter , ) 功能:以模式過濾字符串中的單詞,保留符合模式的單詞??梢杂卸鄠€模式。 返回:返回符合模式的字串。 例如: sources := foo.c bar.c baz.s ugh.h foo: $(sources) cc $(filter %.c %.s,$(sources) -o foo $(filter %.c %.s,$(sources)返回的值是“foo.c bar.c baz.s”。,(4)反過濾函數(shù)filter-out $(filter-out , ) 功能:以模式過濾字符串中的單詞,去除符合模式的單詞??梢杂卸鄠€模式。 返回:返回不符合模式的字串。 示例: objects=main1.o foo.o main2.o bar.o mains=main1.o main2.o $(filter-out $(mains),$(objects) 返回值是“foo.o bar.o”。,(5)排序函數(shù)sort $(sort ) 功能:給字符串中的單詞排序(升序)。 返回:返回排序后的字符串。 例如:$(sort foo bar lose)返回“bar foo lose”。,9.3.7 子目錄Makefile 子目錄Makefile用來控制本級目錄下源代碼編譯規(guī)則。下面是一個子目錄Makefile文件。 # Makefile for the linux kernel. # All of the (potential) objects that export symbols. # This list comes from grep l EXPORT_SYMBOL *.hc. export-objs := tc.o # Object file lists. obj-y := obj-m := obj-n := obj- :=,obj-$(CONFIG_TC) += tc.o obj-$(CONFIG_ZS) += zs.o obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o # Files that are both resident and modular: remove from modular. obj-m := $(filter-out $(obj-y), $(obj-m) # Translate to Rules.make lists. L_TARGET := tc.a L_OBJS := $(sort $(filter-out $(export-objs), $(obj-y) LX_OBJS := $(sort $(filter $(export-objs), $(obj-y) M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m) MX_OBJS := $(sort $(filter $(export-objs), $(obj-m) Include $(TOPDIR)/Rules.make,9.4 嵌入式Linux引導(dǎo)程序 9.4.1 Bootloader引導(dǎo)程序 1Bootloader的架構(gòu)和功能 Bootloader的主要功能有: 初始化CPU 的主頻、SDRAM、中斷、串口等硬件; 啟動Linux內(nèi)核并提供一個RAMDISK; 通過串口下載內(nèi)核或RAMDISK到目標板上; 將修改過的內(nèi)核或RAMDISK寫入到Flash內(nèi); 為用戶提供一個命令接口。,Bootloader引導(dǎo)程序分為stagel和stage2兩個階段。 (1)Bootloader的stage1 包括以下步驟: 屏蔽所有的中斷 。為中斷提供服務(wù)的通常是操作系統(tǒng),因此在執(zhí)行Bootloader的過程中可以不響應(yīng)任何中斷。中斷屏蔽通過寫CPU的中斷屏蔽寄存器來完成。 設(shè)置CPU的時鐘頻率和速度。 初始化RAM設(shè)置系統(tǒng)內(nèi)存控制器的功能寄存器和各內(nèi)存庫控制寄存器等。 為加載stage2準備RAM空間。 拷貝stage2到RAM中。 跳轉(zhuǎn)到stage2的入口點。,(2)Bootloader的stage2 stage2的功能是通過串口下載Linux內(nèi)核到目標板上。 包括以下幾個步驟: 初始化本階段要使用到的硬件設(shè)備。通常包括:初始化至少一個串口,以便和終端用戶進行I/O輸出信息;初始化計時器等。 檢測系統(tǒng)的內(nèi)存映射。所謂內(nèi)存映射就是指在整個4GB物理地址空間中有哪些地址范圍被分配用來尋址系統(tǒng)的RAM單元。 加載內(nèi)核映像和根文件系統(tǒng)從Flash讀入到RAM中。包括兩個方面:第一方面是內(nèi)核映像所占用的內(nèi)存范圍;第二方面是根文件系統(tǒng)所占用的內(nèi)存范圍。在規(guī)劃內(nèi)存占用布局時,主要考慮基地址和映像的大小兩個方面。 設(shè)置內(nèi)核的啟動參數(shù)。 調(diào)用內(nèi)核。Bootloader調(diào)用Linux內(nèi)核的方法是直接跳轉(zhuǎn)到內(nèi)核的第一條指令處。,2BootLoader代碼分析 下面對引導(dǎo)程序2410INIT.S進行分析,以加深對BootLoader的理解。在第一階段完成依賴于體系結(jié)構(gòu)硬件初始化的代碼,包括禁止看門狗、禁止中斷、初始化各控制寄存器拷貝自身到RAM等。, IMPORT Main AREA Init,CODE,READONLY ENTRY b ResetHandler ResetHandler ldr r0,=WTCON ldr r1,=0x0 str r1,r0 ldr r0,=INTMSK ldr r1,=0xffffffff str r1,r0 ldr r0,=INTSUBMSK ldr r1,=0x7ff,str r1,r0 ldr r0,=LOCKTIME ldr r1,=0xffffff str r1,r0 ldr r0,=SMRDATA ldr r1,=BWSCON add r2, r0, #52 0 ldr r3, r0, #4 str r3, r1, #4 cmp r2, r0 bne %B0 ,第二階段通常用C語言實現(xiàn),包括內(nèi)存管理單元初始化、時鐘設(shè)置、端口設(shè)置和串口初始化等。 void Isr_Init(void) rINTMOD = 0x0; /工作在IRQ模式 rINTMSK = BIT_ALLMSK; /屏蔽中斷 rINTSUBMSK = BIT_SUB_ALLMSK; /屏蔽子中斷 ,void Main(void) MMU_Init(); /MMU初始化 ChangeClockDivider(1,1); / 設(shè)置時鐘除法器-1:2:4 ChangeMPllValue(0xa1,0x3,0x1); / 時鐘值FCLK=202.8MHz Port_Init(); Isr_Init(); Uart_Init(0,115200); Uart_Select(0);,while(1) Uart_Printf(“nnSMDK2410 Board (MCU S3C2410) Example Program Ver 1.0(20020521) FCLK = %d Hznn“, FCLK); ,9.4.2 VIVI簡介 VIVI是韓國Mizi公司開發(fā)的BootLoader,可用于ARM9處理器的引導(dǎo)。VIVI利用串行通信為用戶提供接口。它有如下作用: 把內(nèi)核(kernel)從flash復(fù)制到RAM,然后啟動它; 初始化硬件; 下載程序并寫入flash(通常由串口或者網(wǎng)口先把內(nèi)核下載到RAM中,然后寫入flash); 檢測目標板(bootloader會有一些簡單的代碼用以測試目標板硬件的好壞)。,1. VIVI的命令 (1)load命令 將二進制文件載入到Flash或者RAM,命令格式: load | 其中:描述裝載位置,有flash和ram兩種選項; 或 描述裝載的地址,如果有提前定義的mtd分區(qū)信息,可以只輸入分區(qū)名稱,否則需要指定地址和大??;參數(shù) 確定文件的傳輸協(xié)議,常采用的選項“x”用來指定采用xmodem協(xié)議。 例如:vivi load flash kernel x,裝載壓縮映像文件zImage到flash存儲器中,地址是kernel分區(qū),并采用xmodem傳輸協(xié)議。 例如:vivi load flash 0x80000 0xc0000 x。,(2)part命令 part命令用來操作MTD分區(qū)信息,比如顯示、增加、刪除、復(fù)位、保存MTD分區(qū)等。 part show:顯示mtd分區(qū)信息。 part add :增加新的mtd分區(qū),其中為新mtd分區(qū)名稱,是mtd器件的偏移,表示mtd分區(qū)的大小,表示分區(qū)類型,可選項有JFFS2、LOCKED和BONFS。 part del :刪除一個mtd分區(qū)。 part reset:恢復(fù)mtd 分區(qū)為默認值。 part save:在flash中永久保存參數(shù)值和分區(qū)信息。,(3)param命令 param命令用來設(shè)置或者查看參數(shù)。 例如:改變linux command line,使用 vivi param set linux_cmd_line “you wish.”。 也可以改變引導(dǎo)程序啟動的時間,使用 vivi param set boot_delay 100000實現(xiàn)。,(4)boot命令 boot命令用來引導(dǎo)存儲在flash存儲器或者ram中的linux內(nèi)核。命令格式: boot | 參數(shù) 設(shè)定存儲linux內(nèi)核映像的位置,可選項有ram、nor和smc。 參數(shù) 或 描述存儲內(nèi)核的地址,如果有提前定義的mtd分區(qū)信息,可以只輸入分區(qū)名稱,否則需要指定地址和大小。 例如:vivi boot nor 0x80000表示從flash存儲器中讀出linux內(nèi)核,偏移是0x80000。,(5)flash命令 flash命令是存儲器管理命令, 例如: flash erase | 表示擦除flash存儲器。,2VIVI的目錄樹 VIVI的目錄如圖9.1所示,2VIVI的目錄樹 VIVI包括的目錄具體如下: arch:包括所有VIVI支持的目標板的子目錄。 Documentation:存放了許多文檔,包括VIVI使用指南。 drivers:其中包括了引導(dǎo)內(nèi)核所需的MTD設(shè)備和串口驅(qū)動程序。MTD目錄下分maps、nand和nor三個目錄,實現(xiàn)對Nand Flash和Nor Flash的讀寫控制。Serial目錄下的文件實現(xiàn)對串口的控制,并支持xmodem和ymodem協(xié)議。, include:頭文件的公共目錄,其中有S3C2410.h。Platform/smdk2410.h定義了與目標板相關(guān)的資源配置參數(shù),修改波特率、引導(dǎo)參數(shù)和物理內(nèi)存映射等參數(shù)即可配置目標板。 init:此目錄只有main.c和version.c兩個文件。與普通的C程序一樣,VIVI將從main函數(shù)開始執(zhí)行。 lib:一些平臺公共的接口代碼,比如,time.c里的udelay()和mdelay()。 scripts:此目錄存放了配置所需的腳本文件,如Menuconfig和Configure文件,以方便對VIVI的配置。,9.5 嵌入式Linux 下程序調(diào)試應(yīng)用舉例 9.5.1 Linux宿主機下的應(yīng)用程序調(diào)試 下面用一個例子來介紹Linux開發(fā)工具GNU gcc的編譯和GNU gdb調(diào)試器的使用。 1 gcc編譯器的使用 假定例中有4個文件,分別是hello.h、starfun.h、hello.c和star.c。使用Vi編輯器完成hello.h、starfun.h、hello.c和star.c 4個文件的內(nèi)容輸入。,Starfun.h 文件內(nèi)容如下: /*starfun.h*/ #ifndef STARFUN_H #define STARFUN_H #define NUM 4 #define NUMBER 3 int star1() int i,j,k; for(k=1;k=NUM;+k) for(i=1;i=(NUM-k);+i) printf(“ “); for(j=1;j=(2*k-1);+j) printf(“*“); printf(“n“); return 0; ,int star2() int i,j,k; for(k=NUMBER;k=0;-k) for(i=1;i=(NUMBER-k+1);+i) printf(“ “); for(j=1;j=(2*k-1);+j) printf(“*“); printf(“n“); return 0; #endif,hello.h文件內(nèi)容如下: /*hello.h*/ #ifndef HELLO_H #define HELLO_H void hello() star1(); printf(“hello,my friendsn“); #endif hello.c 文件內(nèi)容如下: void showhello() hello(); ,star.c文件內(nèi)容如下: #include “starfun.h“ #include “hello.h“ #include int main() star1(); star2(); showhello(); return 0; ,分析上述4個程序,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論