日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

映像文件启动-(映像文件启动盘重装系统)

發(fā)布時間:2024/4/30 windows 42 电脑专家
生活随笔 收集整理的這篇文章主要介紹了 映像文件启动-(映像文件启动盘重装系统) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
映像文件啟動 (映像文件啟動盤重裝系統(tǒng))

本文啟動文件位STM32G030的啟動文件(.s為結尾的文件),其他型號單片機大同小異,可以直接參考。

我們先來看下啟動文件的,開頭說明

;******************************************************************************;* File Name : startup_stm32g030xx.s;* Author : MCD Application Team;* Description : STM32G030xx devices vector table for MDK-ARM toolchain.;* This module performs:;* - Set the initial SP;* - Set the initial PC == Reset_Handler;* - Set the vector table entries with the exceptions ISR address;* - Branches to __main in the C library (which eventually;* calls main()).;* After Reset the CortexM0 processor is in Thread mode,;* priority is Privileged, and the Stack is set to Main.;* <<< Use Configuration Wizard in Context Menu >>>;****************************************************************************** ;* @attention;*;* Copyright (c) 2019 STMicroelectronics. All rights reserved.;*;* This software component is licensed by ST under Apache License, Version 2.0,;* the "License"; You may not use this file except in compliance with the;* License. You may obtain a copy of the License at:;* opensource.org/licenses/Apache-2.0;*;******************************************************************************; Amount of memory (in bytes) allocated for Stack; Tailor this value to your application needs; <h> Stack Configuration; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>; </h>1、說明

說明里除了版權的聲明外主要說明了啟動文件的主要功能:

1) 設置堆棧指針SP = __initial_sp。

2) 設置PC指針 = Reset_Handler。

3) 設置中斷向量表。

4) 配置系統(tǒng)時鐘。

5) 配置外部SRAM/SDRAM用于程序變量等數(shù)據(jù)存儲(這是可選的)。

6) 跳轉到C庫中的 __main ,最終會調用用戶程序的main()函數(shù)。

Cortex-M內(nèi)核處理器復位或者上電后,處于線程模式,指令權限為最高級別的特權級別,堆棧設置為使用主堆棧MSP。

2、啟動流程

單片機在復位或者重新上電之后,CPU首先將0X08000000位置存放的堆棧棧頂?shù)刂反娣诺絊P中(MSP),當然這個的前提是我們的程序存儲到了flash里。之后將0X08000004位置存放的向量地址放入PC程序計數(shù)器中。

這時候CPU從PC寄存器指向的地址取出指令并執(zhí)行,這個執(zhí)行的程序是復位中斷的服務程序 Reset_Handler。

復位中斷服務程序中調用了SystemInit()函數(shù),這個函數(shù)的作用是配置系統(tǒng)時鐘、配置FMC總線上的外部SRAM/SDRAM。調用完SystemInit()函數(shù)之后,跳轉到了C庫中的__main 函數(shù)。這個時候任務就交給了C庫中的__main函數(shù),__main函數(shù)對用戶的程序進行初始化操作,然后__main函數(shù)會調用我們自己寫的main函數(shù)執(zhí)行程序。

3、程序分析

Stack_SizeEQU 0x400 AREA STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem SPACE Stack_Size__initial_sp

1)這里EQU是個偽指令,和我們C中的#define比較像,編譯器編譯不會生成二進制代碼。0X400表示棧的大小。

2)AREA STACK, NOINIT, READWRITE, ALIGN=3 這句話表示,下面開始定義一個代碼段或者數(shù)據(jù)段。此處是定義數(shù)據(jù)段。AREA 后面的關鍵字表示這個段的屬性。

STACK :這個是代表這個數(shù)據(jù)段的名字,當然我們可以取任意名字。

NOINIT:表示此數(shù)據(jù)段不需要填入初始數(shù)據(jù)。

READWRITE:表示此段可讀可寫。

ALIGN=3 :表示首地址按照 2 的 3 次方對齊,即按照 8 字節(jié)對齊(地址對8求余數(shù)等于0)。

4)SPACE 這行指令告訴編譯器給 STACK (前面命名的名稱)段分配 0x00000400 字節(jié)的連續(xù)內(nèi)存空間。

5) __initial_s表示了棧頂?shù)刂贰_initial_sp 只是一個標號,標號主要用于表示一片內(nèi)存空間的某個位置,等價于 C 語言中的“地址”概念。地址僅僅表示存儲空間的一個位置,從 C 語言的角度來看,變量的地址,數(shù)組的地址或是函數(shù)的入口地址在本質上并無區(qū)別。

Heap_Size EQU 0x200 AREA HEAP, NOINIT, READWRITE, ALIGN=3__heap_baseHeap_Mem SPACE Heap_Size__heap_limit

6)這部分代碼實現(xiàn)開辟堆(heap)空間,主要用于動態(tài)內(nèi)存分配,也就是說用 malloc,calloc, realloc等函數(shù)分配的變量空間是在堆上。這里和上面的類似,首先分配一片連續(xù)的內(nèi)存空間這里的名字叫 HEAP,即分配堆的空間,大小是0X200。__heap_base 表示堆的開始地址。__heap_limit 表示堆的結束地址(只是標號)。

PRESERVE8 THUMB; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size

7)PRESERVE8 指定當前文件保持堆棧八字節(jié)對齊。

8)THUMB表示后面的指令是THUMB指令集 ,我們的內(nèi)核使用的THUMB指令集。

9)AREA定義一塊代碼段,只讀,段名字是 RESET。

10)EXPORT語句將 3 個標號申明為可被外部引用, 主要提供給鏈接器用于連接庫文件或其他文件。

__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler 此處省略若干代碼 DCD 0 ; Reserved DCD RTC_TAMP_IRQHandler ; RTC through EXTI Line DCD FLASH_IRQHandler ; FLASH DCD RCC_IRQHandler ; RCC DCD EXTI0_1_IRQHandler ; EXTI Line 0 and 1 DCD EXTI2_3_IRQHandler ; EXTI Line 2 and 3 DCD EXTI4_15_IRQHandler ; EXTI Line 4 to 15 此處省略若干代碼 DCD I2C1_IRQHandler ; I2C1 DCD I2C2_IRQHandler ; I2C2 DCD SPI1_IRQHandler ; SPI1 DCD SPI2_IRQHandler ; SPI2 DCD USART1_IRQHandler ; USART1 此處省略若干代碼

11)我們可以看到這里就是我們的中斷向量表了,DCD 表示分配 1 個 4 字節(jié)的空間。每行 DCD 都會生成一個 4 字節(jié)的二進制代碼。中斷向量表存放的實際上是中斷服務程序的入口地址。當異常(也即是中斷事件)發(fā)生時,CPU 的中斷系統(tǒng)會將相應的入口地址賦值給 PC 程序計數(shù)器,之后就開始執(zhí)行中斷服務程序。這里地址定義到了代碼斷的最前面。具體的物理地址由鏈接器的配置參數(shù)(IROM1 的地址)決定。我們的程序在 Flash 運行,中斷向量表的起始地址是 0x08000000。

__Vectors_Size EQU __Vectors_End - __Vectors AREA |.text|, CODE, READONLY; Reset handler routineReset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP

12)AREA 定義一塊代碼段,只讀,段名字是 .text 。READONLY 表示只讀。

13)利用 PROC、ENDP 這一對偽指令把程序段分為若干個過程,使程序的結構加清晰。

14)WEAK 聲明其他的同名標號優(yōu)先于該標號被引用,就是說如果外面聲明了的話會調用外面的。 這個聲明很重要,它讓我們可以在C文件中任意地方放置中斷服務程序,只要保證C函數(shù)的名字和向量表中的名字一致即可。

15)IMPORT:偽指令用于通知編譯器要使用的標號在其他的源文件中定義。但要在當前源文件中引用,而且無論當前源文件是否引用該標號,該標號均會被加入到當前源文件的符號表中。

16)SystemInit 函數(shù),主要實現(xiàn)RCC相關寄存器復位和中斷向量表位置設置。

17)__main 標號表示C/C++標準實時庫函數(shù)里的一個初始化子程序__main 的入口地址。該程序的一個主要作用是初始化堆棧(跳轉__user_initial_stackheap 標號進行初始化堆棧的,下面會講到這個標號),并初始化映像文件,最后跳轉到 C 程序中的 main函數(shù)。這就解釋了為何所有的 C 程序必須有一個 main 函數(shù)作為程序的起點。因為這是由 C/C++標準實時庫所規(guī),并且不能更改。

NMI_Handler PROC EXPORT NMI_Handler [WEAK] 省略若干 EXPORT TIM14_IRQHandler [WEAK] EXPORT TIM16_IRQHandler [WEAK] EXPORT TIM17_IRQHandler [WEAK] EXPORT I2C1_IRQHandler [WEAK] EXPORT I2C2_IRQHandler [WEAK] EXPORT SPI1_IRQHandler [WEAK] EXPORT SPI2_IRQHandler [WEAK] EXPORT USART1_IRQHandler [WEAK] EXPORT USART2_IRQHandler [WEAK]

18)死循環(huán),用戶可以在此實現(xiàn)自己的中斷服務程序。不過很少在這里實現(xiàn)中斷服務程序,一般多是在其它的C文件里面重新寫一個同樣名字的中斷服務程序,因為這里是WEEK弱定義的。如果沒有在其它文件中寫中斷服務器程序,且使能了此中斷,進入到這里后,會讓程序卡在這個地方。

IF :DEF:__MICROLIB EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap__user_initial_stackheap LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR ALIGN ENDIF END

19)簡單的匯編語言實現(xiàn)IF…….ELSE…………語句。如果定義了MICROLIB,那么程序是不會執(zhí)行ELSE分支的代碼。__MICROLIB在MDK的Target Option里面設置。__user_initial_stackheap由__main函數(shù)進行調用。

?

總結

以上是生活随笔為你收集整理的映像文件启动-(映像文件启动盘重装系统)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。