成·人免费午夜视频

    1. <code id="p04wk"><small id="p04wk"><track id="p04wk"></track></small></code>

      <th id="p04wk"></th>
      <tr id="p04wk"><sup id="p04wk"></sup></tr>
        <strike id="p04wk"></strike>
        <tr id="p04wk"></tr>
        <center id="p04wk"></center>

        侵權投訴

        四個方面來討論嵌入式系統的Boot Loader

        2019-12-03 15:50 ? 次閱讀

        一個嵌入式 Linux 系統從軟件的角度看通??梢苑譃樗膫€層次:

        1. 引導加載程序。包括固化在固件(firmware)中的 boot 代碼(可選),和 Boot Loader 兩大部分。

        2. Linux 內核。特定于嵌入式板子的定制內核以及內核的啟動參數。

        3. 文件系統。包括根文件系統和建立于 Flash 內存設備之上文件系統。通常用 ram disk 來作為 root fs。

        4. 用戶應用程序。特定于用戶的應用程序。有時在用戶應用程序和內核層之間可能還會包括一個嵌入式圖形用戶界面。常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 懂。

        引導加載程序是系統加電后運行的第一段軟件代碼?;貞浺幌?PC 的體系結構我們可以知道,PC 機中的引導加載程序由 BIOS(其本質就是一段固件程序)和位于硬盤 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起組成。

        BIOS 在完成硬件檢測和資源分配后,將硬盤 MBR 中的 Boot Loader 讀到系統的 RAM 中,然后將控制權交給 OS Boot Loader。Boot Loader 的主要運行任務就是將內核映象從硬盤上讀到 RAM 中,然后跳轉到內核的入口點去運行,也即開始啟動操作系統。

        而在嵌入式系統中,通常并沒有像 BIOS 那樣的固件程序(注,有的嵌入式 CPU 也會內嵌一段短小的啟動程序),因此整個系統的加載啟動任務就完全由 Boot Loader 來完成。比如在一個基于 ARM7TDMI core 的嵌入式系統中,系統在上電或復位時通常都從地址 0x00000000 處開始執行,而在這個地址處安排的通常就是系統的 Boot Loader 程序。

        本文將從 Boot Loader 的概念、Boot Loader 的主要任務、Boot Loader 的框架結構以及 Boot Loader 的安裝等四個方面來討論嵌入式系統的 Boot Loader。

        Boot Loader 的概念

        簡單地說,Boot Loader 就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環境帶到一個合適的狀態,以便為最終調用操作系統內核準備好正確的環境。

        通常,Boot Loader 是嚴重地依賴于硬件而實現的,特別是在嵌入式世界。因此,在嵌入式世界里建立一個通用的 Boot Loader 幾乎是不可能的。盡管如此,我們仍然可以對 Boot Loader 歸納出一些通用的概念來,以指導用戶特定的 Boot Loader 設計與實現。

        1. Boot Loader 所支持的 CPU 和嵌入式板每種不同的 CPU 體系結構都有不同的 Boot Loader。有些 Boot Loader 也支持多種體系結構的 CPU,比如 U-Boot 就同時支持 ARM 體系結構和MIPS 體系結構。除了依賴于 CPU 的體系結構外,Boot Loader 實際上也依賴于具體的嵌入式板級設備的配置。這也就是說,對于兩塊不同的嵌入式板而言,即使它們是基于同一種 CPU 而構建的,要想讓運行在一塊板子上的 Boot Loader 程序也能運行在另一塊板子上,通常也都需要修改 Boot Loader 的源程序。

        2. Boot Loader 的安裝媒介(Installation Medium)系統加電或復位后,所有的 CPU 通常都從某個由 CPU 制造商預先安排的地址上取指令。比如,基于 ARM7TDMI core 的 CPU 在復位時通常都從地址 0x00000000 取它的第一條指令。而基于 CPU 構建的嵌入式系統通常都有某種類型的固態存儲設備(比如:ROM、EEPROM 或 FLASH 等)被映射到這個預先安排的地址上。因此在系統加電后,CPU 將首先執行 Boot Loader 程序。

        下圖1就是一個同時裝有 Boot Loader、內核的啟動參數、內核映像和根文件系統映像的固態存儲設備的典型空間分配結構圖。

        圖1 固態存儲設備的典型空間分配結構

        4. Boot Loader 的啟動過程是單階段(Single Stage)還是多階段(Multi-Stage)通常多階段的 Boot Loader 能提供更為復雜的功能,以及更好的可移植性。從固態存儲設備上啟動的 Boot Loader 大多都是 2 階段的啟動過程,也即啟動過程可以分為 stage 1 和 stage 2 兩部分。而至于在 stage 1 和 stage 2 具體完成哪些任務將在下面討論。

        5. Boot Loader 的操作模式 (Operation Mode)大多數 Boot Loader 都包含兩種不同的操作模式:“啟動加載”模式和“下載”模式,這種區別僅對于開發人員才有意義。但從最終用戶的角度看,Boot Loader 的作用就是用來加載操作系統,而并不存在所謂的啟動加載模式與下載工作模式的區別。

        啟動加載(Boot loading)模式:這種模式也稱為“自主”(Autonomous)模式。也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程并沒有用戶的介入。這種模式是 Boot Loader 的正常工作模式,因此在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。

        下載(Downloading)模式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 Boot Loader 保存到目標機的 RAM 中,然后再被 Boot Loader 寫到目標機上的FLASH 類固態存儲設備中。

        Boot Loader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以后的系統更新也會使用 Boot Loader 的這種工作模式。工作于這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。

        像 Blob 或 U-Boot 等這樣功能強大的 Boot Loader 通常同時支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進行切換。比如,Blob 在啟動時處于正常的啟動加載模式,但是它會延時 10 秒等待終端用戶按下任意鍵而將 blob 切換到下載模式。如果在 10 秒內沒有用戶按鍵,則 blob 繼續啟動 Linux 內核。

        6. BootLoader 與主機之間進行文件傳輸所用的通信設備及協議最常見的情況就是,目標機上的 Boot Loader 通過串口與主機之間進行文件傳輸,傳輸協議通常是 xmodem/ymodem/zmodem 協議中的一種。但是,串口傳輸的速度是有限的,因此通過以太網連接并借助 TFTP 協議來下載文件是個更好的選擇。

        此外,在論及這個話題時,主機方所用的軟件也要考慮。比如,在通過以太網連接和 TFTP 協議來下載文件時,主機方必須有一個軟件用來的提供 TFTP 服務。

        在討論了 BootLoader 的上述概念后,下面我們來具體看看 BootLoader 的應該完成哪些任務。

        Boot Loader 的主要任務與典型結構框架

        在繼續本節的討論之前,首先我們做一個假定,那就是:假定內核映像與根文件系統映像都被加載到 RAM 中運行。之所以提出這樣一個假設前提是因為,在嵌入式系統中內核映像與根文件系統映像也可以直接在 ROM 或 Flash 這樣的固態存儲設備中直接運行。但這種做法無疑是以運行速度的犧牲為代價的。

        從操作系統的角度看,Boot Loader 的總目標就是正確地調用內核來執行。

        另外,由于 Boot Loader 的實現依賴于 CPU 的體系結構,因此大多數 Boot Loader 都分為 stage1 和 stage2 兩大部分。依賴于 CPU 體系結構的代碼,比如設備初始化代碼等,通常都放在 stage1 中,而且通常都用匯編語言來實現,以達到短小精悍的目的。而 stage2 則通常用C語言來實現,這樣可以實現給復雜的功能,而且代碼會具有更好的可讀性和可移植性。

        Boot Loader 的 stage1 通常包括以下步驟(以執行的先后順序):

        · 硬件設備初始化。

        · 為加載 Boot Loader 的 stage2 準備 RAM 空間?!?拷貝 Boot Loader 的 stage2 到 RAM 空間中?!?設置好堆棧。

        · 跳轉到 stage2 的 C 入口點。

        Boot Loader 的 stage2 通常包括以下步驟(以執行的先后順序):· 初始化本階段要使用到的硬件設備?!?檢測系統內存映射(memory map)?!?將 kernel 映像和根文件系統映像從 flash 上讀到 RAM 空間中?!?為內核設置啟動參數?!?調用內核。

        Boot Loader 的 stage1

        基本的硬件初始化

        這是 Boot Loader 一開始就執行的操作,其目的是為 stage2 的執行以及隨后的 kernel 的執行準備好一些基本的硬件環境。它通常包括以下步驟(以執行的先后順序):

        1. 屏蔽所有的中斷。為中斷提供服務通常是 OS 設備驅動程序的責任,因此在 Boot Loader 的執行全過程中可以不必響應任何中斷。中斷屏蔽可以通過寫 CPU 的中斷屏蔽寄存器或狀態寄存器(比如 ARM 的 CPSR 寄存器)來完成。

        2. 設置 CPU 的速度和時鐘頻率。

        3. RAM 初始化。包括正確地設置系統的內存控制器的功能寄存器以及各內存庫控制寄存器等。

        4. 初始化 LED。典型地,通過 GPIO 來驅動 LED,其目的是表明系統的狀態是 OK 還是 Error。如果板子上沒有 LED,那么也可以通過初始化 UART 向串口打印 Boot Loader 的 Logo 字符信息來完成這一點。

        5. 關閉 CPU 內部指令/數據 cache。

        為加載 stage2 準備 RAM 空間

        為了獲得更快的執行速度,通常把 stage2 加載到 RAM 空間中來執行,因此必須為加載 Boot Loader 的 stage2 準備好一段可用的 RAM 空間范圍。

        由于 stage2 通常是 C 語言執行代碼,因此在考慮空間大小時,除了 stage2 可執行映象的大小外,還必須把堆??臻g也考慮進來。此外,空間大小最好是 memory page 大?。ㄍǔJ?4KB)的倍數。一般而言,1M 的 RAM 空間已經足夠了。具體的地址范圍可以任意安排,比如 blob 就將它的 stage2 可執行映像安排到從系統 RAM 起始地址 0xc0200000 開始的 1M 空間內執行。但是,將 stage2 安排到整個 RAM 空間的最頂 1MB(也即(RamEnd-1MB) - RamEnd)是一種值得推薦的方法。

        為了后面的敘述方便,這里把所安排的 RAM 空間范圍的大小記為:stage2_size(字節),把起始地址和終止地址分別記為:stage2_start 和 stage2_end(這兩個地址均以 4 字節邊界對齊)。因此:stage2_end=stage2_start+stage2_size 另外,還必須確保所安排的地址范圍的的確確是可讀寫的 RAM 空間,因此,必須對你所安排的地址范圍進行測試。具體的測試方法可以采用類似于 blob 的方法,也即:以 memory page 為被測試單位,測試每個 memory page 開始的兩個字是否是可讀寫的。為了后面敘述的方便,我們記這個檢測算法為:test_mempage,其具體步驟如下:

        1. 先保存 memory page 一開始兩個字的內容。2. 向這兩個字中寫入任意的數字。比如:向第一個字寫入 0x55,第 2 個字寫入 0xaa。3. 然后,立即將這兩個字的內容讀回。顯然,我們讀到的內容應該分別是 0x55 和 0xaa。如果不是,則說明這個 memory page 所占據的地址范圍不是一段有效的 RAM 空間。4. 再向這兩個字中寫入任意的數字。比如:向第一個字寫入 0xaa,第 2 個字中寫入 0x55。5. 然后,立即將這兩個字的內容立即讀回。顯然,我們讀到的內容應該分別是 0xaa 和 0x55。如果不是,則說明這個 memory page 所占據的地址范圍不是一段有效的 RAM 空間。6. 恢復這兩個字的原始內容。測試完畢。為了得到一段干凈的 RAM 空間范圍,我們也可以將所安排的 RAM 空間范圍進行清零操作。

        拷貝 stage2 到 RAM 中

        拷貝時要確定兩點:(1) stage2 的可執行映象在固態存儲設備的存放起始地址和終止地址;(2) RAM 空間的起始地址。

        設置堆棧指針 sp

        堆棧指針的設置是為了執行 C 語言代碼作好準備。通常我們可以把 sp 的值設置為(stage2_end-4),也即在 3.1.2 節所安排的那個 1MB 的 RAM 空間的最頂端(堆棧向下生長)。

        此外,在設置堆棧指針 sp 之前,也可以關閉 led 燈,以提示用戶我們準備跳轉到 stage2。

        經過上述這些執行步驟后,系統的物理內存布局應該如下圖2所示。

        跳轉到 stage2 的 C 入口點

        在上述一切都就緒后,就可以跳轉到 Boot Loader 的 stage2 去執行了。比如,在 ARM 系統中,這可以通過修改 PC 寄存器為合適的地址來實現。

        圖2 bootloader 的 stage2 可執行映象剛被拷貝到 RAM 空間時的系統內存布局

        Boot Loader 的 stage2

        正如前面所說,stage2 的代碼通常用 C 語言來實現,以便于實現更復雜的功能和取得更好的代碼可讀性和可移植性。但是與普通 C 語言應用程序不同的是,在編譯和鏈接 boot loader 這樣的程序時,我們不能使用 glibc 庫中的任何支持函數。其原因是顯而易見的。這就給我們帶來一個問題,那就是從那里跳轉進 main() 函數呢?直接把 main() 函數的起始地址作為整個 stage2 執行映像的入口點或許是最直接的想法。但是這樣做有兩個缺點:1)無法通過main() 函數傳遞函數參數;2)無法處理 main() 函數返回的情況。一種更為巧妙的方法是利用 trampoline(彈簧床)的概念。也即,用匯編語言寫一段trampoline 小程序,并將這段 trampoline 小程序來作為 stage2 可執行映象的執行入口點。然后我們可以在 trampoline 匯編小程序中用 CPU 跳轉指令跳入 main() 函數中去執行;而當 main() 函數返回時,CPU 執行路徑顯然再次回到我們的 trampoline 程序。簡而言之,這種方法的思想就是:用這段 trampoline 小程序來作為 main() 函數的外部包裹(external wrapper)。

        下面給出一個簡單的 trampoline 程序示例(來自blob):

        .text.globl _trampoline_trampoline:bl main/* if main ever returns we just call it again */b _trampoline

        可以看出,當 main() 函數返回后,我們又用一條跳轉指令重新執行 trampoline 程序――當然也就重新執行 main() 函數,這也就是 trampoline(彈簧床)一詞的意思所在。

        初始化本階段要使用到的硬件設備

        這通常包括:(1)初始化至少一個串口,以便和終端用戶進行 I/O 輸出信息;(2)初始化計時器等。在初始化這些設備之前,也可以重新把 LED 燈點亮,以表明我們已經進入 main() 函數執行。設備初始化完成后,可以輸出一些打印信息,程序名字字符串、版本號等。

        檢測系統的內存映射(memory map)

        所謂內存映射就是指在整個 4GB 物理地址空間中有哪些地址范圍被分配用來尋址系統的 RAM 單元。比如,在 SA-1100 CPU 中,從 0xC000,0000 開始的 512M 地址空間被用作系統的 RAM 地址空間,而在 Samsung S3C44B0X CPU 中,從 0x0c00,0000 到 0x1000,0000 之間的 64M 地址空間被用作系統的 RAM 地址空間。雖然 CPU 通常預留出一大段足夠的地址空間給系統 RAM,但是在搭建具體的嵌入式系統時卻不一定會實現 CPU 預留的全部 RAM 地址空間。也就是說,具體的嵌入式系統往往只把 CPU 預留的全部 RAM 地址空間中的一部分映射到 RAM 單元上,而讓剩下的那部分預留 RAM 地址空間處于未使用狀態。 由于上述這個事實,因此 Boot Loader 的 stage2 必須在它想干點什么 (比如,將存儲在 flash 上的內核映像讀到 RAM 空間中) 之前檢測整個系統的內存映射情況,也即它必須知道 CPU 預留的全部 RAM 地址空間中的哪些被真正映射到 RAM 地址單元,哪些是處于 “unused” 狀態的。

        (1) 內存映射的描述

        可以用如下數據結構來描述 RAM 地址空間中的一段連續(continuous)的地址范圍:

        typedef struct memory_area_struct {u32 start; /* the base address of the memory region */u32 size; /* the byte number of the memory region */int used;} memory_area_t;

        這段 RAM 地址空間中的連續地址范圍可以處于兩種狀態之一:(1)used=1,則說明這段連續的地址范圍已被實現,也即真正地被映射到 RAM 單元上。

        (2)used=0,則說明這段連續的地址范圍并未被系統所實現,而是處于未使用狀態。

        基于上述 memory_area_t 數據結構,整個 CPU 預留的 RAM 地址空間可以用一個 memory_area_t 類型的數組來表示,如下所示:

        memory_area_t memory_map[NUM_MEM_AREAS] = {[0 。。. (NUM_MEM_AREAS - 1)] = {.start = 0,.size = 0,.used = 0},};

        (2) 內存映射的檢測

        下面我們給出一個可用來檢測整個 RAM 地址空間內存映射情況的簡單而有效的算法:

        /* 數組初始化 */for(i = 0; i 《 NUM_MEM_AREAS; i++)memory_map[i].used = 0;/* first write a 0 to all memory locations */for(addr = MEM_START; addr 《 MEM_END; addr += PAGE_SIZE)* (u32 *)addr = 0;for(i = 0, addr = MEM_START; addr 《 MEM_END; addr += PAGE_SIZE) { /* * 檢測從基地址 MEM_START+i*PAGE_SIZE 開始,大小為* PAGE_SIZE 的地址空間是否是有效的RAM地址空間。 */ 調用3.1.2節中的算法test_mempage(); if ( current memory page isnot a valid ram page) {/* no RAM here */if(memory_map[i].used )i++;continue;}

        /* * 當前頁已經是一個被映射到 RAM 的有效地址范圍 * 但是還要看看當前頁是否只是 4GB 地址空間中某個地址頁的別名? */if(* (u32 *)addr != 0) { /* alias? *//* 這個內存頁是 4GB 地址空間中某個地址頁的別名 */if ( memory_map[i].used )i++;continue;}

        /* * 當前頁已經是一個被映射到 RAM 的有效地址范圍 * 而且它也不是 4GB 地址空間中某個地址頁的別名。 */if (memory_map[i].used == 0) {memory_map[i].start = addr;memory_map[i].size = PAGE_SIZE;memory_map[i].used = 1;} else {memory_map[i].size += PAGE_SIZE;}} /* end of for (…) */

        在用上述算法檢測完系統的內存映射情況后,Boot Loader 也可以將內存映射的詳細信息打印到串口。

        加載內核映像和根文件系統映像

        (1) 規劃內存占用的布局

        這里包括兩個方面:(1)內核映像所占用的內存范圍;(2)根文件系統所占用的內存范圍。在規劃內存占用的布局時,主要考慮基地址和映像的大小兩個方面。

        對于內核映像,一般將其拷貝到從(MEM_START+0x8000) 這個基地址開始的大約1MB大小的內存范圍內(嵌入式 Linux 的內核一般都不操過 1MB)。為什么要把從 MEM_START 到 MEM_START+0x8000 這段 32KB 大小的內存空出來呢?這是因為 Linux 內核要在這段內存中放置一些全局數據結構,如:啟動參數和內核頁表等信息。

        而對于根文件系統映像,則一般將其拷貝到 MEM_START+0x0010,0000 開始的地方。如果用 Ramdisk 作為根文件系統映像,則其解壓后的大小一般是1MB。

        (2)從 Flash 上拷貝

        由于像 ARM 這樣的嵌入式 CPU 通常都是在統一的內存地址空間中尋址 Flash 等固態存儲設備的,因此從 Flash 上讀取數據與從 RAM 單元中讀取數據并沒有什么不同。用一個簡單的循環就可以完成從 Flash 設備上拷貝映像的工作:

        while(c++ount) {*dest++ = *src++; /* they are all aligned with word boundary */count -= 4; /* byte number */};

        設置內核的啟動參數

        應該說,在將內核映像和根文件系統映像拷貝到 RAM 空間中后,就可以準備啟動 Linux 內核了。但是在調用內核之前,應該作一步準備工作,即:設置 Linux 內核的啟動參數。

        Linux 2.4.x 以后的內核都期望以標記列表(tagged list)的形式來傳遞啟動參數。啟動參數標記列表以標記 ATAG_CORE 開始,以標記 ATAG_NONE 結束。每個標記由標識被傳遞參數的 tag_header 結構以及隨后的參數值數據結構來組成。數據結構 tag 和 tag_header 定義在 Linux 內核源碼的include/asm/setup.h 頭文件中:

        /* The list ends with an ATAG_NONE node. */#define ATAG_NONE 0x00000000struct tag_header {u32 size; /* 注意,這里size是字數為單位的 */u32 tag;};……struct tag {struct tag_header hdr;union {struct tag_core core;struct tag_mem32 mem;struct tag_videotext videotext;struct tag_ramdisk ramdisk;struct tag_initrd initrd;struct tag_serialnr serialnr;struct tag_revision revision;struct tag_videolfb videolfb;struct tag_cmdline cmdline;/* * Acorn specific */struct tag_acorn acorn;/* * DC21285 specific */struct tag_memclk memclk;} u;};

        在嵌入式 Linux 系統中,通常需要由 Boot Loader 設置的常見啟動參數有:ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。

        比如,設置 ATAG_CORE 的代碼如下:

        params = (struct tag *)BOOT_PARAMS;params-》hdr.tag = ATAG_CORE;params-》hdr.size = tag_size(tag_core);params-》u.core.flags = 0;params-》u.core.pagesize = 0;params-》u.core.rootdev = 0;params = tag_next(params);

        其中,BOOT_PARAMS 表示內核啟動參數在內存中的起始基地址,指針 params 是一個 struct tag 類型的指針。宏 tag_next() 將以指向當前標記的指針為參數,計算緊臨當前標記的下一個標記的起始地址。注意,內核的根文件系統所在的設備ID就是在這里設置的。

        下面是設置內存映射情況的示例代碼:

        for(i = 0; i 《 NUM_MEM_AREAS; i++) {if(memory_map[i].used) {params-》hdr.tag = ATAG_MEM;params-》hdr.size = tag_size(tag_mem32);params-》u.mem.start = memory_map[i].start;params-》u.mem.size = memory_map[i].size;

        params = tag_next(params);}}

        可以看出,在 memory_map[]數組中,每一個有效的內存段都對應一個 ATAG_MEM 參數標記。

        Linux 內核在啟動時可以以命令行參數的形式來接收信息,利用這一點我們可以向內核提供那些內核不能自己檢測的硬件參數信息,或者重載(override)內核自己檢測到的信息。比如,我們用這樣一個命令行參數字符串“console=ttyS0,115200n8”來通知內核以 ttyS0 作為控制臺,且串口采用 “115200bps、無奇偶校驗、8位數據位”這樣的設置。下面是一段設置調用內核命令行參數字符串的示例代碼:

        char *p;/* eat leading white space */for(p = commandline; *p == ‘ ’; p++);/* skip non-existent command lines so the kernel will still * use its default command line. */if(*p == ‘’)return;params-》hdr.tag = ATAG_CMDLINE;params-》hdr.size = (sizeof(struct tag_header) + strlen(p) + 1 + 4) 》》 2;strcpy(params-》u.cmdline.cmdline, p);params = tag_next(params);

        請注意在上述代碼中,設置 tag_header 的大小時,必須包括字符串的終止符‘’,此外還要將字節數向上圓整4個字節,因為 tag_header 結構中的size 成員表示的是字數。

        下面是設置 ATAG_INITRD 的示例代碼,它告訴內核在 RAM 中的什么地方可以找到 initrd 映象(壓縮格式)以及它的大?。?/p>

        params-》hdr.tag = ATAG_INITRD2;params-》hdr.size = tag_size(tag_initrd);

        params-》u.initrd.start = RAMDISK_RAM_BASE;params-》u.initrd.size = INITRD_LEN;

        params = tag_next(params);

        下面是設置 ATAG_RAMDISK 的示例代碼,它告訴內核解壓后的 Ramdisk 有多大(單位是KB):

        params-》hdr.tag = ATAG_RAMDISK;params-》hdr.size = tag_size(tag_ramdisk);

        params-》u.ramdisk.start = 0;params-》u.ramdisk.size = RAMDISK_SIZE; /* 請注意,單位是KB */params-》u.ramdisk.flags = 1; /* automatically load ramdisk */

        params = tag_next(params);

        最后,設置 ATAG_NONE 標記,結束整個啟動參數列表:

        static void setup_end_tag(void){params-》hdr.tag = ATAG_NONE;params-》hdr.size = 0;}

        調用內核

        Boot Loader 調用 Linux 內核的方法是直接跳轉到內核的第一條指令處,也即直接跳轉到 MEM_START+0x8000 地址處。在跳轉時,下列條件要滿足:

        卡片的背景色需要調出布局工具欄來設置1. CPU 寄存器的設置:· R0=0;· R1=機器類型 ID;關于 Machine Type Number,可以參見 linux/arch/arm/tools/mach-types?!?R2=啟動參數標記列表在 RAM 中起始基地址;

        2. CPU 模式:· 必須禁止中斷(IRQs和FIQs);· CPU 必須 SVC 模式;

        3. Cache 和 MMU 的設置:· MMU 必須關閉;· 指令 Cache 可以打開也可以關閉;· 數據 Cache 必須關閉;如果用 C 語言,可以像下列示例代碼這樣來調用內核:每個卡片都可以嵌套插入圖片或其它模板

        void (*theKernel)(int zero, int arch, u32 params_addr) = (void (*)(int, int, u32))KERNEL_RAM_BASE;……theKernel(0, ARCH_NUMBER, (u32) kernel_params_start);

        注意,theKernel()函數調用應該永遠不返回的。如果這個調用返回,則說明出錯。

        關于串口終端

        在 boot loader 程序的設計與實現中,沒有什么能夠比從串口終端正確地收到打印信息能更令人激動了。此外,向串口終端打印信息也是一個非常重要而又有效的調試手段。但是,我們經常會碰到串口終端顯示亂碼或根本沒有顯示的問題。造成這個問題主要有兩種原因:(1) boot loader 對串口的初始化設置不正確。(2) 運行在 host 端的終端仿真程序對串口的設置不正確,這包括:波特率、奇偶校驗、數據位和停止位等方面的設置。

        此外,有時也會碰到這樣的問題,那就是:在 boot loader 的運行過程中我們可以正確地向串口終端輸出信息,但當 boot loader 啟動內核后卻無法看到內核的啟動輸出信息。對這一問題的原因可以從以下幾個方面來考慮:(1) 首先請確認你的內核在編譯時配置了對串口終端的支持,并配置了正確的串口驅動程序。(2) 你的 boot loader 對串口的初始化設置可能會和內核對串口的初始化設置不一致。此外,對于諸如 s3c44b0x 這樣的 CPU,CPU 時鐘頻率的設置也會影響串口,因此如果 boot loader 和內核對其 CPU 時鐘頻率的設置不一致,也會使串口終端無法正確顯示信息。(3) 最后,還要確認 boot loader 所用的內核基地址必須和內核映像在編譯時所用的運行基地址一致,尤其是對于 uClinux 而言。假設你的內核映像在編譯時用的基地址是 0xc0008000,但你的 boot loader 卻將它加載到 0xc0010000 處去執行,那么內核映像當然不能正確地執行了。

        結束語

        Boot Loader 的設計與實現是一個非常復雜的過程。如果不能從串口收到那激動人心的“uncompressing linux.。。.。。.。。.。。.。。.。。 done, booting the kernel……”內核啟動信息,恐怕誰也不能說:“嗨,我的 boot loader 已經成功地轉起來了!”。

        -END-

        原文標題:揭開嵌入式系統BootLoader的神秘面紗

        文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。

        收藏 人收藏
        分享:

        評論

        相關推薦

        嵌入式系統中電源芯片的類型及選擇需要遵循的原則介紹

        電源是嵌入式系統中不可缺少的重要組成部分,電源設計的好壞直接決定了系統設計的成敗。出現電源設計問題的....
        發表于 03-10 10:35 ? 52次 閱讀
        嵌入式系統中電源芯片的類型及選擇需要遵循的原則介紹

        嵌入式μC/OS-II系統中基于ECB基本存儲單元實現信號量管理的設計

        隨著嵌入式技術的發展,實時操作系統RTOS(Real Time Operating System)被....
        發表于 03-10 10:25 ? 54次 閱讀
        嵌入式μC/OS-II系統中基于ECB基本存儲單元實現信號量管理的設計

        CPCI的技術特點及在嵌入式系統的應用和發展解決方案

        以標準的計算機技術為核心的嵌入式系統,由于可以與各種各樣的復雜的設備有機地結合在一起,非常靈活地實現....
        的頭像 牽手一起夢 發表于 03-10 09:59 ? 213次 閱讀
        CPCI的技術特點及在嵌入式系統的應用和發展解決方案

        基于Windows CE和S3C2440A處理器實現網絡收音機系統的設計

        工程利用Visual Studio 2005平臺進行開發,選擇基于對話框結構模式設計,并且要求Win....
        發表于 03-10 09:55 ? 40次 閱讀
        基于Windows CE和S3C2440A處理器實現網絡收音機系統的設計

        采用Linux操作系統和圖形用戶界面庫實現SIP電話終端的設計方案

        隨著VoIP的迅猛發展,越來越多的個人用戶正在使用軟件電話、IP電話通過VoIP系統撥打國內和國際長....
        發表于 03-10 09:45 ? 47次 閱讀
        采用Linux操作系統和圖形用戶界面庫實現SIP電話終端的設計方案

        基于嵌入式低功耗芯片和PC104總線實現鐵路道口報警系統的設計

        鐵路平交道口是鐵路與公路的平面交叉,是鐵路安全運營的重要設施,隨著鐵路的發展,道口密度加大,而隨著鐵....
        發表于 03-10 09:38 ? 50次 閱讀
        基于嵌入式低功耗芯片和PC104總線實現鐵路道口報警系統的設計

        基于多種自動化軟件驗證技術查詢嵌入式C語言應用中的缺陷問題

        這里,我們假設僅在絕對必要的情況下才使用調試器進行調試,因此我們從運行基于模式的靜態代碼分析開始。它....
        發表于 03-10 09:28 ? 38次 閱讀
        基于多種自動化軟件驗證技術查詢嵌入式C語言應用中的缺陷問題

        BioEntry指紋門禁管理系統有什么功能?

        XX公司為了加強訓練管理,達到“對訓練人員具有持續監督與記錄的能力”,同時也徹底解決以往一卡多進,以及臨時卡的使用人身份...
        發表于 03-10 08:27 ? 10次 閱讀
        BioEntry指紋門禁管理系統有什么功能?

        新型電子點菜系統模式有什么特點?

        隨著人民生活水平的提高和生活方式的轉變,餐飲業的市場急劇擴大,利潤飛速增長,被稱為中國的黃金產業。而電子點菜系統的應用,...
        發表于 03-10 08:14 ? 37次 閱讀
        新型電子點菜系統模式有什么特點?

        基于溫控器的熱塑成型機怎么實現?

        吸塑成型設備包括夾持系統,加熱系統,真空和壓縮空氣系統及成型模具等幾部分。塑性塑料片材的吸塑成型過程,主要工序之一就是片...
        發表于 03-10 08:13 ? 15次 閱讀
        基于溫控器的熱塑成型機怎么實現?

        門禁監控系統的組成有哪些?

        門禁,又稱出入管理控制系統,是一種管理人員進出的數字化管理系統。目前,隨著工業自動化的發展和人們對應用需求的不斷提高,門...
        發表于 03-10 08:10 ? 57次 閱讀
        門禁監控系統的組成有哪些?

        微型光學手指導航模組的工作原理是什么?

        微型光學手指導航模組,集感應測量光路、微型機械構造和數字/模擬微電子集成電路于一體,是高度微型化的機電一體化人機輸入模塊,...
        發表于 03-10 07:49 ? 56次 閱讀
        微型光學手指導航模組的工作原理是什么?

        公網通信采集電能信息系統結構是什么?

          1.公網通信采集電能信息系統的技術選擇   本系統技術實現方案中以建筑單元為基礎單位,每個集中的建筑單元安裝數據采集器...
        發表于 03-10 07:14 ? 8次 閱讀
        公網通信采集電能信息系統結構是什么?

        ARM嵌入式微處理器的發展怎么樣?

        隨著網絡技術及現代通信技術的飛速發展,嵌入式系統在相關領域的重要性也備受關注,特別是ARM嵌入式微處理器,其不僅成本低、...
        發表于 03-10 06:35 ? 7次 閱讀
        ARM嵌入式微處理器的發展怎么樣?

        嵌入式智能報警系統有什么優點?

        報警系統作為智能家居的一個重要組成部分, 正在日常生活中起著越來越重要的作用。當今常用的報警系統都是通過單片機控制固定電話...
        發表于 03-10 06:35 ? 51次 閱讀
        嵌入式智能報警系統有什么優點?

        以太網在工業控制中有什么應用?

        在工業生產中,隨著生產規模的擴大和復雜程度的提高,實際應用對控制系統的要求越來越高。在20世紀50~60年代,以模擬信號為主的...
        發表于 03-10 06:11 ? 9次 閱讀
        以太網在工業控制中有什么應用?

        新型可通信智能斷路器控制器基本功能有什么?

          作為輸配電網絡中保護用的電力斷路器(包括框架式斷路器和塑殼式斷路器),在設備過載、短路時,能安全、可靠地切斷故障電流,...
        發表于 03-10 06:08 ? 24次 閱讀
        新型可通信智能斷路器控制器基本功能有什么?

        ARM-Linux開發與MCU開發的差別是什么

        對于ARM-Linux開發,通常是沒有硬件的調試器的,尤其是在應用開發的過程中,很少使用硬件的調試器....
        發表于 03-09 16:43 ? 43次 閱讀
        ARM-Linux開發與MCU開發的差別是什么

        嵌入式技術是如何發展的

        云計算-物聯網-大數據-人工智能,技術革命一浪接著一浪,技術創新一波接著一波。
        發表于 03-09 16:12 ? 99次 閱讀
        嵌入式技術是如何發展的

        嵌入式開發比單片機要難的原因是什么

        嵌入式微處理器有各種不同的體系,即使在同一體系中也可能具有不同的時鐘頻率和數據總線寬度,或集成了不同....
        發表于 03-09 16:08 ? 64次 閱讀
        嵌入式開發比單片機要難的原因是什么

        物聯網連接解決方案值得購買嗎

        嵌入式無線模塊的單價總是比現成的網關低得多。然而,在嵌入無線模塊時,必須考慮設計、開發、認證和生命周....
        發表于 03-09 15:34 ? 87次 閱讀
        物聯網連接解決方案值得購買嗎

        基于S3C2410A芯片和Flash存儲器實現嵌入式工控量熱儀的設計

        如上圖,系統上位機中使用的微處理芯片是三星公司的 arm920T S3C2410A;Flash存儲器....
        發表于 03-09 10:50 ? 60次 閱讀
        基于S3C2410A芯片和Flash存儲器實現嵌入式工控量熱儀的設計

        基于嵌入式C語言開發中的異常堆棧錯誤追蹤機制的設計

        對于嵌入式軟件來說,盡量節省內存資源、降低程序代碼量是十分重要的。因此,將程序中所有錯誤、異常情況都....
        發表于 03-09 10:35 ? 49次 閱讀
        基于嵌入式C語言開發中的異常堆棧錯誤追蹤機制的設計

        EdgeBoard嵌入式AI解決方案中NHWC數據格式的性能分析

        EdgeBoard是百度基于FPGA芯片研發的嵌入式AI解決方案,高性能的加速引擎可提供3.6Top....
        發表于 03-09 10:25 ? 57次 閱讀
        EdgeBoard嵌入式AI解決方案中NHWC數據格式的性能分析

        采用MiniGUI雙緩沖技術和AT91SAM9263實現數字加密電話系統的設計

        在需要豐富人機交互信息的嵌入式系統應用中,高精度的動態圖像顯示非常重要。因此,嵌入式系統對GUI的實....
        發表于 03-09 09:58 ? 51次 閱讀
        采用MiniGUI雙緩沖技術和AT91SAM9263實現數字加密電話系統的設計

        基于S3C2440A處理器和3G模塊實現視頻采集程序的設計

        隨著網絡技術和嵌入式技術的迅猛發展,通過網絡來實現視頻監控已經得到了廣泛的應用,3G網絡以其高帶寬使....
        發表于 03-09 09:28 ? 38次 閱讀
        基于S3C2440A處理器和3G模塊實現視頻采集程序的設計

        QQ3208919269 揭秘嵌入式C語言main函數的寫法原因

        但凡是學過C語言的人,都知道要先寫main函數,然而很多時候我們看到的main函數卻各有差異,這究竟....
        的頭像 如何學習嵌入式 發表于 03-08 14:11 ? 83次 閱讀
        QQ3208919269 揭秘嵌入式C語言main函數的寫法原因

        嵌入式驅動開發 主要分為以下四個大方向

        一、嵌入式硬件開發:熟悉電路等知識,非常熟悉各種常用元器件,掌握模擬電路和數字電路設計的開發能力。熟....
        發表于 03-08 09:24 ? 133次 閱讀
        嵌入式驅動開發 主要分為以下四個大方向

        在Vx-Works平臺實現交叉編譯工具鏈的開發及優化研究

        交叉編譯技術,就是一種在一個異構平臺上編譯出目標平臺程序的技術。比如在PC平臺(X86 CPU)上編....
        發表于 03-07 10:55 ? 64次 閱讀
        在Vx-Works平臺實現交叉編譯工具鏈的開發及優化研究

        利用LPC2148的SD卡實現系統升級的模塊設計

        隨著信息化,智能化,網絡化的發展,嵌入式系統技術也將獲得廣闊的發展空間。嵌入式技術全面展開,目前已成....
        發表于 03-07 10:38 ? 73次 閱讀
        利用LPC2148的SD卡實現系統升級的模塊設計

        采用μC/OS-II系統和LPC2131微處理器實現自適應均衡器的設計

        無線通信中,信號在非理想信道傳輸時總是存在失真,具體表現為碼間干擾。為降低干擾,通常在接收端采用自適....
        發表于 03-07 10:04 ? 50次 閱讀
        采用μC/OS-II系統和LPC2131微處理器實現自適應均衡器的設計

        基于μC/OS-II操作系統在SPCE061A上的移植優化研研究

        SPCE061A是凌陽科技新推出的u課SP內核的十六位單片機,內嵌32K字 Flash的SPCE06....
        發表于 03-07 09:57 ? 74次 閱讀
        基于μC/OS-II操作系統在SPCE061A上的移植優化研研究

        嵌入式和物聯網兩者有什么聯系

        物聯網時代,物聯網實現了人人互聯,物物互聯,還有就是人物互聯,它是一種建立在互聯網上的泛在網絡。
        發表于 03-06 10:48 ? 147次 閱讀
        嵌入式和物聯網兩者有什么聯系

        利用MDO4000系列混合域示波器在嵌入式系統的測試射頻與總線信號

        基本上今天的每一個電子產品都是一個嵌入系統,小到電子表,大到各種復雜的控制系統。嵌入式系統實際上是專....
        發表于 03-06 10:46 ? 60次 閱讀
        利用MDO4000系列混合域示波器在嵌入式系統的測試射頻與總線信號

        嵌入式和人工智能之間有怎樣的聯系

        長期以來,形形色色的人工智能應用就在我們周圍,可以說嵌入式開啟了人工智能的進程,人工智能的終極目的是....
        發表于 03-06 10:45 ? 149次 閱讀
        嵌入式和人工智能之間有怎樣的聯系

        基于LEACH協議的數據融合策略及實驗仿真研究

        無線傳感器網絡綜合了無線通信技術、傳感器技術、嵌入式系統、分布式計算等多種前沿技術,網絡內各節點能夠....
        發表于 03-06 10:26 ? 47次 閱讀
        基于LEACH協議的數據融合策略及實驗仿真研究

        嵌入式系統開發經常使用哪一些數據庫

        數據庫是一種儲存和管理、組織數據的倉庫,在嵌入式開發當中起到至關重要的作用。
        發表于 03-06 10:12 ? 66次 閱讀
        嵌入式系統開發經常使用哪一些數據庫

        嵌入式多媒體應用軟件的框架建模和并行技術的研究

        對于大多數多媒體應用,可以將數據存取模式看成是2D(空間域)和3D(時間域)操作模式。在2D模式中,....
        發表于 03-06 10:03 ? 74次 閱讀
        嵌入式多媒體應用軟件的框架建模和并行技術的研究

        基于M16C62單片機實現實時多任務系統的設計方案

        隨著微電子技術和網絡的發展,人們對網絡的認識日益深入。網絡終端產品也越來越受到人們的關注,嵌入式操作....
        發表于 03-06 09:47 ? 76次 閱讀
        基于M16C62單片機實現實時多任務系統的設計方案

        基于S3C2440處理器和Windows CE實現電能計量帶電核查儀系統的設計

        電能計量帶電核查儀系統是根據對高供高計設備現場檢測的需求設計的,主要由電能計量帶電核查儀和電腦后臺支....
        發表于 03-06 09:32 ? 117次 閱讀
        基于S3C2440處理器和Windows CE實現電能計量帶電核查儀系統的設計

        通過嵌入式軟件實現路徑覆蓋測試的設計方案研究

        路徑覆蓋測試是覆蓋測試中的關鍵測試技術之一,目前已應用于程序覆蓋率分析、測試用例設計、程序調試、性能....
        發表于 03-05 10:55 ? 109次 閱讀
        通過嵌入式軟件實現路徑覆蓋測試的設計方案研究

        通過嵌入式Linux和S3C2440處理器實現無線監控報警系統的設計

        隨著計算機網絡技術、移動通信技術、多媒體技術的快速發展,無線監控系統以其便捷、實用、安裝方便等優點被....
        發表于 03-05 10:40 ? 105次 閱讀
        通過嵌入式Linux和S3C2440處理器實現無線監控報警系統的設計

        連續變倍視頻顯微鏡的工作原理及基于嵌入式的設計方案

        在20世紀70年代起出現了國產的連續變倍體視顯微鏡,由于明顯優于間隔變倍類型的體視顯微鏡,從此在體視....
        發表于 03-05 10:14 ? 114次 閱讀
        連續變倍視頻顯微鏡的工作原理及基于嵌入式的設計方案

        基于Web服務器和S3C2410處理器實現溫室茶樹培養監測系統的設計

        對于溫室茶樹的培養,需要保持其相對優異的生長環境。本文通過嵌入式Web服務器將被控設備接入Inter....
        發表于 03-05 10:04 ? 96次 閱讀
        基于Web服務器和S3C2410處理器實現溫室茶樹培養監測系統的設計

        基于S3C2440在Linux上實現視頻監控系統的FFmpeg編解碼設計

        隨著視頻編解碼技術、計算機網絡技術、數字信號處理技術和嵌入式系統的發展,以嵌入式網絡視頻服務器為核心....
        發表于 03-05 09:51 ? 65次 閱讀
        基于S3C2440在Linux上實現視頻監控系統的FFmpeg編解碼設計

        在Linux系統中如何進行CGI的程序設計,有什么方法

        隨著互聯網應用的普及,越來越多的信息化產品需要接入互聯網通過Web頁面進行遠程訪問。嵌入式Web系統....
        發表于 03-05 09:38 ? 85次 閱讀
        在Linux系統中如何進行CGI的程序設計,有什么方法

        基于LED大屏幕控制電路設計方案研究

        作為LED大屏幕顯示系統的核心,控制電路的設計對于大屏幕的穩定性與擴展性發揮了重要的影響。本文介紹了....
        發表于 03-05 08:00 ? 89次 閱讀
        基于LED大屏幕控制電路設計方案研究

        嵌入式系統在物聯網時代有著更大的發展空間

        隨著國家信息化的推進,電子技術也得到了更廣泛的發揮,嵌入式作為一種傳統的電子技術,未來會因為物聯網的....
        發表于 03-04 11:15 ? 142次 閱讀
        嵌入式系統在物聯網時代有著更大的發展空間

        為什么心臟起搏器容易受到攻擊

        大多數嵌入式醫療設備目前沒有內存、處理能力或電池壽命來支持適當的密碼安全、加密或訪問控制。
        發表于 03-03 11:00 ? 49次 閱讀
        為什么心臟起搏器容易受到攻擊

        使用STR730開發產品實現串口ISP在線編程的設計方案

        ISP方案的硬件連接如圖1所示。RS232轉接板用來將RS232電平轉換為TTL電平,并通過ISP_....
        發表于 03-03 09:34 ? 102次 閱讀
        使用STR730開發產品實現串口ISP在線編程的設計方案

        物聯網嵌入式應用帶來了怎樣的價值

        嵌入式系統根據英國電機工程師協會的定義,其為控制、監視或輔助設備、機器或甚至工廠運作的裝置。
        發表于 03-02 15:26 ? 73次 閱讀
        物聯網嵌入式應用帶來了怎樣的價值

        嵌入式硬件還是軟件比較好

        嵌入式硬件工程師那在工作中,是指能夠根據項目管理和工程技術的實際要求,按照系統總體設計規格進行軟、硬....
        發表于 03-02 10:51 ? 146次 閱讀
        嵌入式硬件還是軟件比較好

        你覺得嵌入式入門容易嗎

        首先需要學習LINUX內核基礎部分,包括內核配置編譯,內核模塊,并發控制,字符設備,設備模型,平臺設....
        發表于 03-02 10:42 ? 109次 閱讀
        你覺得嵌入式入門容易嗎

        物聯網是如何改變嵌入式設計思維

        有別于一般泛用型的PC架構,嵌入式系統的定義,是為特定用途所設計的IT系統,近年來嵌入式在特定領域的....
        發表于 02-29 16:57 ? 88次 閱讀
        物聯網是如何改變嵌入式設計思維

        怎樣在惡劣的環境開發物聯網

        物聯網涵蓋行業眾多,包括嵌入式技術和云系統的大規??缙脚_部署。
        發表于 02-29 16:39 ? 78次 閱讀
        怎樣在惡劣的環境開發物聯網

        基于人機界面和PLC實現環境設備控制系統的設計

        由于測控模塊不需要過多的應用程序與圖形界面,因此選擇了相對Linux嵌入式操作系統機構要小巧的多的u....
        發表于 02-29 10:17 ? 152次 閱讀
        基于人機界面和PLC實現環境設備控制系統的設計

        嵌入式電子秤的程序合集免費下載

        1) 通過資源擴展板電位器 RP5 模擬稱重傳感器輸出信號, STM32 采集 此電壓信號,并計算貨....
        發表于 02-29 08:00 ? 51次 閱讀
        嵌入式電子秤的程序合集免費下載

        藍寶石為AMD APU推出兩款嵌入式主板,適用于NUC類小主機

          根據消息報道,藍寶石為AMD之前發布的Zen架構嵌入式APU推出了主板,體型小巧,只有4英寸見方....
        的頭像 牽手一起夢 發表于 02-27 14:52 ? 524次 閱讀
        藍寶石為AMD APU推出兩款嵌入式主板,適用于NUC類小主機

        Simplynuc即將推出OAK NUC,采用雙網口設計

        Simplynuc已經宣布在其EverGreen型號NUC上搭載AMD G系列嵌入式處理器了,因此這....
        的頭像 牽手一起夢 發表于 02-26 14:44 ? 450次 閱讀
        Simplynuc即將推出OAK NUC,采用雙網口設計

        AMD新款嵌入式APU支持4K分辨率顯示

        新款嵌入式APU分別是R1102G和R1305G,前者為2核2線程,Vega 3核顯,6W TDP;....
        的頭像 汽車玩家 發表于 02-26 14:29 ? 430次 閱讀
        AMD新款嵌入式APU支持4K分辨率顯示
        成·人免费午夜视频

          1. <code id="p04wk"><small id="p04wk"><track id="p04wk"></track></small></code>

            <th id="p04wk"></th>
            <tr id="p04wk"><sup id="p04wk"></sup></tr>
              <strike id="p04wk"></strike>
              <tr id="p04wk"></tr>
              <center id="p04wk"></center>