• 沒有找到結果。

3. 系統架構與實作

3.1. DSP Manager

3.1.1. DSP系統核心的啓動機制

在DSP 上執行的系統核心之原始程式碼,經由 TI 的開發工具 CCS 編譯後,

會產生一個執行檔。一般在系統開發階段,這個執行檔是由 CCS 經由 JTAG 來 載入到 DSP 的程式記憶體空間。但對嵌入式系統而言,開發完後,要銷售的產 品,並不會有 JTAG 這種介面來載入程式,大都是將程式的執行檔燒錄到 Flash 上,開機就能獨自運行。因此 DSP 的系統核心也需要提供類似的方式來啓動 (boot)。Rishi Bhattacharya 提供一個 OMAP5910 的 DSP 開機範例[10],將 DSP 的執行檔轉成一個常數資料陣列的宣告,和運行在 ARM 上的主程式一起編譯 後,再由ARM 的主程式經由 MPUI 將這個資料陣列(DSP 的系統核心)載到 DSP 的程式記憶體空間,並加以啓動,詳細步驟如Figure 5。

Figure 5. Bootloader Build Flowchart.

其中 OUT2BOOT,是隨[10]附上的程式。它會先用 CCS 裡的工具 Hex Conversion Utility(hex55.exe), 詳細使用說明可以參照 TI 的文件[11]。將執行檔 (.out 檔)轉成 Intel MCS-86 Object 的格式,再轉成 header 檔內的資料陣列宣告,

詳細格式如Figure 6。

Figure 6. Intel Hex Object Format.

可以看到這種格式可記錄的address 只有 16 bits,但由 ARM 的 MPUI 載入 DSP 的程式記憶體空間會需要 32 bits。因此被轉出來 header 檔,只固定從 0xE0010000 開始填寫到 0xE001FFFF,這也是對應到 DSP 內部的 SARAM 前 64Kbyte,以 DSP 程式記憶體空間來看是從 0x10000 的位置開始去填寫。會固定 從0x10000 開始,是根據 TI 的文件對 DSP Bootloader 的說明[12]。DSP Bootloader 做好基本的設定後,會根據 Boot 模式,跳到特定的起始位置,0x10000 是其中 的Internal memory boot 模式(5)的起始位置。為了使編譯完的執行檔,其起始位 置也是0x10000,這需要對 CCS 的 linker 設定檔(.cmd 檔)做些修改,如 Figure 7,

其詳細使用說明可以參照 TI 的文件[13]。強制設定負責初始化 C 語言環境的 boot.obj 連結檔,在 static link 時,會 link 成從 0x10000 開始載入,而 boot.obj 執 行完C 語言環境的初始化程序(c_int00 函式),就會呼叫我們的 main 函式。

MEMORY {

: :

SARAM: origin = 0x10000, len = 0x18000

: : }

SECTIONS { :

.text: { rts55x.lib<boot.obj> (.text) } > SARAM

: : }

Figure 7. Starting Address Configuration.

但 這 樣 的 設 計 就 限 制 了 程 式 只 能 載 入 到 SARAM , DSP 內 部 另 外 有 DARAM,同時可以存取兩筆資料,如果我們把 DSP 系統核心的資料區域放在 DARAM,應能提升效率。如果執行檔有用到 DARAM,其轉出來的 Intel Object 會有Recode type 為 04 的 entry,代表要改變目前 24bit base address 的 high 8bit,

但原本OUT2BOOT 不支援,一處理到這種 entry 就會當掉。我們將 OUT2BOOT 提供的程式碼稍微修改後,並在轉成header 檔時,加上把 DSP 程式記憶體空間 的位置,轉成對應MPUI 或 shared memory 的位置的功能,就可以解決這個問題,

之後要ARM 設定 DSP 核心系統的記憶體就比較簡單。

但照著[10]的 DSP 開機範例去啓動 DSP 後,DSP 還是不能正常運作,後來 在OSK5912 開發板提供給 CCS 的設定檔 osk5912.gel 裡面發現類似的函式。.gel 檔的作用,是讓CCS 去對使用的核心初始化,會以類似[10]所描述的方式去啓動 DSP,但會設定更多的暫存器,而填到 SARAM 的 DSP 機械碼,只是不停執行 一個無窮迴圈而已。參考.gel 檔來改寫原本 ARM 啓動 DSP 的 dsp_init 函式,這 樣就可以很順利讓DSP 啓動,並順利執行 ARM 根據 header 檔內的資料陣列所 設定好在SARAM 和 DARAM 內的 DSP 核心執行檔之內容。

3.1.2. DSP 記憶體管理

DSP 可以存取的記憶體除了內部的 DARAM 和 SARAM 外,經由 DSP MMU 的設定可啟用shared memory,這樣 DSP 就可存取共用的 SRAM 和外部的 Flash 和SDRAM。本論文所設計的系統,針對這些記憶體種類和動態分配的需要,以 linked-list 來實作記憶體管理,並提供了三個函式給系統核心及應用程式使用,

如Figure 8 所示。

typedef struct _dspmem {

uint32 base;

uint32 size;

int used;

int type;

struct _dspmem *next;

}dspmem;

void dspmem_init();

dspmem *dspmem_alloc(uint32 size, int type);

int dspmem_free(dspmem *free_dspmem)

Figure 8. DSP Memory Managerment functions.

目前系統規劃了五種不同類別的記憶體(DARAM、SARAM、SRAM、

SDRAM、Flash),所以在 dspmem_init 函式裡,會對五個 linked-list 做初始化,

設定可以使用的位置和大小。如Figure 9,當系統或應用程式所註冊的服務要求 DSP 分配大小為 0x2000 的 SARAM 的記憶體空間以供使用,DSP 記憶體管理程 式會從 SARAM Head 開始尋找有足夠空間的節點,找到後修改它所佔用的大 小、並標示為已使用、最後新增一個節點記錄剩餘的空間。從Figure 9 可以注意 到每個節點的Base address 是用 24 bits 來記錄,這是因為透過 DSP 的記憶體管 理程式分配到的記憶體空間,是要給DSP 執行的服務所使用的,而 DSP 的資料 位址最多有24-bit 的空間。

Base:0x010000

Figure 9. DSP Memory Allocation Example.

3.1.3. 動態服務註冊管理 結檔格式是common object file format,COFF。在系統開發的過程中,我們發展 了一個程式,分析連結檔後將所有必要的資訊(如參考到的外部程式等等)連結

3.1.3.1. COFF file structure

根據 TI 文件對 COFF 檔的描述[14],每次編譯後產生的連結檔包含了 File header、Section header、Section raw data、Section relocation information、Symbol table、String table。如 Figure 10 所示。

Figure 10. COFF File Structure.

其中File header 如 Figure 11,可得知 Version ID、Section 個數,Symbol table 的位置和有多少筆entry;而一般都不會有 Option header。File header 裡面 Version ID 的 2 個 byte 用 little-endian 方式讀取,一般都是 0x00C2,如果是 0xC200,則 代表目前的連結檔是以big-endian 編寫的。

Figure 11. File Header Contents.

COFF 檔裡的 Section,代表程式執行會需要的各類記憶體空間,可以分成兩類。

1) Initialized section:

其raw data 有實際內容,如機械碼、const 變數。

2) Uninitialized section:

保留的記憶體空間,只有Section 大小,在連結檔裡並沒有實質內容,例如 未被初始過的global 變數等,只是用來告知 linker 要為其保留記憶體空間。

Section header 的格式如 Figure 12,會需要用到 Section 的名稱、Size、Raw data 位置、Relocation information 位置和個數。名稱的欄位最多只能存 8 個字元,所 以字數大於8 的名稱,會記錄著 String table 裡的 offset,在 String table 裡就會有 完整的名稱。之後所有用到名稱的欄位都是以這種方式來記錄。如果是Initialized section,Size 和 Raw data 位置的欄位都會有非零的值;Uninitialized section 則只 有Size 欄位有非零的值,Raw data 位置和 Relocation information 都會是零。如果 Section 有 Relocation information,則代表其 Raw data 裡有 Virtual address,需要 在link 時被重新定位(relocate)為 Physical address。

Section 的名稱是很重要的欄位,CCS 為 DSP 所產生的 COFF 檔會有 Table 1 所列的這幾種section。

Table 1. COFF File Sections.

名稱 Initialized 存放內容/用途- .text 是 機械碼

.data 是 assembly 語言的變數初始值 .bss 否 未被初始過的global 變數 .const 是 const 變數

.switch 是 switch statement label table

.cinit 是 C 語言的 global 變數初始值 table .pinit 是 C++語言的 object constructor table .cio 否 C 語言的 IO 暫存空間

.stack 否 主要的系統stack 記憶體 .sysstack 否 第二個系統stack 記憶體 ..sysmem 否 heap 記憶體

而實際在release mode 編譯 H.264 Intra frame 編碼器所產生的 COFF 檔,只 會用到.text、.bss、.const、.switch、.cinit、.sysmem,這幾個 Section。而其中.cinit section 是在 setup C 語言環境時,根據 Raw data 裡的 Auto initialization table 設定 global 變數的初始值,也就是要填初始值到.bss section 的所保留的空間,因此這 兩個section 是可以整合為一個 section,另外.sysmem 是只有 C 語言內建的 malloc 和 free 函式會用到,會特別再做處理。所以分析 COFF 檔後,最後只會留 下.text、.bss、.const、.switch,這四個 section 在映像檔裡。

Relocation information 是為了重新定位 Symbol 的 Virtual address 到 physical address 所用的資訊,就是如何做到動態載入最主要的資訊。格式如 Figure 13。

會需要用到Virtual address、Symbol table index 和 Relocation type。這個 Virtual address 是指被重新定位的 Symbol 在 Raw data 裡的 offset,經由這個 offset 可以 讀到Relocatable field,即 Symbol 的 Virtual address。

Figure 13. Relocation Entry Contents

Symbol table 裡的 Symbol 格式如 Figure 14,會需要用到名稱、Value、Section number 和 Storage class。Section number 代表這個 Symbol 屬於哪個 Section,如 果Section number 不是 0,代表這個 Symbol 是 Internal Symbol,再根據 Storage class,分別是 Global 或是 Static,如果是 Global,可以被其他連結檔 Reference 的 Symbol,如果是 Static,則是目前連結檔裡的 Relocation information 會到的 Symbol。

如果 Section number 是 0,代表這個 Symbol 不在目前的連結檔,而是 Reference 其他連結檔的 Symbol,屬於 External Symbol。所以要由連結檔建立映 像檔之前,如果連結檔裡要重新定位的Symbol 屬於 External Symbol,則必需先 Resolve 這些 External Symbol,當發現 External Symbol 在某個連結檔裡,這個連 結檔也要一起被建立進映像檔裡。

因為TI 的文件[14]並沒有詳細說明,每一類 Relocation information,要如何 重新定位。為了能在動態重建執行檔的資訊,因此以反向工程的方式,把原本連 結檔裡的16 進位值和在 CCS 下開啟執行檔相互對照,大略可以把在 Relocation information 所記錄的資訊,分成 Table 2 中四類。

Table 2. Relocation Information

名稱

機械碼內存放 Physical address 的暫存器

Virtual address of

Reference Symbol Name

Internal AR ARn global 變數、const 變數 .bss/.const/.sysmem Internal AC ACn global 變數、const 變數、

switch statement label table

.text/.bss/

.const/.switch External AR ARn 別的object 檔的 global 變數、

const 變數、function

function/variable name

External AC ACn 別的object 檔的 global 變數、

const 變數 __SYSMEM_SIZE

其中會使用 ARn 或 ACn 哪一種暫存器是根據 physical address 被讀出後的 offset 計算有關,如只是 scalar 變數和一維陣列,通常是會讀到 ARn,而多維的 陣列或是陣列的 index 會經由複雜的運算而得出的,則會讀到 ACn;switch statement 如果比較複雜的將會使用 label table,而這 table 的 physical address 都會 載入到ACn,而 external function 的 address 則都是使用 ARn。

ARn 類的 relocation information 會用有一筆 3byte 的 Relocatable field,載入 23bit 的值到 ARn 暫存器。AC 類的 relocation information 則會用兩筆 2byte 的 Relocatable field,以組成 32bit 的值載入到 ACn 暫存器。

3.1.3.2. Virtual Address 的取得

重新定位所需要的Virtual address 取得的方式可分兩種 1) Internal:

Symbol 位於目前連結檔的某個 Section 裡,經由 Relocation information 可以 在Raw data 裡找到對應的 Relocatable field,Symbol 的 Virtual address 會在 Relocatable field 上。

2) External:

Symbol 位於其他連結檔的某個 Section 裡,這就需要 Resolve 這個 Symbol。

到其他連結檔裡的 Symbol table 去找這個 Symbol 名稱,如果找到,則其 Value 欄位代表著 Symbol 在 Section number 對應 Section 裡的 Virtual address。但這會是 byte address,如果 Symbol 不屬於 function,就是不屬於 程式記憶體空間的位址,必須再除 2 得到資料記憶體空間用的 word address(16bit address)。

3.1.3.3. Dual-core Service Image File Format

我們從各連結檔中抽取最重要的資料,並考慮Relocation information 的種類 和Virtual address 取得的方式,設計了如 Figure 15 的映像檔格式。還多保留了 ARM 的執行檔的欄位,是因為我們的目標是能將同一個函式,編譯成包含兩個 核心執行檔的映像檔,這樣就能隨著實際各核心上的負擔,動態載入執行檔到較 低負載的核心來運行

ARM executable DSP object number Section size header Section raw data Sysmem information Relocation information Main/Initial entry point

DSP object number 欄位,標示這個映像檔中 DSP 的執行檔由有多少個連結

DSP object number 欄位,標示這個映像檔中 DSP 的執行檔由有多少個連結

相關文件