1. 程式人生 > >[kernel 啟動流程] (第二章)第一階段之——設定SVC、關閉中斷

[kernel 啟動流程] (第二章)第一階段之——設定SVC、關閉中斷

本文是基於arm平臺。例子都是以tiny210(s5pv210 armv7)為基礎的。
[kernel 啟動流程]系列

建議參考文件

================================================

零、說明

本文是《[kernel 啟動流程] (第一章)概述》的延伸,
閱讀本文前建議先閱讀《[kernel 啟動流程] (第一章)概述》

1、kernel啟動流程第一階段簡單說明

arch/arm/kernel/head.S

  • kernel入口地址對應stext
ENTRY(stext)
  • 第一階段要做的事情,也就是stext的實現內容

    • 設定為SVC模式,關閉所有中斷
    • 獲取CPU ID,提取相應的proc info
    • 驗證tags或者dtb
    • 建立頁表項
    • 配置r13暫存器,也就是設定開啟MMU之後要跳轉到的函式。
    • 使能MMU
    • 跳轉到start_kernel,也就是跳轉到第二階段

本文要介紹的是“設定為SVC模式,關閉所有中斷”的部分。分成兩部分說明,設定為SVC模式,關閉所有中斷。

2、疑問

主要帶著以下幾個問題去理解

  • 設定SVC模式
    • 什麼是SVC模式?
    • 為什麼要設定成SVC模式?
    • 如何設定成SVC模式
  • 關閉所有中斷
    • 為什麼要關閉所有中斷?
    • 如何關閉所有中斷?
      對應程式碼
ENTRY(stext)
    @ ensure svc mode and all interrupts masked
    safe_svcmode_maskall r9

safe_svcmode_maskall實現程式碼如下:
arch/arm/include/asm/assembler.h

.macro safe_svcmode_maskall reg:req
#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
    mrs \reg , cpsr
    eor \reg, \reg, #HYP_MODE
    tst \reg, #MODE_MASK
    bic \reg , \reg , #MODE_MASK
    orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE
THUMB( orr \reg , \reg , #PSR_T_BIT ) bne 1f orr \reg, \reg, #PSR_A_BIT badr lr, 2f msr spsr_cxsf, \reg __MSR_ELR_HYP(14) __ERET 1: msr cpsr_c, \reg 2:

這部分程式碼也就是後面要講述的“設定為SVC模式,關閉所有中斷”的核心

一、設定為SVC模式

1、ARM7體系的幾種工作模式(什麼是SVC模式?)

ARM7體系的cpu有如下七種工作模式。具體參考《ARMV7官方資料手冊 B1.3.1 ARM processor modes》。
* 使用者模式(USR)
普通模式
正常程式工作模式,此模式下程式不能夠訪問一些受作業系統保護的系統資源,應用程式也不能直接進行處理器模式的切換。
* 系統模式(SYS)
特權模式
作業系統特權任務模式,用於支援作業系統的特權任務等,可以訪問系統保護的系統資源,也可以直接切換到其它模式等特權。
* 管理模式(SVC)
特權模式、異常模式
作業系統保護模式
* 快中斷模式(FIQ)
特權模式、異常模式
支援高速資料傳輸及通道處理,FIQ異常響應時進入此模式。
* 中斷模式(IRQ)
特權模式、異常模式
用於通用中斷處理,IRQ異常響應時進入此模式。
* 中止模式(ABT)
特權模式、異常模式
用於支援虛擬記憶體和/或儲存器保護。
* 未定義模式(UND)
特權模式、異常模式
支援硬體協處理器的軟體模擬,未定義指令異常響應時進入此模式。

2、為什麼要設定成SVC模式?

除了使用者模式之外的其他6種處理器模式稱為特權模式。
特權模式下,程式可以訪問所有的系統資源(除了特定模式下的影子暫存器),也可以任意地進行處理器模式的切換。
特權模式中,除系統模式外,其他5種模式又稱為異常模式。
* 使用者模式下訪問的資源受限,故不能使用使用者模式
* 系統模式的優先順序低於異常模式,故不使用系統模式
* 快中斷模式、中斷模式、中止模式、未定義模式用於特殊場景下由CPU自動切入,故不使用
所以需要使用SVC模式。(這裡是個人見解,如果說法不對還請幫忙指出。)

3、如何設定成SVC模式?

(1)CPSR & SPSR
ARM工作模式的切換由CPSR暫存器控制。
CPSR表示當前程式狀態暫存器,SPSR表示備份的程式狀態暫存器。
CPSR:程式狀態暫存器(current program status register) (當前程式狀態暫存器),在任何處理器模式下被訪問。它包含了條件標誌位、中斷禁止位、當前處理器模式標誌以及其他的一些控制和狀態位。如下所示(具體參考文件《ARMV7官方資料手冊》“Format of the CPSR and SPSRs”一節,這裡只列出一些目前我們可能會用到的):
* 條件標誌位(這裡可以暫時不關心)

對應位 對應標識 功能說明
31bit N flag 用兩個補碼錶示的帶符號的運算結果標識,為1表示負數,為0表示非負數
30bit Z flag 為1表示運算結果為0,為0表示運算結果為非0
29bit C flag 加法運算結果進位標誌位
28bit V flag 加減法運算指令符號位溢位標誌位

* 控制位

對應位 對應標識 功能說明
7bit flag 為1表示禁止IRQ中斷。
6bit F flag 為1表示禁止FIQ中斷。
5bit T flag 為1表示程式運行於Thumb狀態,否則處於ARM狀態。
[4:0] 模式控制位 用於配置CPU當前的工作模式。

(2)工作模式編碼
七種工作模式對應在CPSR中的工作模式編碼如下:

工作模式 工作模式編碼
USR 10000
FIQ 10001
IRQ 10010
SVC 10011
ABT 10111
UND 11011
SYS 11111

綜上,需要將CPSR的[4:0]設定成10011就可以切換到SVC模式

二、關閉所有中斷

1、為什麼要關閉所有中斷?

在啟動過程中,中斷環境並沒有完全準備好,也就是中斷向量表和中斷處理函式並沒有完成設定,一旦有中斷產生,可能會導致預想不到的問題,或者是程式跑飛。因此,在準備好中斷環境之前,需要關閉所有中斷。

2、如何關閉所有中斷?

中斷的關閉同樣由CPSR暫存器來進行控制,具體請看上一一節

對應位 對應標識 功能說明
7bit flag 為1表示禁止IRQ中斷。
6bit F flag 為1表示禁止FIQ中斷。

綜上,需要將CPSR的bit6和bit7設定為1

三、程式碼分析

設定為SVC模式和關閉所有中斷都是在safe_svcmode_maskall中完成。

ENTRY(stext)
    @ ensure svc mode and all interrupts masked
    safe_svcmode_maskall r9

safe_svcmode_maskall實現和分析如下:
注意,涉及到Hyper態,但是我沒找到關於這個模式的資料,《ARMV7官方資料手冊 》也沒有說明這個模式。
所以這裡關於Hyper mode的程式碼暫時略過,有興趣的可以參考http://blog.csdn.net/crosskernel/article/details/21091819
arch/arm/include/asm/assembler.h

.macro safe_svcmode_maskall reg:req
#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
    mrs \reg , cpsr                                  
    eor \reg, \reg, #HYP_MODE
    tst \reg, #MODE_MASK
    bic \reg , \reg , #MODE_MASK                                         
    orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE  
THUMB(  orr \reg , \reg , #PSR_T_BIT    )
    bne 1f
    orr \reg, \reg, #PSR_A_BIT
    badr    lr, 2f
    msr spsr_cxsf, \reg                    
    __MSR_ELR_HYP(14)
    __ERET
1:  msr cpsr_c, \reg
2:

其中主要的關閉中斷設定SVC的核心程式碼如下:

    mrs \reg , cpsr                                          @獲取CPSR暫存器的值到臨時暫存器中
    bic \reg , \reg , #MODE_MASK                                                @清除模式位[4:0]位
    orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE        @設定BIT6\BIT7,關閉中斷,設定[4:0]為SVC_MODE
1:  msr cpsr_c, \reg                @儲存到CPSR的低八位中,CPSR_C表示CRSR暫存器的低8位,也就是控制域遮蔽位元組。

其中
arch/arm/include/uapi/asm/ptrace.h中

#define SVC_MODE    0x00000013
#define PSR_F_BIT   0x00000040
#define PSR_I_BIT   0x00000080

到這裡就實現了工作模式的切換和中斷的關閉。

相關推薦

[kernel 啟動流程] 第二第一階段——設定SVC關閉中斷

本文是基於arm平臺。例子都是以tiny210(s5pv210 armv7)為基礎的。 [kernel 啟動流程]系列: 建議參考文件: ================================================ 零、說

[kernel 啟動流程] 第五第一階段——臨時核心頁表的建立

本文是基於arm平臺。例子都是以tiny210(s5pv210 armv7)為基礎的。 [kernel 啟動流程]系列: 建議參考文件: ================================================ 零、說明

我的python中級班學習全程筆記第一模組 第二第2部分

第二章                       資料型別    字元編碼    檔案操作 第二部分 第三節 :資料型別—字串講解 一

我的python中級班學習全程筆記第一模塊 第二第2部分

一個 文件操作 模塊 生成 字符串 講解 mar style 定義 第二章 數據類型 字符編碼 文件操作 第二部分 第三節 :數據類型—字符串講解 一、定義: 字符串是一個有序的字符的字符

我的python中級班學習全程筆記第一模組 第二第3部分

第二章                       資料型別    字元編碼    檔案操作 第三部分  第六節 :資料型別—元祖型別

redis設計與實現第二 第一 引言

1.前言 本書的版本基於redis 3.0 個人主要是鞏固redis基礎知識,同時探索redis的分散式使用 2.本書主要內容 (1)資料結構與物件 (2)單機資料庫的實現 (3)多機資料庫的實現 (4)獨立功能的實現 3.資料結構與物件 redis

嵌入式linux基礎教程第二第一

       linux已經成為很多裝置的作業系統,手機、DVD播放器、電子遊戲機、數碼相機、網路交換機和無線網路裝置、機頂盒、高清電視、藍光DVD播放器、汽車的資訊娛樂中心和很多日常使用的電器等都在使用linux作業系統。linux已經成為很多裝置的嵌入式作業系統 一.為

資料結構演算法與應用C++語言描述第二 第一部分練習參考答案

1、 void swap(int& x,int& y) {//交換x,y int temp=x; x=y; y=temp; } 2、 template<class T,unsigned N> size_t count(const T (

隨便玩玩PostgreSQL第二單表數據查詢

兩種 fse 排序。 可能 結束 三個班 image sel div 隨便玩玩之PostgreSQL(第二章)單表數據查詢 未經授權不得轉載 第二章 單表數據查詢數據庫的基本功能就是數據增查改刪,倘若不可以,要她還有什麽意義。數據查詢功能不僅僅是查詢,而且還能篩選,並且格式

CSAPP家庭作業第二

inter image 要求 temp tar type gpo color def 2.55(*) #include <stdio.h> typedef unsigned char *byte_pointer; void show_bytes(byte_

java-web學習筆記第二

直接 () destroy 垃圾回收 垃圾回收器 troy 鏈接 ems cse 第二章:Servlet基礎 1,創建Servlet有幾種方式?處理http請求最好使用哪種方式?  1>直接實現Servlet接口和它的所有方法;&emsp

git服務器的搭建及使用第二

etc log 指定 作者 取消 不起作用 -a 關聯 pat 一、git服務器創建倉庫   在普通用戶有讀寫權限的目錄下,創建git倉庫,切勿使用root創建(root創建的倉庫,普通用戶無寫的權限,導致提交失敗)。   mkdir xxx.git   git init

Python學習第二

img 開始 png 變量命名 spa cccccc otto pad 基本 一、 變量 1. type(變量名) 可以查看該變量的類型 2. 關於字符串的兩個運算符 + 與 * ,分別執行 拼接 和 重復 操作 3. 格式化輸出 %s 字符串 %d 整型 (%0

阿裏雲彈性計算服務ECS基本概念第二

之間 啟動 分享圖片 操作系統 png 使用 col 拷貝 內存 第二章:彈性計算服務ECS基本概念四、ECS產品概念ECS,是由多個並列,又相互關聯的產品概念組成,包括在介紹產品概念之前,先需要理解兩個重要的邏輯位置概念Region,地域,是阿裏雲提供雲計算服務的城市位置

網絡操作系統課後習題第二

第二章 本地用戶 系統 系統默認 tor 列表 包含 roo 操作系統 1.Windows Server 2008 中的用戶有哪些類型?系統默認的用戶有哪些? 用戶類型: (1)用戶; (2)InetOrgPerson; (3)聯系人; (4)默認用戶賬戶。 默認用戶: (

《SQL入門經典》筆記第二:建立資料庫資料型別

“建立資料庫”包括五個內容:定義資料結構、管理資料庫物件、規格化過程、操作資料以及管理資料庫事務   1. 什麼是資料型別? 資料型別用於指定特定列所包含資料的規則,它決定了資料儲存在列裡的方式。SQL最基本的資料型別有字串、數值、日期和時間(其實每個實現都有自己的資料型別

Linux核心設計與實現 總結筆記第二

一、Linux核心中的一些基本概念 核心空間:核心可獨立於普通應用程式,它一般處於系統態,擁有受保護的記憶體空間和訪問硬體裝置的所有許可權。這種系統態和被保護起來的記憶體空間,稱為核心空間。 程序上下文:當應用程式執行一條系統呼叫,通過系統呼叫執行在核心空間,而核心被稱為執行在程序上下文中。  

Effective Objective-C 2.0 總結與筆記第二—— 物件訊息執行期

第二章:物件、訊息、執行期 ​ “物件”就是“基本構造單元”,開發者可以通過物件來儲存並傳遞資料。物件之間傳遞資料並執行任務的過程就是“訊息傳遞”。程式執行起來後,為其提供相關支援的程式碼就是“Objective-C執行期環境”,它提供了一些使得物件之間能夠傳遞訊息的重要函式,並且包括建

spider資料抓取第二

download最完善的指令碼 import urllib2 import urlparse def download(url, user_agent="wswp", proxy=None, num_retries=2): print "DownLoading", url head

Beginng_rust:在終端上列印第二

在終端上列印 在本章中,您將學習: 如何在Rust語言中編寫和執行您的第一個程式 如何在終端上輸出文字和數字 如何編寫一個小指令碼,使編譯器的輸出更具可讀性 如何在程式碼中編寫註釋 如何開始 最短且有效Rust程式是: fn main(){} 當然,它什麼