龍芯軟體開發 11 龍芯2E執行的第一行程式

2021-08-22 06:32:25 字數 2841 閱讀 8849

天生萬物,萬物始於天。同樣,龍芯2e要執行起來,那麼就少不了程式。那麼龍芯2e的盤古開天是從那裡開始呢?追源尋根,才能了解事物的來龍去脈,才能把握住未來的方向。現在就去尋找龍芯電腦執行的第一行程式,去看看龍芯的初始化階段都做了些什麼事情,有沒有做壞事情呢?哈哈,這個很難說的。如果有bug的出現,就會幹出各種各樣的壞事情。

龍芯2e的記憶體布局已經說明它要從那裡載入第一行程式了,很明確的位址就是

0xbfc0 0000

,相應的實體地址是

0x1fc0 0000

。因此,只把

pmon

程式放到那個

rom flash

裡,就會執行第一行程式。

開啟pmon目錄下的檔案start.s,就會看到下面的匯程式設計序:

.set noreorder

.globl_start

.globlstart

.globl__main

_start:

start:

.globlstack

stack = start - 0x4000 /* place pmon stack below pmon start in ram */

/* note!! not more that 16 instructions here!!! right now it's full! */

mtc0 zero, cop_0_status_reg

mtc0 zero, cop_0_cause_reg

lit0, sr_boot_exc_vec /* exception to boostrap location */

mtc0 t0, cop_0_status_reg

lasp, stack

lagp, _gp

bal uncached /* switch to uncached address space */

nopbal locate /* get current execute address */

nopuncached:

orra, uncached_memory_addr

j ra

nop/*

蔡軍生 2006-12-28 */ ok

,從上面看到,第一行程式執行的就是

mtc0zero, cop_0_status_reg

。找到了第一行執行的程式,但這段程式是什麼意思呢?為什麼不是

.set noreorder

最先執行的呢?有疑問就是好方向,下面就慢慢地給你解說。在龍芯所使用的編譯器是gcc,那麼它的彙編也有特定的格式。在這裡看到的就是彙編器的編譯程式所需要格式和編譯條件。

.set noreorder是告訴彙編器不要對後面的**進行優化處理,比如重新排列執行**。

.globl_start

.globlstart

.globl__main

這裡,就定義了三個全域性名稱。可以任何地方引用它。

_start:

start:

.globlstack

stack = start - 0x4000 /* place pmon stack below pmon start in ram */

在這裡定義了子程式的名稱

_start和

start

。並定義了堆疊的大小變數

stack。

/* note!! not more that 16 instructions here!!! right now it's full! */

mtc0 zero, cop_0_status_reg

mtc0 zero, cop_0_cause_reg

lit0, sr_boot_exc_vec /* exception to boostrap location */

mtc0 t0, cop_0_status_reg

lasp, stack

lagp, _gp

由於龍芯的位址空間決定,這裡的**不能超過32條指令,因為後面緊跟著是其它中斷向量的位址。接著,就把cp0的狀態暫存器

cop_0_status_reg

和cop_0_cause_reg暫存器全部清空為

0。li t0, sr_boot_exc_vec接著設定狀態暫存器的bev位,這樣就是讓cp0執行在沒有tlb的模式,並且執行在引導模式。後面兩句主要設定引導程式的堆疊空間,lasp, stack是把棧首位址給sp暫存器,la gp, _gp是把編譯器中的_gp全域性位址給gp暫存器,這樣做法是讓全域性變數可以作相對暫存器定址。其中_gp是在連線指令碼檔案裡定義的。

bal uncached /* switch to uncached address space */

nopbal locate /* get current execute address */

nopuncached:

orra, uncached_memory_addr

j ra

nop這段程式先進行乙個無條件跳轉連線指令,這樣做的目的很明確就是想清空預取指令和流水線的指令。這樣就跳到

uncached這裡執行,先來看看bal指令會做些什麼事情,通常bal指令會算出相對於pc暫存器的偏移量,然後把pc+8指令位址放到ra暫存器裡,也就是把bal locate指令位址放到ra暫存器,以便可以返回。由於龍芯2e的加電時啟動位址是

0xbfc0 0000,那麼放在

ra裡的值就是0xbfco 0028。後面or ra, uncached_memory_addr,這裡進行是與0xa000 00000的或運算,也就是說從rom載入時,不會改變返回位址ra的值。主要是從其它位址空間執行這段程式時才會引起跳轉的位址空間的轉換。所以接著就跳回來到bal locate位置並執行bal locate指令,這樣就跳到locate的位置執行程式了。

龍芯軟體開發 12 龍芯2E摸索前行

上一次說到怎麼樣執行起來,現在接著上次再進行分析下去。在 locate的程式,如下 locate la s0,start subu s0,ra,s0 ands0,0xffff0000 li t0,sr boot exc vec mtc0 t0,cop 0 status reg mtc0 zero,c...

龍芯軟體開發 8 理解龍芯2E暫存器和記憶體布局

對於軟體開發人員來說,乙個cpu最重要的部分就是暫存器 記憶體布局和指令。龍芯2e 邏輯上是有 32個定點通用暫存器 其中 0號固定為0 32個浮點暫存器,乙個 hi,乙個 lo,以及若干 cp0控制暫存器,兩個 cp1控制暫存器。物理上是 64個定點,64個浮點,和若干控制暫存器。龍芯2e具有下面...

關閉龍芯2E 之 cache

發表日期 2006 11 01 19 50 pmon 載入kernel 時,是載入到 kseg0 的 通過在 arch mips makefile 中 load config godsonev2e 0x80100000 指定 該位址空間是 unmaped cached 的,當 pmon 將控制權交給...