天天看點

【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例

  • 一. 處理器工作模式相關介紹
    • 1. 處理器模式簡介
      • (1) 處理器工作模式分類
      • (2) 處理器不同工作模式差別
      • (3) Linux 系統運作的模式
      • (4) 特權模式 說明
      • (5) 異常模式
      • (6) 系統模式
    • 2. 處理器模式 改變
      • (1) 處理器工作模式 改變 的前提條件
      • (2) 處理器工作模式 修改方式 ( 程式狀态字寄存器 工作模式修改 )
      • (3) 程式狀态字寄存器 位 類型
      • (4) 程式狀态字寄存器修改流程
  • 二. 處理器工作模式修改 代碼示例
    • 1. 彙編代碼編寫
      • (1) 代碼 邏輯 分析
      • (2) 彙編代碼示例
    • 2. 連結器腳本
    • 3. Makefile 編譯腳本
    • 4. 編譯輸出可執行檔案

本部落格的參考文章及相關資料下載下傳 :

  • 1.ARM 架構參考手冊 ( ARM Architecture Reference Manual ) : https://download.csdn.net/download/han1202012/8324641
  • 2.彙編參考手冊 : https://download.csdn.net/download/han1202012/8328375
  • 3.本部落格代碼下載下傳 : https://download.csdn.net/download/han1202012/10400369

一. 處理器工作模式相關介紹

參考手冊 : A2.2 Processor modes

  • 1.處理器工作模式位置 : ARM Architecture Reference Manual [ A 2.2 ] 章節;
  • 2.參考手冊下載下傳位址 : https://download.csdn.net/download/han1202012/8324641

1. 處理器模式簡介

(1) 處理器工作模式分類

處理器的 七種 工作模式 :

  • 1.User ( 使用者模式 usr ) : 普通的應用運作的模式 ;
  • 2.FIQ ( 快速中斷模式 fiq ) : 該模式下支援資料的高速傳輸 ;
  • 3.IRQ ( 普通中斷模式 irq ) : 該模式常用于處理普通的中斷 ;
  • 4.Supervisor ( 管理模式 svc ) : 作業系統使用的一種保護模式 , 本節 BootLoader 就是需要設定這種 svc 模式;
  • 5.Abort ( 終止模式 abt ) : 實作虛拟記憶體 和 存儲器保護 ;
  • 6.Undefined ( 未定義模式 und ) : 硬體協處理器 的 軟體仿真支援, 當執行的指令處理器不支援, 那麼會進入該模式;
  • 7.System ( 系統模式 ) : 該模式用于運作具有特權的作業系統任務, ARMv4 以上的架構才有;

(2) 處理器不同工作模式差別

處理器 工作模式 差別 :

  • 1.可運作的指令不同 : 不同的處理器工作模式下 可 運作的 處理器指令 是不同的;
  • 2.可通路的寄存器不同 : 不同處理器模式下 可通路的 寄存器 也是有差別的;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 3.分級别處理 : 7 種工作模式級别不同, 作業系統 一般在級别較高的模式下運作, 應用程式在級别較低的模式下運作;
  • 4.使用者模式說明 :
    • ( 1 ) 應用運作 : 絕大多數 應用程式都運作在使用者模式 ( User ) 下;
    • ( 2 ) 資源限制 : 在 ① 使用者模式下, 應用無法通路受保護的系統資源 , ② 系統資源的使用 是在作業系統的控制下;
    • ( 3 ) 無法修改模式 : 在 使用者模式 下, 應用也無法修改 處理器 的工作模式 ;

(3) Linux 系統運作的模式

Linux 作業系統運作模式 :

  • 1.應用程式 : Linux 系統的應用程式運作在 User 使用者模式下;
  • 2.核心 : Linux 系統 核心 運作在 Supervisor 管理模式下 ;

(4) 特權模式 說明

特權模式 :

  • 1.特權概念 : 除 使用者模式 外, 其它的 6 種模式 都是特權模式 ;
  • 2.特權模式 的 功能 : 特權模式 比 使用者模式 擁有更大的權限, 可 ① 通路系統資源, ② 修改處理器工作模式 ;
    • ( 1 ) 資源通路 : 特權模式 擁有通路系統資源的權限 ;
    • ( 2 ) 模式修改 : 特權模式 下 可以 修改 處理器的工作模式 ;
  • 3.五種異常模式 : 在 6 種 特權模式中, 有 5 種 是 異常模式 , 當對應的異常發生的時候, 就會進入對應的工作模式 ;
  • 4.異常模式寄存器 : 每種異常模式都有一些附加的寄存器, 當異常發生的時候, 避免影響使用者模式的狀态;

(5) 異常模式

五種 處理器工作模式 ( 異常模式 ) 對應的異常類型 :

  • 1.FIQ ( 快速中斷模式 fiq ) : 該模式下支援資料的高速傳輸 , 對應異常類型 為 快速中斷 異常;
  • 2.IRQ ( 普通中斷模式 irq ) : 該模式常用于處理普通的中斷 , 對應異常類型 為 普通中斷 異常 ;
  • 3.Supervisor ( 管理模式 svc ) : 作業系統使用的一種保護模式 , 本節 BootLoader 就是需要設定這種 svc 模式, 對應異常類型 為 Reset 和 軟中斷 異常 ;
  • 4.Abort ( 終止模式 abt ) : 實作虛拟記憶體 和 存儲器保護 , 對應異常類型 為 預取指令失敗 和 讀取資料失敗 異常 ;
  • 5.Undefined ( 未定義模式 und ) : 硬體協處理器 的 軟體仿真支援, 當執行的指令處理器不支援, 那麼會進入該模式, 對應異常類型 為 無法識别指令 異常;
【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例

七種 異常類型 對應的 處理器工作模式 : ARM 架構 支援 七種類型的異常,

  • 1.Reset : 處理器在工作時, 突然 按下重新開機鍵, 就會觸發該異常 , 該異常對應的處理器工作模式為 svc 模式;
  • 2.Undefined instructions : 處理器無法識别指令的異常, 處理器執行的指令是有規範的, 如果 嘗試執行 不符合要求的指令, 就會進入到該異常指令對應的位址中, 該異常對應的處理器工作模式為 und 模式;
  • 3.Software interrupt (SWI) : 軟中斷, 軟體中需要去打斷處理器工作, 可以使用軟中斷來執行 , 該異常對應的處理器工作模式為 svc 模式;
  • 4.Prefetch Abort (instruction fetch memory abort) : 預取指令失敗, ARM 在執行指令的過程中, 要先去預取指令準備執行, 如果預取指令失敗, 就會産生該異常, 該異常對應的處理器工作模式為 abt 模式;
  • 5.Data Abort (data access memory abort) : 讀取資料失敗, 該異常對應的處理器工作模式為 abt 模式;
  • 6.IRQ (interrupt) : 普通中斷 , 該異常對應的處理器工作模式為 irq 模式;
  • 7.FIQ (fast interrupt) : 快速中斷, 快速中斷要比普通中斷響應速度要快一些, 該異常對應的處理器工作模式為 fiq 模式;

(6) 系統模式

系統模式 :

  • 1.進入方式 : 任何異常都無法進入 系統 模式 ;
  • 2.寄存器 : 從下面的寄存器截圖可以看出, 系統模式 可 使用的 寄存器, 與 使用者模式 可通路的寄存器 是一樣的;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 3.擁有特權 : 系統模式也是一種特權模式, 不受使用者模式限制影響,
  • 4.模式存在的目的 : 系統模式 主要 服務于 需要通路系統資源的 作業系統任務, 避免使用 與 異常相關的附加寄存器;
    • ( 1 ) 避免被異常幹擾 : 主要是為了 保證 任務狀态, 避免 被 發生的異常 幹擾 ;

2. 處理器模式 改變

(1) 處理器工作模式 改變 的前提條件

修改 處理器 工作模式 的 前提條件 :

  • 1.軟體控制 : 在 軟體控制下, 可以修改處理器的工作模式 ;
  • 2.外部中斷 : 外部中斷也會改變處理器的工作模式;
  • 3.異常處理 : 當異常發生的時候, 也會修改處理器的工作模式 ;
  • 4.BootLoader 工作模式 : BootLoader 工作在 svc 模式 下, 該模式比較進階, 可以 通路較多的寄存器資源 , 執行更多的處理器指令 ;
  • 5.如何修改工作模式 : 修改 程式狀态 寄存器 ( CPSR ) 中的 0 ~ 4 位 即可改變處理器工作模式;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 6.修改CPSR值 : 修改的 程式狀态寄存器 0 ~ 4 位的值 為, 下面表中的 模式代碼. 即 每行 第三列的 二進制碼 ;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 7.處理器工作模式 對應的 M 位 ( CPRS 0 : 4 ) 值 以及其對應的 可使用的寄存器 :
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例

(2) 處理器工作模式 修改方式 ( 程式狀态字寄存器 工作模式修改 )

參考手冊 : A2.5 Program status registers

  • 1.處理器工作模式位置 : ARM Architecture Reference Manual [ A 2.5 ] 章節;
  • 2.參考手冊下載下傳位址 : https://download.csdn.net/download/han1202012/8324641

程式狀态字寄存器 :

  • 1.寄存器内容 : 該寄存器 中 包含 ① 狀态碼标志位, ② 中斷标志位, ③ 目前處理器工作模式 和 其它一些 ④ 狀态 與 ⑤ 控制資訊 ;
  • 2.CPSR 寄存器 : 全稱 Current Program Status Register ( 目前程式狀态字寄存器 ), 儲存的是目前的程式狀态 ;
  • 3.SPSR 寄存器 : 全稱 Saved Program Status Register ( 程式狀态儲存寄存器 ), 每個異常都有對應的獨立的 SPSR 寄存器, 當異常發生的時候, 先将 CPSR 寄存器中的值 儲存到 SPSR 寄存器中, 以便 異常處理完畢後 再回到原來斷點處 繼續運作 ;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 4.SPSR 寄存器分布 : 使用者模式 和 系統模式 沒有 對應的 SPSR 寄存器, 隻有 5 種 異常模式才有對應的 SPSR 寄存器 ;
    • ( 1 ) SPSR 寄存器讀寫 : 在 使用者模式 或 系統模式 讀寫 SPSR 指令 會出現不可預測的錯誤或行為 ;

(3) 程式狀态字寄存器 位 類型

參考手冊 : A2.5 Program status registers

  • 1.處理器工作模式位置 : ARM Architecture Reference Manual [ A 2.5 ] 章節;
  • 2.參考手冊下載下傳位址 : https://download.csdn.net/download/han1202012/8324641

程式狀态字寄存器 位 類型簡介 :

【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 1.特權位 : 在 特權模式 下可進行修改 的 位數, 使用者模式下不能修改特權位, 如 A, I , F, 和 M ( 0 :4 ) 位;
  • 2.使用者可寫位 : 任何模式都可以修改的 資料位, 如 N, Z, C, V, Q, GE[ 3 : 0 ], E 資料位;
  • 3.執行狀态位 : 可以從 任何特權模式修改, 使用者模式不能修改 ; J 和 T 兩位 是運作狀态位, 在 ARM 狀态下總是 0 ;
    • ( 1 ) CPSR 運作狀态位 : 使用 MSR 特權指令 将通用寄存器的值 儲存到 CPSR 中, J 和 T 兩位必須設定為 0 , 否則會出現不可預知錯誤;
    • ( 2 ) SPSR 運作狀态位 : 在 上面 的 限制中, 隻針對 CPSR 寄存器, SPSR 沒有這個限制,
  • 4.保留位 : 為之後的功能擴充保留的位數 ;
    • ( 1 ) 讀取 : 保留位 讀取時 都當做 0 值;
    • ( 2 ) 寫入 : 不能向 保留位 寫出實際資料 ;

(4) 程式狀态字寄存器修改流程

參考手冊 : arm彙編手冊(中文版).chm

  • 1.本節使用的彙編指令 : BIC, ORR, MSR, MRS;
  • 2.arm彙編手冊下載下傳位址 : https://download.csdn.net/download/han1202012/8328375

修改程式狀态字寄存器 使用到的彙編指令 :

  • 1.将處理器工作模式位 設定 0 : 将 CPRS 程式狀态字 寄存器 中的 0 ~ 4 位 設定為 0 , 注意 CPRS 不能直接操作 ; 使用 BIC 指令進行設定;
    • ( 1 ) BIC 彙編指令 文法 : bic 文法格式

      bic <dest>, <op1>, <op2>

      , dest 存放位清除結果, op1 是被清除的對象, op2 是掩碼;
    • ( 2 ) BIC 指令 示例 :

      bic r0, r0, #0b1011

      , 清除 r0 中的 第0, 1, 3 位, 其餘位保持不變, 結果放入 r0 中;
    • ( 3 ) 使用注意點 : dest op1 都不能使用立即數, 必須使用寄存器, op2 可以使用立即數;
    • ( 4 ) 立即數進制 : 此處的的立即數必須使用二進制形式 ;
  • 2.為 處理器工作模式位 設定 1 : 将 CPRS 程式狀态字 寄存器 中的 0 ~ 4 位 設定為 指定的二進制數字 , 注意 CPRS 不能直接操作 ; 使用 orr 指令 進行設定 ;
    • ( 1 ) ORR 彙編指令 文法 :

      ORR{條件}{S} <dest>, <op 1>, <op 2>

      , dest 結果是 op 1 與 op 2 進行或運算的結果;
    • ( 2 ) ORR 指令 說明 : dest 必須是寄存器, 操作數 1 ( op 1 ) 必須是寄存器, 操作數 2 ( op 2 ) 可以是 ① 寄存器 ② 被移位寄存器 ③ 立即數;
    • ( 3 ) ORR 示例 :

      ORR R0, R0, #3

      , 将 立即數 3 與 R0 寄存器中的值 進行 或 運算, 然後将運算結果存放到 R0 中;
  • 3.程式狀态字寄存器 ( CPSR 和 SPSR ) 通路指令 : 使用 MRS MSR 指令, 程式狀态字 不能使用 通用寄存器的語句 如 MOV 等通路, 必須使用 程式狀态寄存器的 專用指令 讀寫;
    • ( 1 ) 程式狀态字寄存器 通路 流程 : 程式狀态字寄存器不能直接通路, 需要先将程式狀态字寄存器内容導出到通用寄存器中, 才能進行操作 , 不能直接修改 CPSR 和 SPSR 中的值 ;
    • ( 2 ) MRS 指令 :

      MRS R0, CPSR

      , 将 CPRS 寄存器的值 複制 到 R0 寄存器中;
    • ( 3 ) MSR 指令 :

      MSR CPSR, R0

      , 将 R0 寄存器中的值 設定 到 CPSR 寄存器中 ;
  • 4.流程總結 :
    • ( 1 ) 導出 CPSR 寄存器值 : 使用 MRS 将 CPSR 寄存器的值導出到通用寄存器中 ;
    • ( 2 ) 将工作模式位置 0 : 将導出的 CPSR 寄存器的值的 0 ~ 4 位 設定為 0 ;
    • ( 3 ) 将工作模式位置 1 : 将導出的 CPSR 寄存器的值的 0 ~ 4 位 設定 對應 的 模式代碼 ;
    • ( 4 ) 将設定好的 CPSR 寄存器值設定到 寄存器中 : 使用 MSR 指令, 将 在通用寄存器中 設定好的 CPSR 寄存器值 設定回 CPSR 寄存器中 ;

二. 處理器工作模式修改 代碼示例

1. 彙編代碼編寫

(1) 代碼 邏輯 分析

代碼 邏輯 分析 :

  • 1.設定 處理器工作模式 時機 : 進行 處理器工作模式 設定 是在 開發闆上電後, 對應的 reset 異常向量處;
  • 2.設定 指令标号 : 設定一個指令标号, 在标号下定義一組彙編指令, 當需要執行這一組指令的時候, 在跳轉到該标号即可;
    • ( 1 ) 定義标号 :

      set_svc :

      , 在标号下定義一組彙編指令;
  • 3.導出 CPSR 寄存器值 : 使用 MRS 指令, 即

    mrs r0 cpsr

    将 CPSR 寄存器中的值導出到 R0 寄存器中;
  • 4.将 R0 中的 M 位 清 0 : 在 R0 中将從 CPSR 中導出的寄存器值 對應的 0 ~ 4 位 清0, 使用

    bic r0, r0, #0x1f

    , 将 R0 寄存器的值 與 #0x1f 進行 與操作, 即 後5 位都設定成0, 然後将 與 操作的結果儲存到 R0 寄存器中 ;
  • 5.将 R0 中的 M 位 設定 模式代碼 : 在下圖中, svc 的模式代碼時 0b10011 ( 二進制 ), 即 0x13 ( 十六進制 ), 使用

    orr r0, r0, #0xd3

    語句設定, 将 R0 寄存器中的值 與 0x13 進行 或操作, 将 或操作的結果 存放到 R0 寄存器中;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例
  • 6.将值寫回 CPSR 寄存器 : 使用 MSR 指令

    msr cpsr, r0

    , 将處理完的 CPSR 寄存器值 設定給 CPSR 寄存器;

(2) 彙編代碼示例

彙編代碼示例 :

@****************************  
@File:start.S  
@  
@BootLoader 初始化代碼 
@****************************  

.text                                   @ 宏 指明代碼段  
.global _start                          @ 僞指令聲明全局開始符号  
_start:                                 @ 程式入口标志  
        b   reset                       @ reset 複位異常  
        ldr pc, _undefined_instruction  @ 未定義異常, 将 _undefined_instruction 值裝載到 pc 指針中  
        ldr pc, _software_interrupt     @ 軟中斷異常  
        ldr pc, _prefetch_abort         @ 預取指令異常  
        ldr pc, _data_abort             @ 資料讀取異常  
        ldr pc, _not_used               @ 占用  位址                            
        ldr pc, _irq                    @ 普通中斷異常  
        ldr pc, _fiq                    @ 軟中斷異常  

_undefined_instruction: .word undefined_instruction @ _undefined_instruction 标号存放了一個值, 該值是  位位址 undefined_instruction, undefined_instruction 是一個位址  
_software_interrupt:    .word software_interrupt    @ 軟中斷異常  
_prefetch_abort:    .word prefetch_abort            @ 預取指令異常 處理  
_data_abort:        .word data_abort                @ 資料讀取異常  
_not_used:      .word not_used                      @ 空位處理  
_irq:           .word irq                           @ 普通中斷處理  
_fiq:           .word fiq                           @ 快速中斷處理  

undefined_instruction:                              @ undefined_instruction 位址存放要執行的内容  
        nop  

software_interrupt:                                 @ software_interrupt 位址存放要執行的内容  
        nop  

prefetch_abort:                                     @ prefetch_abort 位址存放要執行的内容  
        nop  

data_abort:                                         @ data_abort 位址存放要執行的内容  
        nop  

not_used:                                           @ not_used 位址存放要執行的内容  
        nop  

irq:                                                @ irq 位址存放要執行的内容  
        nop  

fiq:                                                @ fiq 位址存放要執行的内容  
        nop  

reset:                                              @ reset 位址存放要執行的内容  
        bl set_svc                                  @ 跳轉到 set_svc 标号處執行

set_svc:
        mrs r0, cpsr                                @ 将 CPSR 寄存器中的值 導出到 R0 寄存器中
        bic r0, r0, #0x1f                           @ 将 R0 寄存器中的值 與 #0x1f 立即數 進行與操作, 并将結果儲存到 R0 寄存器中, 實際是将寄存器的 0 ~ 4 位 置 0
        orr r0, r0, #0xd3                           @ 将 R0 寄存器中的值 與 #0xd3 立即數 進行或操作, 并将結果儲存到 R0 寄存器中, 實際是設定 0 ~ 4 位 寄存器值 的處理器工作模式代碼
        msr cpsr, r0                                @ 将 R0 寄存器中的值 儲存到 CPSR 寄存器中
           

2. 連結器腳本

gboot.lds 連結器腳本 代碼解析 :

  • 1.指明輸出格式 ( 處理器架構 ) : 使用

    OUTPUT_ARCH(架構名稱)

    指明輸出格式, 即處理器的架構, 這裡是 arm 架構的,

    OUTPUT_ARCH(arm)

    ;
  • 2.指明輸出程式的入口 : 設定編譯輸出的程式入口位置, 文法為

    ENTRY(入口位置)

    , 在上面的 Start.S 中設定的程式入口是

    _start

    , 代碼為

    ENTRY(_start)

    ;
  • 3.設定代碼段 : 使用

    .text :

    設定代碼段;
  • 4.設定資料段 : 使用

    .data :

    設定資料段;
  • 5.設定 BSS 段 : 使用

    .bss :

    設定 BSS 段;
    • ( 1 ) 記錄 BSS 段的起始位址 :

      bss_start = .;

      ;
    • ( 2 ) 記錄 BSS 段的結束位址 :

      bss_end = .;

      ;
  • 6.對齊 : 每個段都需要設定記憶體的對齊格式, 使用

    . = ALIGN(4);

    設定四位元組對齊即可;
  • 7.代碼示例 :
OUTPUT_ARCH(arm)        /*指明處理器結構*/  
ENTRY(_start)           /*指明程式入口 在 _start 标号處*/  
SECTIONS {                
    . = ;     /*整個程式連結的起始位置, 根據開發闆确定, 不同開發闆位址不一緻*/  

    . = ALIGN();       /*對齊處理, 每段開始之前進行 4 位元組對齊*/  
    .text :             /*代碼段*/  
    {  
    start.o (.text)     /*start.S 轉化來的代碼段*/  
    *(.text)            /*其它代碼段*/  
    }  

    . = ALIGN();       /*對齊處理, 每段開始之前進行 4 位元組對齊*/  
    .data :             /*資料段*/  
    {  
    *(.data)  
    }  

    . = ALIGN();       /*對齊處理, 每段開始之前進行 4 位元組對齊*/  
    bss_start = .;      /*記錄 bss 段起始位置*/  
    .bss :              /*bss 段*/  
    {  
    *(.bss)   
    }  
    bss_end = .;        /*記錄 bss 段結束位置*/  
} 
           

3. Makefile 編譯腳本

makefile 檔案編寫 :

  • 1.通用規則 ( 彙編檔案編譯規則 ) : 彙編檔案 編譯 成同名的 .o 檔案, 檔案名稱相同, 字尾不同,

    %.o : %.S

    , 産生過程是

    arm-linux-gcc -g -c $^

    , 其中

    ^

    辨別是所有的依賴檔案, 在該規則下 start.S 會被變異成 start.o ;
  • 2.通用規則 ( C 檔案編譯規則 ) : C 代碼編譯成同名的 .o 檔案,

    %.o : %.c

    , 産生過程是

    arm-linux-gcc -g -c $^

    ;
  • 3.設定最終目标 : 使用

    all:

    設定最終編譯目标;
    • ( 1 ) 依賴檔案 : 産生最終目标需要依賴 start.o 檔案, 使用

      all: start.o

      表示最終目标需要依賴該檔案;
    • ( 2 ) 連結過程 :

      arm-linux-ld -Tgboot.lds -o gboot.elf $^

      , 需要使用連結器腳本進行連接配接, ①連結工具是 arm-linux-ld 工具, ②使用

      -Tgboot.lds

      設定連結器腳本 是剛寫的 gboot.lds 連結器腳本, ③輸出檔案是 gboot.elf 這是個中間檔案, ④ 依賴檔案是

      $^

      代表所有的依賴;
    • ( 3 ) 轉換成可執行二進制檔案 :

      arm-linux-objcopy -O binary gboot.elf gboot.bin

      , 使用

      -O binary

      設定輸出二進制檔案, 依賴檔案是

      gboot.elf

      , 輸出的可執行二進制檔案 即 結果是

      gboot.bin

      ;
  • 4.makefile 檔案内容 :
all: start.o #依賴于 start.o  
    arm-linux-ld -Tgboot.lds -o gboot.elf $^    #使用連結器腳本, 将 start.o 轉為 gboot.elf  
    arm-linux-objcopy -O binary gboot.elf gboot.bin #将 gboot.elf 轉化為可以直接在闆子上執行的 gboot.bin 檔案  

%.o : %.S   #通用規則, 如 start.o 是由 start.S 編譯來的, -c 是隻編譯不連結  
    arm-linux-gcc -g -c $^  

%.o : %.c   #通用規則, 如 start.o 是由 start.c 編譯來的, -c 是隻編譯不連結  
    arm-linux-gcc -g -c $^  

.PHONY: clean     
clean:              #清除編譯資訊  
    rm *.o *.elf *.bin  
           

4. 編譯輸出可執行檔案

編譯過程 :

  • 1.檔案準備 : 将 彙編代碼 ( start.S ) 連結器腳本 ( gboot.lds ) makefile 檔案 拷貝到編譯目錄 ;
  • 2.執行編譯指令 :

    make

    ;
  • 3.編譯結果 : 可以看到 生成了 編譯目标檔案 start.o, 連結檔案 gboot.elf, 可執行的二進制檔案 gboot.bin ;
    【嵌入式開發】ARM 處理器工作模式 及 修改方法 ( 處理器模式 | 設定處理器模式 | 程式狀态字寄存器 CPSR SPSR | 模式設定代碼編寫 | 設定 svc 模式 )一. 處理器工作模式相關介紹二. 處理器工作模式修改 代碼示例

本部落格的參考文章及相關資料下載下傳 :

  • 1.ARM 架構參考手冊 ( ARM Architecture Reference Manual ) : https://download.csdn.net/download/han1202012/8324641
  • 2.彙編參考手冊 : https://download.csdn.net/download/han1202012/8328375
  • 3.本部落格代碼下載下傳 : https://download.csdn.net/download/han1202012/10400369

繼續閱讀