![Bootloader基礎(chǔ)知識.ppt_第1頁](http://file1.renrendoc.com/fileroot2/2020-1/11/81f92907-4412-4361-903e-842e6cb6a6b5/81f92907-4412-4361-903e-842e6cb6a6b51.gif)
![Bootloader基礎(chǔ)知識.ppt_第2頁](http://file1.renrendoc.com/fileroot2/2020-1/11/81f92907-4412-4361-903e-842e6cb6a6b5/81f92907-4412-4361-903e-842e6cb6a6b52.gif)
![Bootloader基礎(chǔ)知識.ppt_第3頁](http://file1.renrendoc.com/fileroot2/2020-1/11/81f92907-4412-4361-903e-842e6cb6a6b5/81f92907-4412-4361-903e-842e6cb6a6b53.gif)
![Bootloader基礎(chǔ)知識.ppt_第4頁](http://file1.renrendoc.com/fileroot2/2020-1/11/81f92907-4412-4361-903e-842e6cb6a6b5/81f92907-4412-4361-903e-842e6cb6a6b54.gif)
![Bootloader基礎(chǔ)知識.ppt_第5頁](http://file1.renrendoc.com/fileroot2/2020-1/11/81f92907-4412-4361-903e-842e6cb6a6b5/81f92907-4412-4361-903e-842e6cb6a6b55.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、第六章 Bootloader,一個嵌入式 Linux 系統(tǒng)從軟件的角度看通??梢苑譃槲鍌€層次:,引導(dǎo)加載程序 包括固化在固件中的 boot 代碼(可選),和 Bootloader 兩大部分。 2. Linux 內(nèi)核 特定于嵌入式板子的定制內(nèi)核(包括驅(qū)動程序)以及內(nèi)核的 啟動參數(shù)。 3. 文件系統(tǒng) 建立于 Flash 設(shè)備之上文件系統(tǒng)。 4.驅(qū)動程序編寫(移植) 5. 用戶應(yīng)用程序 特定于用戶的應(yīng)用程序。有時在用戶應(yīng)用程序和內(nèi)核層之間 可能還會包括一個嵌入式圖形用戶界面。常用的嵌入式 GUI 有:QT 和 MiniGUI 。,固態(tài)存儲設(shè)備的典型空間分配結(jié)構(gòu),引導(dǎo)加載程序是系統(tǒng)加電后運行的第一段軟
2、件代碼。 在 PC 機中: PC 機中的引導(dǎo)加載程序由 BIOS(其本質(zhì)就是一段固 件程序)和位于硬盤中的OS Boot Loader(比如,LILO 和 GRUB 等)一起組成。 BIOS: 在完成硬件檢測和資源分配后,將硬盤中的 Boot Loader 讀到系統(tǒng)的 RAM 中,然后將控制權(quán)交給 OS Boot Loader。 Boot Loader: 主要運行任務(wù)就是將內(nèi)核映象從硬盤上讀到 RAM 中,然后跳轉(zhuǎn)到內(nèi)核的入口點去運行,也即開始啟動 操作系統(tǒng)。,在嵌入式系統(tǒng)中: 通常并沒有像 BIOS 那樣的固件程序 (有的嵌入式 CPU 也會內(nèi)嵌一段短小的啟動程序) ,因此整個系統(tǒng)的加載啟動
3、任務(wù)就完全由 Boot Loader 來完成。 比如在一個基于 ARM7TDMI core 的嵌入式系統(tǒng) 中,系統(tǒng)在上電或復(fù)位時通常都從地址 0 x00000000 處 開始執(zhí)行,而在這個地址處安排的通常就是系統(tǒng)的 Boot Loader 程序。,系統(tǒng)加電或復(fù)位后,所有的處理器通常都從某個預(yù)先 安排的地址上取指令。 比如,ARM在復(fù)位時從地址0 x0取指。 嵌入式系統(tǒng)中通常都有某種類型的固態(tài)存儲設(shè)備(比 如:ROM、EEPROM 或FLASH 等)被映射到這個預(yù)先安 排的地址上。因此在系統(tǒng)加電后,處理器將首先執(zhí)行 Bootloader 程序。 Bootloader是最先被系統(tǒng)執(zhí)行的程序。,每種
4、不同的 CPU 體系結(jié)構(gòu)都有不同的 Boot Loader。 有些 Boot Loader 也支持多種體系結(jié)構(gòu)的 CPU,比如 U-Boot 就同時支持 ARM 體系結(jié)構(gòu)和MIPS體系結(jié)構(gòu)。 Boot Loader 實際上也依賴于具體的嵌入式板級 設(shè)備的配置。對于兩塊不同的嵌入式板而言,即使 它們是基于同一種 CPU 而構(gòu)建的,要想讓運行在一 塊板子上的 Boot Loader 程序也能運行在另一塊 板子上,通常也都需要修改 Boot Loader 的源程序。,一、 bootloader的基本概念 1、什么是bootloader(引導(dǎo)加載程序) 簡單地說BootLoader就是在操作系統(tǒng)內(nèi)核或
5、用戶應(yīng)用程序運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖(有的CPU沒有內(nèi)存映射功能如S3C44B0),從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核或用戶應(yīng)用程序準(zhǔn)備好正確的環(huán)境。,2、 BootLoader的操作模式 多數(shù)BootLoader都包含兩種不同的操作模式?!皢蛹虞d”模式和“下載”模式,這種區(qū)別僅對于開發(fā)人員才有意義。但從最終用戶的角度看,BootLoader的作用就是用來加載操作系統(tǒng),而并不存在所謂的啟動加載模式與下載工作模式的區(qū)別。 啟動加載(Boot loading)模式:這種模式也稱為“自主”(Autono
6、mous)模式,也即BootLoader從目標(biāo)機上的某個固態(tài)存儲設(shè)備上將操作系統(tǒng)加載到RAM中運行,整個過程并沒有用戶的介入。這種模式是BootLoader的正常工作模式。因此在嵌入式產(chǎn)品發(fā)布的時候, BootLoader顯然必須工作在這種模式下。,下載(Down loading)模式: 在這種模式下 目標(biāo)機上的BootLoader 將通過串口連接或網(wǎng)絡(luò)連接等通信手段從主機下載文件,比如:下載應(yīng)用程序、數(shù)據(jù)文件、內(nèi)核映像等。從主機下載的文件通常首先被BootLoader保存到目標(biāo)機的RAM中,然后再被BootLoader寫到目標(biāo)機上的固態(tài)存儲設(shè)備中。BootLoader的這種模式通常在系統(tǒng)更新
7、時使用。工作于這種模式下的 BootLoader通常都會向它的終端用戶提供一個簡單的命令行接口。,最常見的情況是,目標(biāo)機上的BootLoader通過串口與主機之間進(jìn)行文件傳輸,傳輸協(xié)議通常xmodem/ymodem/zmodem協(xié)議中的一種。但是,由于串口傳輸?shù)乃俣仁怯邢薜模虼送ㄟ^以太網(wǎng)連接并借助TFTP協(xié)議來下載文件是個更好的選擇。但是,在通過以太網(wǎng)連接和TFTP協(xié)議來下載文件時,因為主機方必須有一個軟件用來的提供TFTP服務(wù),所以操作相對復(fù)雜。,3、BootLoader的啟動過程 由于 Boot Loader 的實現(xiàn)依賴于 CPU 的體系結(jié)構(gòu),因此大多數(shù) Boot Loader 的啟動都
8、分為 stage1 和 stage2兩大部分。依賴于 CPU 體系結(jié)構(gòu)的代碼,比如設(shè)備初始化代碼等,通常都放在 stage1中,而且通常都用匯編語言來實現(xiàn),以達(dá)到短小精悍的目的。而 stage2則通常用C語言來實現(xiàn),這樣可以實現(xiàn)更復(fù)雜的功能,而且代碼會具有更好的可讀性和可移植性。,通常包括以下步驟(以執(zhí)行的先后順序): 硬件設(shè)備初始化 1 屏蔽所有的中斷。為中斷提供服務(wù)通常是 OS 設(shè)備驅(qū)動程序的責(zé)任,因此在 Boot Loader 的執(zhí)行全過程中可以不必響應(yīng)任何中斷。中斷屏蔽可以通過寫 CPU 的中斷屏蔽寄存器或狀態(tài)寄存器(比如 ARM 的 CPSR 寄存器)來完成。 2 設(shè)置 CPU 的速
9、度和時鐘頻率。 3 RAM 初始化。包括正確地設(shè)置系統(tǒng)的內(nèi)存控制器的功能寄存器以及各內(nèi)存庫控制寄存器等。 4 初始化 LED。典型地,通過 GPIO 來驅(qū)動 LED,其目的是表明系統(tǒng)的狀態(tài)是 OK 還是 Error。如果板子上沒有 LED,那么也可以通過初始化 UART 向串口打印 Boot Loader 的 Logo 字符信息來完成這一點。 5 關(guān)閉 CPU 內(nèi)部指令數(shù)據(jù) cache。,Boot Loader 的 stage1,為加載 Boot Loader 的 stage2 準(zhǔn)備 RAM 空間。 為了獲得更快的執(zhí)行速度,通常把 stage2 加載到 RAM 空間中來執(zhí)行,因此必須為加載 B
10、oot Loader 的 stage2 準(zhǔn)備好一段可用的 RAM 空間范圍。 空間大小最好是 memory page 大小(通常是4KB)的倍數(shù)。一般而言,1M 的 RAM 空間已經(jīng)足夠了。具體的地址范圍可以任意安排。 比如 blob 就將它的 stage2 可執(zhí)行映像安排到從系統(tǒng) RAM 起始地址 0 xc0200000 開始的 1M 空間內(nèi)執(zhí)行。 拷貝 Boot Loader 的 stage2 到 RAM 空間中。 拷貝時要確定兩點:(1) stage2 的可執(zhí)行映象在固態(tài)存儲設(shè)備的存放起始地址和終止地址;(2) RAM 空間的起始地址。 設(shè)置好堆棧。 堆棧指針的設(shè)置是為了執(zhí)行 C 語言代
11、碼作好準(zhǔn)備。 通常我們可以把 sp 的值設(shè)置為(stage2_end-4),也即在前面所安排的那個1MB的RAM 空間的最頂端(堆棧向下生長)。 此外,在設(shè)置堆棧指針 sp 之前,也可以關(guān)閉 LED ,以提示用戶準(zhǔn)備跳轉(zhuǎn)到 stage2。,跳轉(zhuǎn)到 stage2 的 C 入口點。 在上述一切都就緒后,就可以跳轉(zhuǎn)到 Boot Loader 的 stage2 去執(zhí)行了。在ARM系統(tǒng)中,可以通過修改PC寄存器為合適的地址來實現(xiàn)。,比如,用以下代碼來實現(xiàn)兩個階段的交接工作。 如(U-Boot中可以用以下兩行代碼實現(xiàn)) ldr pc _start_armboot _start_armboot:.word
12、start_armboot 在vivi中是通過以下實現(xiàn)的: bl main mov pc,#FLASH_BASE,stage2 的代碼通常用 C 語言來實現(xiàn),以便于實現(xiàn)更復(fù)雜的功能和取得更好的代碼可讀性和可移植性。 Boot Loader 的 stage2 通常包括以下步驟(以執(zhí)行的先后順序): 初始化本階段要使用到的硬件設(shè)備。 通常包括:(1)初始化至少一個串口,以便和終端用戶進(jìn)行 I/O 輸出信息;(2)初始化計時器等。設(shè)備初始化完成后,可以輸出一些打印信息,程序名字字符串、版本號等。 檢測系統(tǒng)內(nèi)存映射(memory map)。 所謂內(nèi)存映射就是指在整個 4GB 物理地址空間中有哪些地址范
13、圍被分配用來尋址系統(tǒng)的 RAM 單元。比如,在 SA-1100 CPU 中,從0 xC000,0000 開始的 512M 地址空間被用作系統(tǒng)的 RAM 地址空間,而在 Samsung S3C44B0X CPU 中,從0 x0c00,0000 到 0 x1000,0000 之間的 64M 地址空間被用作系統(tǒng)的 RAM 地址空間。,Bootloader 的stage2,將 kernel 映像和根文件系統(tǒng)映像從 flash 上讀到 RAM 空間中。 (1)規(guī)劃內(nèi)存占用的布局這里包括兩個方面:內(nèi)核映像所占用的內(nèi)存范圍;根文件系統(tǒng)所占用的內(nèi)存范圍。在規(guī)劃內(nèi)存占用的布局時,主要考慮基地址和映像的大小兩個方
14、面。 (2)從 Flash 上拷貝數(shù)據(jù) 為內(nèi)核設(shè)置啟動參數(shù)。 在將內(nèi)核映像和根文件系統(tǒng)映像拷貝到 RAM 空間中后,就可以準(zhǔn)備啟動 Linux 內(nèi)核了。但是在調(diào)用內(nèi)核之前,應(yīng)該作一步準(zhǔn)備工作,即:設(shè)置 Linux 內(nèi)核的啟動參數(shù)。 調(diào)用內(nèi)核。,VIVI簡介,VIVI是韓國Mizi公司開發(fā)的BootLoader,可用于ARM9處理器的引導(dǎo)。VIVI利用串行通信為用戶提供接口。為連接VIVI,首先利用串口電纜連接宿主機和目標(biāo)板,然后在主機上運行串口通信程序(minicom),并在目標(biāo)板上正確設(shè)置VIVI以支持串口。正確連接后,就可以由串口通信程序顯示提示信息,提示信息的最后一行如下所示: Pres
15、s Return to start the LINUX now, any other key for vivi. VIVI也有前面說過的兩種工作模式,啟動模式可以在一段時間后自行啟動Linux內(nèi)核,這是VIVI的默認(rèn)方式。出現(xiàn)上述信息后,如果按除回車鍵外的任意鍵,即可進(jìn)入下載模式,出現(xiàn)“vivi”提示符。在下載模式下,VIVI為用戶提供了一個命令行接口,通過該接口可以使用VIVI提供的一些命令。,二、常用BootLoader代碼分析,1load命令 將二進(jìn)制文件載入到Flash或者RAM,命令格式: load | 其中命令行參數(shù)描述裝載位置,有flash和ram兩種選項;參數(shù) 或 描述裝載的地
16、址,如果有提前定義的MTD分區(qū)信息,可以只輸入分區(qū)名稱,否則需要指定地址和大小;參數(shù) 確定文件的傳輸協(xié)議,常采用的選項“x”用來指定采用xmodem協(xié)議。 例如:vivi load flash kernel x,裝載壓縮映像文件zImage到flash存儲器中,地址是kernel分區(qū),并采用xmodem傳輸協(xié)議。 也可以指定地址和大小,例如:vivi load flash 0 x80000 0 xc0000 x。,2part命令 操作MTD分區(qū)信息,比如,顯示、增加、刪除、復(fù)位、保存MTD分區(qū)等。 part show:顯示mtd分區(qū)信息。 part add :增加新的mtd分區(qū),其中為新mtd
17、分區(qū)名稱,是mtd器件的偏移,表示mtd分區(qū)的大小,表示分區(qū)類型,可選項有JFFS2、LOCKED和BONFS。 part del :刪除一個mtd分區(qū)。 part reset:恢復(fù)mtd 分區(qū)為默認(rèn)值。 part save:在flash中永久保存參數(shù)值和分區(qū)信息。 3param命令 用來設(shè)置或者察看參數(shù)。例如:改變“l(fā)inux command line”,使用 vivi param set linux_cmd_line “you wish.”。 也可以改變引導(dǎo)程序啟動的時間,使用vivi param set boot_delay 100000實現(xiàn)。,4boot命令 用來引導(dǎo)存儲在flash存
18、儲器或者RAM中的linux內(nèi)核。命令格式: boot | 參數(shù) 設(shè)定存儲linux內(nèi)核映像的位置,可選項有ram、nor和smc。 參數(shù) 或 描述存儲內(nèi)核的地址,如果有提前定義的MTD分區(qū)信息,可以只輸入分區(qū)名稱,否則需要指定地址和大小。 例如:vivi boot nor 0 x80000表示從flash存儲器中讀出linux內(nèi)核,偏移是0 x80000。 5flash命令 存儲器管理命令,例如:flash erase | ,表示擦除flash存儲器。,VIVI的代碼分析與移植,1arch 此目錄包括了所有VIVI支持的目標(biāo)板的子目錄,例如s3c2410目錄 。 2Documentation
19、 存放了許多文檔,非常詳細(xì),主要是VIVI的使用指南。 3drivers 其中包括了引導(dǎo)內(nèi)核所需的MTD設(shè)備(mtd)和串口驅(qū)動程序(serial)。MTD目錄下分maps、nand和nor三個目錄,實現(xiàn)對Nand Flash和Nor Flash的讀寫控制。Serial目錄下的文件實現(xiàn)對串口的控制,并支持xmodem和ymodem協(xié)議。 4include 頭文件的公共目錄,其中的S3C2410.h定義了處理器的一些寄存器,以及NAND Flash的一些寄存器等。Platform/smdk2410.h定義了與目標(biāo)板相關(guān)的資源配置參數(shù),修改波特率、引導(dǎo)參數(shù)和物理內(nèi)存映射等參數(shù)就可適用于自己的目標(biāo)板
20、。,5Init 這個目錄只有main.c和version.c兩個文件。與普通的C程序一樣,VIVI將從main函數(shù)開始執(zhí)行。 6Lib 一些平臺公共的接口代碼,比如,time.c里的udelay()和mdelay()。 7scripts 主要在配置時用到,存放了配置所需的腳本文件,如Menuconfig和Configure文件,以方便對VIVI的配置。,VIVI的運行也可以分為兩個階段。 在第一階段完成含有依賴于CPU體系結(jié)構(gòu)硬件初始化的代碼,利用匯編語言完成。 第二階段是用C語言完成的。在跳轉(zhuǎn)進(jìn)main()函數(shù)之前,利用匯編語言編寫了一段trampoline程序(彈簧床)作為階段2可執(zhí)行鏡像
21、的執(zhí)行入口點。之后可以在trampoline中用處理器的跳轉(zhuǎn)指令進(jìn)入main()函數(shù)中去執(zhí)行。 當(dāng)main()函數(shù)返回時,CPU就進(jìn)行復(fù)位。,vivi的第一階段,完成含依賴于CPU的體系結(jié)構(gòu)硬件初始化的代碼,包括禁止中斷、初始化串口、復(fù)制自身到RAM等。相關(guān)代碼集中在head.S(viviarchs3c2410目錄下):,Head.S: #include config.h #include linkage.h #include machine.h Start of executable code ENTRY(_start) ;程序入口點 ENTRY(ResetEntryPoint) , Exc
22、eption vector table (physical address = 0 x00000000) ;異常向量表物理地址 0 x00: Reset ;復(fù)位異常 b Reset 0 x04: Undefined instruction exception ;未定義的指令異常 UndefEntryPoint: b HandleUndef 0 x08: Software interrupt exception ;軟件中斷異常,SWIEntryPoint: b HandleSWI 0 x0c: Prefetch Abort (Instruction Fetch Memory Abort) ;內(nèi)存
23、操作異常 PrefetchAbortEnteryPoint: b HandlePrefetchAbort 0 x10: Data Access Memory Abort ;數(shù)據(jù)異常 DataAbortEntryPoint: b HandleDataAbort 0 x14: Not used ;未使用 NotUsedEntryPoint: b HandleNotUsed 0 x18: IRQ(Interrupt Request) exception ;普通中斷異常,IRQEntryPoint: b HandleIRQ 0 x1c: FIQ(Fast Interrupt Request) exce
24、ption ;快速中斷異常 FIQEntryPoint: b HandleFIQ VIVI magics ,ARM規(guī)定,在起始必須有8條跳轉(zhuǎn)指令,可以用b,也可以用ldr pc,文件名。這樣的8條規(guī)則的標(biāo)志被arm定義為bootloader的識別標(biāo)志,檢測到這樣的標(biāo)志后,就可以從該位置啟動。這樣的做法是因為開始的時候不一定有bootloader,必須有一種識別機制,如果識別到bootloader,那么就從bootloader啟動。,下面是固定位置存放環(huán)境變量 對vivi的這些magic number,雖然設(shè)計在這里,不過大部分沒有使用。其中0 x20和0 x24沒有使用,在0 x2C處,設(shè)計了
25、一個magic number,組成的格式如下:bit31:24為platform,bit23:16為cpu type,bit15:0為machine id。關(guān)于ARCHITECTURE_MAGIC的定義,在【include/platform/smdk2410.h】, 0 x20: magic number so we can verify that we only put .long 0 0 x24: .long 0 0 x28: where this vivi was linked, so we can put it in memory in the right place .long _s
26、tart 0 x2C: this contains the platform, cpu and machine id .long ARCHITECTURE_MAGIC 0 x30: vivi capabilities .long 0 #ifdef CONFIG_PM ;vivi沒有使用電源管理 0 x34: b SleepRamProc #endif #ifdef CONFIG_TEST 0 x38: b hmi #endif Start VIVI head Reset:, disable watch dog timer ;禁止看門狗計時器 mov r1, #0 x53000000 ;WTCO
27、N寄存器地址是 0 x53000000,清0 mov r2, #0 x0 str r2, r1 #ifdef CONFIG_S3C2410_MPORT3 ;不符合條件,跳到下面的關(guān)中斷 /* 在/vivi/include/autoconf.h中#undef CONFIG_S3C2410_MPORT3*/ mov r1, #0 x56000000 ;GPACON寄存器地址是 0 x56000000 mov r2, #0 x00000005 str r2, r1, #0 x70 ;配置GPHCON控制寄存器 mov r2, #0 x00000001 str r2, r1, #0 x78 ;配置GP
28、HUP上拉寄存器 mov r2, #0 x00000001 str r2, r1, #0 x74 ;配置GPHDAT數(shù)據(jù)寄存器,#endif disable all interrupts ;禁止全部中斷 mov r1, #INT_CTL_BASE mov r2, #0 xffffffff str r2, r1, #oINTMSK ;掩碼關(guān)閉所有中斷 ldr r2, =0 x7ff str r2, r1, #oINTSUBMSK, initialise system clocks ;初始化系統(tǒng)時鐘 mov r1, #CLK_CTL_BASE ;定義CLK_CTL_BASE ox4C000000
29、mvn r2, #0 xff000000 str r2, r1, #oLOCKTIME ldr r2, mpll_50mhz ;CPU的頻率是50MHz str r2, r1, #oMPLLCON #ifndef CONFIG_S3C2410_MPORT1 ;滿足條件,向下執(zhí)行 /* 在/vivi/include/autoconf.h中#undef CONFIG_S3C2410_MPORT1*/ 1:2:4 mov r1, #CLK_CTL_BASE mov r2, #0 x3 str r2, r1, #oCLKDIVN mrc p15, 0, r1, c1, c0, 0 read ctrl
30、register orr r1, r1, #0 xc0000000 Asynchronous mcr p15, 0, r1, c1, c0, 0 write ctrl register now, CPU clock is 200 Mhz ;CPU的頻率是200MHz mov r1, #CLK_CTL_BASE ldr r2, mpll_200mhz str r2, r1, #oMPLLCON,#else 1:2:2 mov r1, #CLK_CTL_BASE ldr r2, clock_clkdivn str r2, r1, #oCLKDIVN mrc p15, 0, r1, c1, c0,
31、0 read ctrl register orr r1, r1, #0 xc0000000 Asynchronous mcr p15, 0, r1, c1, c0, 0 write ctrl register now, CPU clock is 100 Mhz ;CPU的頻率是100MHz mov r1, #CLK_CTL_BASE ldr r2, mpll_100mhz str r2, r1, #oMPLLCON #endif bl memsetup ;跳轉(zhuǎn)到memsetup函數(shù),/* Memsetup函數(shù)的實現(xiàn): ENTRY(memsetup) initialise the static
32、memory set memory control registers ;設(shè)置內(nèi)存控制寄存器的初值 mov r1, #MEM_CTL_BASE adrl r2, mem_cfg_val /* Data Area Memory configuration values .align 4 mem_cfg_val: ;定義好的13*4=52個字節(jié)初值,.long vBWSCON ;總線寬度和等待控制寄存器 在/vivi/include/platform/smdk2410.h中賦值 /* SDRAM從32位變成16位,需要修改vBWSCON的值 */ .long vBANKCON0 .long vBA
33、NKCON1 .long vBANKCON2 .long vBANKCON3,/* 網(wǎng)卡控制器vBANKCON3的值可能需要修改 */ .long vBANKCON4 .long vBANKCON5 .long vBANKCON6 /* SDRAM從32位變成16位,可能需要修改vBANKCON6的值 */ .long vBANKCON7 .long vREFRESH ;SDRAM刷新控制寄存器 .long vBANKSIZE ;可變的組大小寄存器 /* SDRAM從64MB變成32MB,需要修改vBANKSIZE的值 */ .long vMRSRB6 ;BANK6的模式設(shè)置寄存器 .long
34、 vMRSRB7 ;BANK7的模式設(shè)置寄存器 */ add r3, r1, #52 1: ldr r4, r2, #4 str r4, r1, #4 cmp r1, r3 bne 1b ;循環(huán)操作,直到13個寄存器賦值完成 mov pc, lr,*/ #ifdef CONFIG_PM ;vivi考慮不需要使用電源管理 Check if this is a wake-up from sleep ldr r1, PMST_ADDR ldr r0, r1 tst r0, #(PMST_SMR) bne WakeupStart ;查看狀態(tài),判斷是否需要跳轉(zhuǎn)到WakeupStart #endif #i
35、fdef CONFIG_S3C2410_SMDK ;SMDK開發(fā)板使用 All LED on ;點亮開發(fā)板上的LED mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F ;LED使用GPIOF組的管腳 ldr r2,=0 x55aa ;使能EINT0,EINT1,EINT2,EINT3, ;另四個管腳配置成輸出,屏蔽EINT4,5,6,7 str r2, r1, #oGPIO_CON ;配置管腳 mov r2, #0 xff str r2, r1, #oGPIO_UP ;禁止上拉功能 mov r2, #0 x00 str r2, r1, #oGPIO_DAT
36、 ;PORT H 數(shù)據(jù)寄存器,#endif #if 0 SVC ;進(jìn)入系統(tǒng)管理模式 mrs r0, cpsr bic r0, r0, #0 xdf orr r1, r0, #0 xd3 msr cpsr_all, r1 #endif set GPIO for UART ;設(shè)置串口 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_H ;設(shè)置GPIO_H組管腳為串口 ldr r2, gpio_con_uart str r2, r1, #oGPIO_CON ldr r2, gpio_up_uart str r2, r1, #oGPIO_UP /* initial
37、values for GPIO gpio_con_uart: .long vGPHCON ;vGPHCON在/vivi/include/platform/smdk2410.h中賦值 ;#define vGPHCON 0 x0016faaa ;GPIO_H配置為nCTS0,nRTS0, RXD0,TXD0, RXD1, ,TXD1,nCTS1,nRTS1,/* 三個串口都使能,可能需要修改#define vGPHCON 0 x0016aaaa */ gpio_up_uart: .long Vgphup ;同上 #define vGPHUP 0 x000007ff ;The pull-up fun
38、ction is disabled. */ bl InitUART ;跳轉(zhuǎn)到InitUART串口初始化函數(shù) Initialize UART r0 = number of UART port InitUART: ldr r1, SerBase /* .align 4 ;缺省情況下在vivi中只初始化了UART0 SerBase: #if defined(CONFIG_SERIAL_UART0) .long UART0_CTL_BASE ;基地址在/vivi/include/s3c2410.h中定義 #elif defined(CONFIG_SERIAL_UART1) .long UART1_CT
39、L_BASE #elif defined(CONFIG_SERIAL_UART2) .long UART2_CTL_BASE #else #error not defined base address of serial #endif,*/ mov r2, #0 x0 str r2, r1, #oUFCON ; UART FIFO控制寄存器 str r2, r1, #oUMCON ; UART MODEM控制寄存器 mov r2, #0 x3 str r2, r1, #oULCON ; UART 列控制寄存器 ldr r2, =0 x245 str r2, r1, #oUCON ; UART控
40、制寄存器 #define UART_BRD (50000000 / (UART_BAUD_RATE * 16) - 1) mov r2, #UART_BRD; 波特率設(shè)置 str r2, r1, #oUBRDIV ;波特率約數(shù)寄存器 mov r3, #100 mov r2, #0 x0 1: sub r3, r3, #0 x1 tst r2, r3 bne 1b #if 0 mov r2, #U str r2, r1, #oUTXHL ; UART 傳輸緩沖區(qū)寄存器 1: ldr r3, r1, #oUTRSTAT ;UART 錯誤寄存器,and r3, r3, #UTRSTAT_TX_EMP
41、TY tst r3, #UTRSTAT_TX_EMPTY bne 1b mov r2, #0 str r2, r1, #oUTXHL 1: ldr r3, r1, #oUTRSTAT ;UART TX/RX狀態(tài)寄存器 and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne 1b #endif mov pc, lr */ #ifdef CONFIG_DEBUG_LL ;打印調(diào)試信息,缺省未定義 Print current Program Counter ldr r1, SerBase mov r0, #r bl PrintChar
42、mov r0, #n bl PrintChar mov r0, #,bl PrintChar mov r0, pc bl PrintHexWord #endif #ifdef CONFIG_BOOTUP_MEMTEST simple memory test to find some DRAM flaults. bl memtest #endif #ifdef CONFIG_S3C2410_NAND_BOOT ;從NAND Flash啟動 bl copy_myself ;跳轉(zhuǎn)到copy_myself函數(shù) , /* copy_myself: copy vivi to ram;復(fù)制到RAM copy
43、_myself: mov r10, lr reset NAND; 復(fù)位NAND FLASH mov r1, #NAND_CTL_BASE ldr r2, =0 xf830 initial value,str r2, r1, #oNFCONF ;配置NAND FLASH ldr r2, r1, #oNFCONF bic r2, r2, #0 x800 ;芯片使能,Bit11為0,使能,即允許訪問 str r2, r1, #oNFCONF mov r2, #0 xff RESET command strb r2, r1, #oNFCMD ;設(shè)置NAND FLASH命令 mov r3, #0 wai
44、t 1: add r3, r3, #0 x1 cmp r3, #0 xa blt 1b 2: ldr r2, r1, #oNFSTAT wait ready ; NAND FLASH操作狀態(tài)寄存器 tst r2, #0 x1 beq 2b ldr r2, r1, #oNFCONF orr r2, r2, #0 x800 ;禁止芯片,不允許訪問 str r2, r1, #oNFCONF get read to call C functions (for nand_read() ldr sp, DW_STACK_START setup stack pointer mov fp, #0 no pre
45、vious frame, so fp=0 copy vivi to RAM ldr r0, =VIVI_RAM_BASE,*/ mov r1, #0 x0 mov r2, #0 x20000 ;0 x20000-128k字節(jié) bl nand_read_ll ;nand_read_ll在/vivi/arch/s3c2410/nand_read.c中定義 ;r0,r1,r2分別為函數(shù)的三個參數(shù) ;從NANDFlash的0地址拷貝128k到SDRAM指定處 tst r0, #0 x0 beq ok_nand_read #ifdef CONFIG_DEBUG_LL bad_nand_read: ldr
46、 r0, STR_FAIL ldr r1, SerBase bl PrintWord 1: b 1b infinite loop #endif ok_nand_read: #ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif,/*在/vivi/linux/platform/smdk2410.h中定義 #define VIVI_RAM_BASE (DRAM_BASE + DRAM_SIZE - VIVI_RAM_SIZE), verify mov r0, #0 ldr r1, =0 x33f00000
47、mov r2, #0 x400 4 bytes * 1024 = 4K-bytes go_next: ldr r3, r0, #4 ldr r4, r1, #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq done_nand_read bne go_next notmatch: #ifdef CONFIG_DEBUG_LL sub r0, r0, #4 ldr r1, SerBase bl PrintHexWord ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord #endif,1: b 1b done_na
48、nd_read: #ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif mov pc, r10 ;vivi拷貝到SDRAM完成,函數(shù)返回 */ jump to ram ldr r1, =on_the_ram add pc, r1, #0 nop nop 1: b 1b infinite loop on_the_ram: #endif #ifdef CONFIG_DEBUG_LL ldr r1, SerBase ldr r0, STR_STACK bl PrintWord ldr r0, DW_STAC
49、K_START bl PrintHexWord #endif, get read to call C functions ldr sp, DW_STACK_START setup stack pointer mov fp, #0 no previous frame, so fp=0 mov a2, #0 set argv to NULL bl main call main mov pc, #FLASH_BASE otherwise, reboot End VIVI head ,Bootloader的第二階段是用C語言完成的,但是與普通 C語言應(yīng)用程序不同的是,在編譯和鏈接Bootloader時
50、,不能使用glibc庫中的任何支持函數(shù),從哪里跳轉(zhuǎn)進(jìn) main() 函數(shù)呢? 直接把 main() 函數(shù)的起始地址作為整個 stage2 執(zhí)行映像的入口點或許是最直接的想法。 但是這樣做有兩個缺點: 1)無法通過main() 函數(shù)傳遞函數(shù)參數(shù); 2)無法處理 main() 函數(shù)返回的情況。 一種較為巧妙的方法是利用彈簧床的概念,也就是用匯編語言寫一段trampoline 小程序,并將這段程序作為stage2可執(zhí)行映象的執(zhí)行入口點,然后在trampoline匯編小程序中用CPU跳轉(zhuǎn)指令跳入main()函數(shù)中去執(zhí)行。當(dāng)main()函數(shù)返回時,CPU執(zhí)行路徑再次回到trampoline程序。簡而言之
51、,這種方法的思想就是:用這段 trampoline小程序來作為main()函數(shù)的外部包裹。,vivi的第二階段,Trampoline程序的源代碼如下: ldrsp,DW_STACK_START;設(shè)置堆棧指針 movfp,#0 ;no previous frame,so fp=0 mova2,#0 ;set argv to NULL blmain ;call main movpc,#FLASH_BASE ;否則,reboot,vivi的第二階段是從main()函數(shù)開始,同一般的C語言程序一樣,該函數(shù)在/init/main.c文件中,總共可以分為8個步驟。 (1) 函數(shù)開始,通過putstr(vi
52、vi_banner)打印出vivi的版本。 Vivi_banner在/init/version.c文件中定義 (2) 對開發(fā)板進(jìn)行初始化(board_init函數(shù)),board_init是與開發(fā)板緊密相關(guān)的,這個函數(shù)在/arch/s3c2410/smdk.c文件中。開發(fā)板初始化主要完成兩個功能,時鐘初始化(init_time())和通用IO口設(shè)置(set_gpios())。,void set_gpios(void) GPACON = vGPACON; GPBCON = vGPBCON; GPBUP = vGPBUP; GPCCON = vGPCCON; GPCUP = vGPCUP; GPDC
53、ON = vGPDCON; GPDUP = vGPDUP; GPECON = vGPECON; GPEUP = vGPEUP; GPFCON = vGPFCON; GPFUP = vGPFUP; GPGCON = vGPGCON; GPGUP = vGPGUP; GPHCON = vGPHCON; GPHUP = vGPHUP; EXTINT0 = vEXTINT0; EXTINT1 = vEXTINT1; EXTINT2 = vEXTINT2; GPIO口在smdk2410.h(viviincludeplatform目錄下)文件中定義。 這里vGPxCON中的v表示value,oGPxCON
54、中的o表示offset,(3) 內(nèi)存映射初始化和內(nèi)存管理單元的初始化工作: mem_map_init(); mmu_init(); 這兩個函數(shù)都在/arch/s3c2410/mmu.c文件中。 void mem_map_init(void) #ifdef CONFIG_S3C2410_NAND_BOOT mem_map_nand_boot(); #else mem_map_nor(); #endif cache_clean_invalidate(); tlb_invalidate(); 如果配置vivi時使用了NAND作為啟動設(shè)備,則執(zhí)行mem_map_nand_boot(),否則執(zhí)行mem_
55、map_nor()。這里要注意的是,如果使用NOR啟動,則必須先把vivi代碼復(fù)制到RAM中。這個過程是由copy_vivi_to_ram()函數(shù)來完成的。代碼如下: static void copy_vivi_to_ram(void) putstr_hex(Evacuating 1MB of Flash to DRAM at 0 x, VIVI_RAM_BASE); memcpy(void *)VIVI_RAM_BASE, (void *)VIVI_ROM_BASE,VIVI_RAM_SIZE); ,VIVI_RAM_BASE、VIVI_ROM_BASE、VIVI_RAM_SIZE這些值都可以在smdk2410.h中查到,并且這些值必須根據(jù)自己開發(fā)板的RAM實際大小修改。這也是在移植vivi的過程中需要注意的一個地方。 mmu_init()函數(shù)中執(zhí)
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 昆明2025年云南昆明市生態(tài)環(huán)境局所屬事業(yè)單位引進(jìn)高層次人才筆試歷年參考題庫附帶答案詳解
- 2025年中國雙人翻轉(zhuǎn)座椅骨架市場調(diào)查研究報告
- 廣西2025年廣西合浦儒艮國家級自然保護區(qū)管理中心招聘筆試歷年參考題庫附帶答案詳解
- 2025至2031年中國鋁合金絲編織管行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國精密交流脈沖焊接機行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國玻璃衛(wèi)浴產(chǎn)品行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國汽車前大燈鏡片行業(yè)投資前景及策略咨詢研究報告
- 惠州2025年廣東惠州龍門縣市容環(huán)境衛(wèi)生事務(wù)中心招聘編外環(huán)衛(wèi)工人14人筆試歷年參考題庫附帶答案詳解
- 2025年平移大門驅(qū)動系統(tǒng)項目可行性研究報告
- 2025年合金鋼襯項目可行性研究報告
- 婚內(nèi)財產(chǎn)債務(wù)協(xié)議書(通用)
- 血液透析流程圖
- DB11∕T 1653-2019 供暖系統(tǒng)能耗指標(biāo)體系
- 齒輪箱振動信號和故障診斷
- 小學(xué)生急救常識(課件)主題教育班會
- 信息光學(xué)試卷試題及答案
- 文化差異及跨文化交際試題集
- PC-Ф800×800錘式破碎機結(jié)構(gòu)設(shè)計
- 慢病患者隨訪服務(wù)記錄表
- 雙溪課程評量表完整優(yōu)秀版
- 最新社工服務(wù)部組織架構(gòu)
評論
0/150
提交評論