ARM的分散加載文件(scatter)介紹

2020-12-15 電子產品世界
keil中編譯的程序通過了,但是debug的時候會出現一些錯誤:

* error 65: access violation at 0x4C000018 : no write permission

本文引用地址:

http://www.eepw.com.cn/article/201611/317888.htm

* error 65: access violation at 0x00000000 : no execute/read permission (ram.sct的時候)

我發現當我工程設置中linker中選擇了runinram.sct和runinflash.sct或者自動生成的sct文件的時候就出現上面的錯誤。應該就是地址的問題。但是具體怎麼修改才能解決這個錯誤,還沒弄明白。弄明白了再發。

下面是找了一篇值得參考的文章:

原文地址:

http://hi.baidu.com/pengjj0807/blog/item/ef73e287a212453cc65cc3be.html

KEIL下分散加載文件的使用

*
; * Scatter-Loading Description File generated by uVision *
; *

LR_IROM1 0x08000000 0x00004000 ; load region size_region第一個加載域,起始地址0x08000000,{大小0x00004000

ER_IROM1 0x08000000 0x00004000 ; load address = execution address第一個運行時域

{起始0x08000000,大小0x00004000

*.o (RESET, +First)IAP第一階段還是在FLASH中運行
*(InRoot$$Sections)
startup_stm32f10x_md.o
}
ER_IROM2 0x20008000 0x00004000 ; load address = execution address第二個運行時域,

{起始0x20008000,大小0x00004000

.ANY (+RO)IAP第二階段加載到SDRAM中運行
}
RW_IRAM1 0x20000000 0x00008000 ; RW data把可讀寫的數據和初始化為0的數據放在內存SDRAM的開頭

{

.ANY (+RW +ZI)
}
}

讓MDK自己分配--選linker-usexxx

對於分散加載的概念,在《ARM體系結構與編程》書中第11章有明確介紹。

分散加載文件(即scatter file 後綴為.scf)是一個文本文件,通過編寫一個分散加載文件來指定
ARM連接器在生成映像文件時如何分配RO,RW,ZI等數據的存放地址。如果不用SCATTER文件指定,那麼
ARM連接器會按照默認的方式來生成映像文件,一般情況下我們是不需要使用分散加載文件的。

但在某些場合,我們希望把某些數據放在指定的地址處,那麼這時候SCATTER文件就發揮了非常大的作用
而且SCATTER文件用起來非常簡單好用。

舉個例子:比如像LPC2378晶片具有多個不連續的SRAM,通用的RAM是32KB,可是32KB不夠用,我想把
某個.C中的RW數據放在USB的SRAM中,那麼就可以通過SCATTER文件來完成這個功能。
下面是就這個例子作的說明:


這是一個標準的常用的分散加載文件,現在加注釋於後,方便以後查閱:
;
;
; SCATTER LOADING DEION
; ARM
; KEILs uVision3
; (RealView Microprocessor Developer Kit)
;
; Filename : LPC2378_Flash.scat
;

LR_IROM1 0x00000000 0x00080000 ;; 第一個加載域,名字為LR_IROM1,起始
{                  ;;地址為0x0,大小為0x80000
ER_IROM1 0x00000000 0x00080000 ;;加載域中的運行時域,名字為ER_IROM1
{ ;; 起始地址為0x0,大小為0x80000
vectors.o (VECT, +First) ;;將vectors.c編譯後生成的文件vectors.o中的代碼
init.o (INIT) ;;以及init.o中的代碼
* (+RO) ;;以及所有編譯生成的RO屬性的代碼全部存放在
} ;;運行時域ER_IROM1指定的地址範圍內,存放方式:順序存放

RW_IRAM1 0x40000000 0x0000e800  ;;這是第二個運行時域,功能同上
{ ;;其中 *是代表具有()裡面指定的屬性的全部數據
*(+RW,+ZI) ;;與*功能相似的有.ANY,後面說明
} ;; The following declarations select the "two region model" ;

;; A default __user_initial_stackheap() will be used ;
ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {} ;;指定堆棧地址
ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}
}


下面是針對LPC2378的USB SRAM作數據RAM使用的配置:

;
;
; SCATTER LOADING DEION
; ARM
; KEILs uVision3
; (RealView Microprocessor Developer Kit)
;
; Filename : LPC2378_Flash.scat
;

LR_IROM1 0x00000000 0x00080000 ;; 第一個加載域,名字為LR_IROM1,起始
{                  ;;地址為0x0,大小為0x80000
ER_IROM1 0x00000000 0x00080000 ;;加載域中的運行時域,名字為ER_IROM1
{ ;; 起始地址為0x0,大小為0x80000
vectors.o (VECT, +First)
init.o (INIT)
* (+RO)
}

RW_IRAM1 0x40000000 0x0000e800
{
.ANY(+RW,+ZI)     ;; 此處.ANY替換原來的*,是因為下面的一個執行域對指定的模塊中的RW,ZI數據指定了存放地址
;;用.ANY就可以把已經被指定的具有RW,ZI屬性的數據排除
} ;; The following declarations select the "two region model" ;

找了3個分散加載文件來分析:

1、7x256的flash.sct分散加載文件:

Load_region 0x100000 0x40000 {//ro起始地址為0x100000,大小為0x40000

Fixed_region 0x100000 0x40000 {
*(cstartup +First)
.ANY (+RO)
}

Relocate_region 0x200000 {//rw和zi段的地址為0x200000

*.o (VECTOR, +First)
.ANY (+RW +ZI)
}

ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 {
}

ARM_LIB_STACK 0x210000 EMPTY -0x1000 {
}
}

2、sram.sct文件

Load_region 0x200000 0x10000 {

Fixed_region 0x200000 {
*.o (VECTOR, +First)
.ANY (+RO)
}

Relocate_region +0 {
*(cstartup +First)
.ANY (+RW +ZI)
}

ScatterAssert((ImageLength(Fixed_region) + ImageLength(Relocate_region)) < 0xE000)

ARM_LIB_HEAP 0x20E000 EMPTY 0x1000 {
}

ARM_LIB_STACK 0x210000 EMPTY -0x1000 {
}
}

3、自定義的sram.sct

LR_IROM1 0x00200000 0x00008000 { ; load region size_region
ER_IROM1 0x00200000 0x00008000 { ; load address = execution address//加載域等於運行域
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x00208000 UNINIT 0x00008000 { ; RW data//rw和zi段
.ANY (+RW +ZI)
}
}

什麼是分散加載文件這裡就不贅述了。

前面兩個分散加載文件是從別的地方拷過來的,用在自己的程序中可能會有問題,因為如果不修改它的話它就固定了加載地址和運行地址,如果程序簡單又比較小的話可能不會有問題,但是如果程序代碼比較大,超出了那兩個加載文件的定義大小可能就會出問題,解決辦法也很簡單,直接修改.sct文件直到適合你的代碼。

更好的辦法是自己定義一個分散加載文件,在keil中勾選Use Memory Layout from Target Dialog,那麼加載文件就是從你定義irom和iram等地址得到的,如果不勾選的話就是通過你自己指定的加載文件來加載。

如果分散加載文件不對的話,可能出現的問題就是明明是在sram中調試程序,但是卻能神奇的通過flash downloader下載到flash中去,剛開始也是不解,後來才發現是分散加載文件有錯誤,我使用了一個指定的flash.sct分散加載文件,這樣的話我設置的irom和iram都無效了,編譯器直接根據我指定的flash.sct來分布代碼和加載代碼,又查看了一下flash.sct文件是加代碼加載到flash地址空間的,這就是為什麼在jlink-sram工程中也能通過flash downloader工具燒寫代碼到flash中去的原因

相關焦點

  • ARM系列之分散加載描述符(scatte)文件的應用
    但不採用分散加載機制,零初始化段在編譯連接後是直接生成到鏡像文件中的。它的大小直接影響最終要燒寫的文件的大小,且零初始化段的大小還取決於內存的大小,它不能大到超過內存的大小;而採用分散加載機制,可以將某個零初始化段定位到非內存地址的一個存儲器外設上,如NVRAM(非易失性隨機存儲器)。
  • 引用ARM開發,對entry point的含義
    自己寫bootloader並通過scatter文件將之定位到硬體復位地址。或許某些開發工具會自動的為我們生成bootloader,這裡介紹的是自力更生的方法。首先介紹bootloader,這裡僅實現中斷向跳轉: AREA Vect, CODE, READONLY ;編譯器偽指令,scatter根據這些屬性來組織程序映像 ENTRY ;這個entry和本文中的entry point是沒有關係的,它表示的是彙編程序代碼部分的開始 LDR PC, Reset_Addr
  • ARM Linux根文件系統Root Filesystem的製作
    首先介紹根文件系統的組成:目錄、Shell、庫、腳本,一個個來。根文件系統要包含這些必須有的目錄:/dev、/bin、/usr、/sbin、/lib、/etc、/proc、/sys/dev是devfs(設備文件系統)或者udev的掛在點所在。
  • arm-linux-ld命令 ld連結腳本
    我們對每個c或者彙編文件進行單獨編譯,但是不去連接,生成很多.o 的文件,這些.o文件首先是分散的,我們首先要考慮的如何組合起來;其次,這些.o文件存在相互調用的關係;再者,我們最後生成的bin文件是要在硬體中運行的,每一部分放在什麼地址都要有仔細的說明。
  • ARM映像文件 he 編譯器自動生成的啟動函數
    什麼是arm的映像文件 arm映像文件其實就是可執行文件,包括bin或hex兩種格式,可以直接燒到rom裡執行。在axd調試過程中,我們調試的是axf文件,其實這也是一種映像文件,它只是在bin文件中加了一個文件頭和一些調試信息。
  • 嵌入式根文件製作方法
    然而在這個根文件系統中又包含了一系列的目錄,接下來對這些目錄做一個簡單的介紹。proc這是個空目錄,常作為proc文件系統的掛載點。dev該目錄存放設備文件和其它特殊文件。etc存放系統配置文件,包括啟動文件。lib存放共享庫和可加載塊(即驅動程序),共享庫用於啟動系統、運行根文件系統中的可執行程序。mnt用於臨時掛接某個文件系統的掛接點,通常是空目錄。
  • Andes 的分散聚合(SAG)機制
    通常這需要複雜的link script來管理實現,而Andes提供了分散聚合(SAG, Scattering-And-Gathering)機制,SAG機制能夠將加載和運行時存儲器中的代碼和數據描述在一個SAG格式的文本描述文件中,並通過link generator tool將SAG文件轉化為標準GNU的link script文件,以供連結時使用。
  • SpringBoot配置文件的加載優先級順序
    01application.properties加載Spring Boot啟動會掃描以下位置的application.properties或者application.yml文件作為Spring Boot的默認配置文件file:/config/file:/classpath:/config/classpath:/以上順序按照優先級從高到低的順序,所有位置的文件都會被加載,高優先級的配置內容會覆蓋低優先級配置的內容,其中配置文件中的內容是互補配置,即存在相同的配置內容,高優先級的內容會覆蓋低優先級的內容存在不同的內容的時候,高優先級和低優先級的配置內容取併集我們也可以通過
  • ARM-Linux開發與MCU開發的差別是什麼
    即編寫定製相應的bootloader,編譯生成bootloader映象文件後,利用工具(專用或通用)下載到SD卡的MBR區域(通常是存儲區的第一個扇區)。此時需要在BIOS中設置,或者通過電路板的硬體電路設置,選擇bootloader的加載位置;若BIOS中設置從SD卡啟動,則BIOS初始化結束後,將跳轉到SD卡的位置去執行bootloader,從而實現bootloader的啟動。
  • ARM板上掛載NFS文件系統
    建立和配置 NFS 服務(1)設置共享目錄 建立nfs目錄:/home/nfs/2410目錄,在Linux中修改配置文件 /etc/exports,如[root@nfs#]vi /etc/exports /home/nfs/2410 *(rw,sync,no_root_squash) 表示的是:(共享的目錄)空格(主機名或者IP)
  • Android逆向之旅--「最右」籤名算法解析(ARM指令學習噁心篇)
    因為之前有同學找我分析了一下,分析過程中覺得是個學習指令的好樣本就分享給大家,因為他的籤名算法稍微有點複雜,所以就分為三篇來介紹,希望通過這一系列的文章之後大家能夠了解到arm指令的常規語法,能夠簡單的分析so代碼邏輯。
  • 利用PostGIS導入ArcGIS Shapefile文件進行大數據量加載
    在研究開源GIS的過程中,會經常使用到PostGIS空間資料庫,接下來將和大家介紹如何將ArcGIS中的Shapefile數據導入到PostGIS資料庫中進行展示。1.首先我們準備下ArcGIS中的Shapefile文件,注意文件路徑及文件名不要出現中文字符,如下圖所示:2.打開已經安裝的「PostGIS Bundle 3 for PostgreSQL x64 9.6」下面的「PostGIS PostGIS Bundle 3 for PostgreSQL
  • OpenCV ffmpeg移植到ARM平臺
    那麼如何用OpenCV讀寫ARM板上的視頻文件,並進行視頻處理呢?這該又將如何移植呢?本文引用地址:http://www.eepw.com.cn/article/201611/317669.htm這個就必須要裝x264,xvid和ffmpeg,和上一篇中講的通過V4L2底層函數獲取攝像頭視頻就有點不一樣了。下面就介紹一種方法。
  • Python Add-In加載項系列:(3)創建加載項按鈕
    續接Python Add-In加載項系列文章,上一篇文章詳細介紹了Add-In加載項類型以及如何使用加載項嚮導創建加載項工程和創建工程文件需要注意的問題
  • gcc、arm-linux-gcc和arm-elf-gcc的關係?
    有一個 c 源文件 test.c 源碼如下:#include<stdio.h>int main(int argc, char *argv[]){ printf("Hello Linux!!\n"); return 0;}編譯命令為:gcc -o test test.c 編譯生成 test 可執行文件。gcc 編譯流程分為四個步驟:預處理、編譯 、彙編、連結。個人認為預處理和編譯主要由 gcc-core 來完成,彙編和連結主要由 Binutils 來完成。
  • 3分鐘理解 pytorch 的 gather 和 scatter
    這兩個方法,理解起來是有一定難度的,正因如此,網上有很多博客介紹它們,但往往作者講得並不清晰。scatter首先摘錄 pytorch 的官方文檔:scatter_(dim, index, src, reduce=None) → TensorFor a 3-D tensor, self is updated as:self[index[i][j][k]][j][k] = src[i][j][k] # if dim == 0self[i][index
  • ARM彙編和內嵌彙編
    一、ldr的確是個複雜的指令,現總結一下: 首先要判斷我們用的是ldr arm指令還是偽指令。 當我們用的是arm指令時,它的作用不是向寄存器裡加載立即數,而是將某個地址裡 的內容加載到寄存器。而偽指令ldr的作用就是向寄存器裡加載立即數。
  • ARM指令學習筆記
    順帶說一下其另一個便捷之處,加載/裝填數據時,可以在命令後加H/B來表示對半字/字節的數據操作,默認情況下是字。並且ARM可以實現一組寄存器和一塊連續內存之間傳送數據,如LDMIA和STMIA指令。>SHL R2,3ADD R1,R2就是說arm的指令更人性化,加上後來對arm偽指令的學習,我個人覺得arm指令集是彙編中的高級語言了。
  • MS Office格式文件完整介紹
    在這段時間裡,每個Office應用程式都在不斷發展,增加了新功能和新工具,並一路為與該程序一起使用的文件以及至少以一種或另一種方式與該程序兼容的其他文件開發新的文件類型。可以想像,在如此長的一段時間內,此文件類型列表已增長到驚人的規模,並且很難知道哪個文件適用於哪種程序,反之亦然。這就是我們今天要做的,為您介紹每個主要Office程序的所有不同Microsoft Office文件類型和擴展名。
  • 從官方文檔學pyecharts(Scatter、Overlap)
    創建一個Scatter,僅需一步:from pyecharts.charts import Scatterfrom pyecharts import options as optsfrom pyecharts.faker import Fakerscatter