cpu匯流排介面圖
首先,程式以機器碼的形式,即二進位製碼的形式存在flash中;
上電後,cpu通過控制器將待執行的程式從flash中讀入記憶體中;
**在記憶體中執行時,控制器將需要計算的資料存入暫存器中;
運算器從暫存器中讀取資料進行運算,並將結果存入暫存器中;
控制器將暫存器中的結果讀入記憶體中;
由此,形成乙個閉環的程式執行過程。
系統開始執行的時候,程式首先躺在flash裡面,分為3個段,**段、資料段,bss段,控制器讀取到cpu內部通用暫存器,cpu的機制會在記憶體中給他們各自分配好記憶體空間。
比如**段在上電後**的執行過程:
第一步,cpu對內部的boot rom進行直接讀取並解析指令後初始化部分ddr,指令會自動在記憶體上分配**段;
第二步,cpu上的flash控制器將flash上的**拷貝到記憶體的**段,然後cpu讀取並執行解析**,此時cpu的運算器會工作,在ddr的堆和棧中不斷的訪問資料,再根據解析下一行或下幾行的**的要求,訪問指定位址的空間,去存放資料。因為要處理資料,放入記憶體中執行時,會有在ddr中多出2部分(堆和棧)用來處理資料。
boot rom:boot rom是cpu當中的一段啟動**。因為ddr和flash其實也是外設,他們也需要一段**去初始化他們的暫存器,使他們能被使用,所以一般會有一段啟動**在cpu,cpu上電就會執行裡面的**,這是硬體設計好的。
嵌入式裝置上電後,cpu開始執行,通常cpu會從某乙個固定的實體地址開始執行,這個實體地址一般是flash晶元的起始實體地址。flash晶元的最初一段通常存放的是bootloader,於是cpu就會開始執行bootloader的**。
那cpu是如何讀取flash上的資料的呢?
我們知道cpu可以讀寫flash上的資料,但是不能直接執行flash上的指令,cpu通常只能執行記憶體中的指令,那麼cpu剛開始執行時怎樣去執行flash上的指令呢?這裡分兩種情況,flash晶元主要分為兩種,一種是nor flash,另一種是nand flash,nor flash具有可以直接在flash晶元上執行指令的特點。如果嵌入式裝置採用的是nor flash,那就比較簡單了,cpu可以直接執行在nor flash上的指令。如果採用的是nand flash呢,怎麼辦?目前主要有兩種方法,一種方法是flash控制器能夠把nand flash的前4k資料搬到4k的內部ram中,並設定cpu從這個內部ram的起始位址開始啟動執行。另一種方法是flash控制器能夠把nand flash的前4k資料的位址對映到系統匯流排的某個位址上,並設定cpu從這個位址開始啟動執行。這兩種方法都是硬體來完成的。
bootloader分為兩個部分,第一部分是彙編**且不做壓縮,第二部分是c**且有壓縮的。bootloader開始執行時,第一部分彙編**先負責初始化cpu、pll、ddr、cache等硬體,讓cpu和記憶體能夠穩定執行,然後解壓第二部分的image,並拷貝到到記憶體執行。第二部分c**完成串列埠、flash、網口等驅動的載入,並構建乙個shell環境來接受使用者輸入。注意,在整個bootloader執行其間cpu的mmu是沒有被初始化的,所有的位址訪問都是採用實體地址直接訪問的。
在完成bootloader初始化後,根據**中設定的核心區實體地址,bootloader會把核心區壓縮後的linux映象拷貝到記憶體中並解壓。同時準備好核心的啟動引數,如:console=ttys0,115200 root=31:2 mtdparts=ar7100-nor0:196608(boot),835236(kernel),-(rootfs),這裡主要是把bootloader裡設定的mtd分割槽資訊傳遞給核心,還有需要載入的根檔案系統。最後跳轉到核心入口開始執行。
linux核心**開始執行,會先進行核心各個子系統初始化,並完成對mmu的初始化。mmu是cpu中的乙個單元,它跟作業系統一起配合完成從虛擬位址到實體地址的轉換。如果cpu帶有mmu單元,則cpu執行單元發出的記憶體位址將被mmu截獲,從cpu到mmu的位址稱為虛擬位址,而mmu將這個位址翻譯成另乙個位址發到cpu晶元的外部位址引腳上,這個位址稱為實體地址。在這個過程中linux核心會維護頁表結構,它儲存著核心和程序的虛擬位址到實體地址的對映,而mmu則通過linux核心頁表去完成位址翻譯和保護工作。
接下來linux核心會掛載根檔案系統,要掛載的根檔案系統是通過核心啟動引數來獲取的。這裡有乙個問題,根檔案系統通常表示為乙個linux檔案系統下的某個mtd裝置,但在載入根檔案系統前linux還沒有乙個檔案系統,那它怎樣通過訪問檔案系統中的mtd裝置來載入根檔案系統呢?事實上,根檔案系統的安裝分為兩個階段,首先linux核心會安裝乙個特殊的rootfs檔案系統,該檔案系統僅提供乙個作為初始安裝點的空目錄,然後linux核心再在空目錄上安裝乙個真正的根目錄。linux核心對flash的訪問都是通過mtd子系統來進行的,它抽象了對於各種flash裝置的訪問,提供統一的介面。
linux核心繼續初始化各種型別的驅動程式,完成之後會啟動第乙個應用程式,它的程序id為1。這個應用程式可以由核心啟動引數傳入,如果沒有則會預設執行/sbin/init。init程序會讀取配置檔案/etc/inittab,根據配置檔案的內容它會完成兩個工作,執行rcs和啟動shell。至此,linux系統已經啟動完成,給使用者提供了乙個shell的互動環境,後續的行為就取決於使用者的輸入或者系統特定應用的載入。
嵌入式系統中引導程式的實現 上電到main
在嵌入式系統的開發過程中,技術難點主要在於系統引導程式的編寫,為此本文將詳細論述在arm7基礎上開發嵌入式系統時引導程式的實現。引導引導程式是系統加電後執行的第一段軟體 當乙個微處理器最初啟動時,他首先執行預定位址處的指令。通常這個位置是唯讀記憶體,其中存放著系統初始化或引導程式。在pc系統中,引導...
QT嵌入式程式,成功執行
2 環境搭建參考 部落格裡環境變數設定方法不錯 3 建立arm示例程式test.cpp 注test程式要用.cpp格式 4 按照另一篇部落格,建立虛擬機器與開發板的ftp連線,將編譯好的test程式考到開發板裡 5 直接執行的話會報error while loading shared librari...
嵌入式Linux系統的移植(上)
一 核心原始碼的準備和交叉編譯環境的建立 開發環境搭建 vmware workstation軟體來做虛擬機器,vmware workstation 軟 件 可 以 在 wmeare 官 網 下 載 下 載 地 址 當前最新版 本是 vmware workstation pro 15。nfs linu...