關於系統移植uboot的一些思路

2021-05-21 21:54:35 字數 3712 閱讀 2942

第一回:

應深圳友堅科技之邀,這幾天要把djyos移植到他們的idea6410上。

現在發布的是si版本,是以微控制器模式執行的,s3c6410這樣強勁的cpu,執行si版本,就作為高速微控制器用了,所有位址都是按照實體地址一一對應對映。cpu的狀態也沒有區分核心態和使用者態。

1、中斷引擎最初的部分**在irq態(還沒決定是否使用fiq)。

2、中斷引擎的大部分以及使用者isr執行在svc態。

3、所有其他**執行在sys態。

移植碰到的第乙個問題就是燒錄**到flash的問題,由於廉價的jtag燒錄器不支援arm11,我們不能要求使用者必須擁有昂貴的**燒錄工具才能夠在idea6410上使用djyos,這樣不利於使用者使用。

6410的手冊上說,可以從nandflash、onenand、sd卡啟動,沒有專用的燒錄工具的情況下,只有sd卡啟動是可以考慮的。手冊上看到,sd卡啟動,實際上是先執行片內irom中的一段程式,該程式從sd卡中讀取**,寫到stepping stone中,stepping stone是位於0x0c000000、size為8k的片內記憶體,**寫入stepping stone後,跳到0x0c000000處繼續執行程式。那麼,要實現從sd卡啟動,就必須弄清楚:

1、8k的**儲存在sd卡的什麼位置。

2、**以什麼格式儲存。

為弄清楚上述問題,依例google 一番,沒找到有用的資料,上三星的**,6410的資料沒有公開,申請了一下,第二天得到了批准,也沒有關於怎樣從sd卡啟動的資料。找三星**,似乎不太愛搭理我,也是,我勢單力薄乙個人,他們怎看得上眼。難道就沒有辦法了?

依葫蘆畫瓢,把編譯好的**寫入到最後晶元末尾偏移-9216位元組處,插入sd卡座,把開關撥到sd0卡啟動的位置,上電,哈哈,成功了,幾個藍色的led歡快地閃爍起來。試了兩個sd卡,16m的可以,2g的不行,不知何故,暫且放一邊吧。

首戰告捷,該歇歇了,待續。

第二回:

上篇說道,用16m的sd卡啟動可以,但用2g的卡卻不行,反覆試過,實在不知道怎麼回事,也沒有irom中的引導程式的進一步資料,問題也就無從查起了,暫且先放一邊,把後續的移植工作做完再說吧。

移植作業系統,跟開發裸奔程式是不一樣的,裸奔程式可以從main開始寫程式,在執行main之前,編譯器產生了大量的**用於初始化cpu、記憶體清零、初始化堆和棧、直到建立main的執行環境。而作業系統往往有自己的執行環境要求,c編譯器完成的這些環境往往不能符合要求,需要自己寫初始化檔案,即initcpu.s檔案。

初始化檔案主要完成以下工作:

1、從復位位址跳轉到啟動位址。

2、設定cpu為特權模式,禁止看門狗和中斷,禁止cache。

3、設定時鐘,有些cpu的時鐘設定很複雜的,尤其是高速cpu,因為涉及到核心和外設匹配的問題,設定起來比較麻煩。

4、設定記憶體匯流排,設定記憶體訪問速度,要跟上一步的時鐘設計配合,使cpu能正確讀寫記憶體和記憶體對映的外設。

5、配置cache和mmu,然後使能cache和mmu。

6、初始化棧,跳轉到c**。

根據拿來主義的原則,寫cpu初始化**千萬不能自己從0開始寫,而是要找乙個現成的來參考,因為各個系統的cpu初始化工作是大同小異的。而且,許多 cpu廠商都會出example,會帶乙個檔名類似startup.s的檔案,參考該檔案來寫即可。但是,三星不知從何年何月開始不公開其cpu的文件了,甚至連datasheet都要申請才給。當我千辛萬苦找到三星提供的"6410_test_rev01"源**包時,心都涼了,該**包中雖然有 start.s檔案,但檔案中只有幾條指令,初始化過程都在"__rt_entry"函式中,而該函式在庫中。對晶元應用資料的保密工作做得如此周密,不知三星所謀何事。

沒辦法,繼續找,實在不行再自己一行行寫。好在天無絕人之路,終於在友堅提供的wince的eboot**中,找到了eboot的start.s檔案,開啟一看,果然是乙個詳細的啟動檔案,心中不禁狂喜!

接下來的工作,就是對照datasheet,看懂這個start.s,然後改造成適合djyos的。別看說的輕巧,這裡面工作量還是很大的,6410的 datasheet有1300多頁,光時鐘和匯流排配置相關的部分就有100多頁,e文的,暈死。而且第一次用arm11,其mmu和cache配置和 arm9有多大差別,還不可知。今天先寫到這裡,下回分解吧。

第三回:

接續上回,開始啃start.s,跟所有的啟動檔案一樣,開始部分是關閉cache、禁止中斷等,沒什麼問題。這裡稍稍解釋一下為什麼要做這些工作,禁止中斷大家應該沒什麼異議,關鍵是為什麼一定要禁止 cache,原來,我們不知道程式為什麼要重新啟動,也不知道重新啟動前cpu和cache處於什麼狀態,cache可能包含錯誤的資訊,cpu可能會從中取得錯誤的指令,從而不能正常啟動系統。eboot的start.s遺漏了乙個很重要的過程,就是要重新把cpu設定成svc狀態,因為就像我們不了解重啟動前cache狀態一樣,cpu的狀態也是未知的,須加上這幾句確保cpu處於svc態:

mrs r0,cpsr @取cpsr

bic r0,r0,#modemask @清模式位

orr r1,r0,#svcmode|noint @設定為管理態,並禁止中斷

msr cpsr_cxsf,r1 @切換到管理態,可防止意外返回0位址時出錯.

實際上,這幾句仍然不夠保險,因為如果程式是從user態直接跳轉到0位址的話,mrs和msr指令是無效的。保險的做法是用swi指令強制修改,既然是個簡易的bootloader程式,暫且偷懶一下。

依慣例,接下來是各種時鐘初始化,s3c6410的時鐘結構比較複雜,共有3個pll要設定,而且分頻控制也較為複雜,雖然start.s有得抄,但還是要自己弄清楚,因為接下來的程式設計用得上。6410的時鐘部分之所以如此複雜,完全是為了適應其內部豐富的外設,不同的外設需要不同的時鐘。設定時鐘,不外乎就是定義幾個常用的主頻,然後分別為這些主頻定義鎖相環(pll)的分頻係數,再把這些分頻係數填充到相應的暫存器中去,細節就不再贅述了,看**吧。

初始化完時鐘後,就輪到初始化記憶體匯流排了。依據用什麼初始化什麼的原則,這裡只初始化了srom0和dram兩個區域,這部分**是用c語言實現的,參見memcfg.c檔案,**比較簡單,不過是按照datasheet的要求,依次設定暫存器而已。

接下來,你一定會想到,該初始化mmu了,初始化mmu本來是一項複雜的工作,但si版本是為微控制器準備的,即使6410再強勁,也只能委屈一下,當高速微控制器了。mmu在這裡並沒有用來做位址變換,而是把4g記憶體空間全部對映到其實體地址上了。這種對映效果跟禁止mmu是一樣的,但是arm的mmu和cache是繫結在一起的,禁止mmu的同時也就禁止了cache,故只能開啟mmu。頁表的位址在0x50000000,占用16kbytes,故應用程式的起始位址是0x50004000。

又可以偷懶了,6410的核是arm11jzf-s的,2440的核是arm920t的,arm11jzf-s的mmu功能比arm920t的強很多,但都是arm公司的,做最簡單對映的話,能否相容呢?懶得讀arm11的手冊了,先試一下把2440版本的mmu初始化部分直接copy看行不行。事實證明是可行的,但我在這裡繞了乙個大大的圈子,浪費了許多時間。加入初始化mmu部分**後,試了一下,發現燈不閃了,而把該段程式放到初始化頁表的**之前,則可以。仔細檢查,發現是因為dram沒有初始化,加上dram初始化後,先把閃燈程式放在dram初始化後面,發現可以了。這時候,不幸發生了,移動閃燈程式時,只copy了一半的**,當然不閃了,可我沒仔細檢查**,就懷疑是2440的mmu初始化**不能用於6410的造成的(偷懶了,心虛),於是找來arm11jzf-s的手冊猛啃,幾百頁的英文資料啊,費了好幾天功夫,最後證明了一件事:原來的mmu初始化是正確的!!

到這裡,基本硬體的初始化就算完成了,接下來要搞norflash和uart的driver了。待續......

關於系統移植uboot的一些思路

第一回 應深圳友堅科技之邀,這幾天要把djyos移植到他們的idea6410上。現在發布的是si版本,是以微控制器模式執行的,s3c6410這樣強勁的cpu,執行si版本,就作為高速微控制器用了,所有位址都是按照實體地址一一對應對映。cpu的狀態也沒有區分核心態和使用者態。1 中斷引擎最初的部分 在...

關於U boot的移植(一)

參考文章 s3c6410移植u boot 2010.3 1 成功編譯的開始 s3c6410移植u boot 2010.3 2 基本的啟動資訊修改 s3c6410移植u boot 2010.3 3 正常化配置 s3c6410移植u boot 2010.3 4 uboot的dnw功能新增 s3c6410...

關於uboot一些概念

u boot的環境變數值得注意的有兩個 bootcmd和bootargs。bootcm bootargs bootargs是環境變數中的重中之重,甚至可以說整個環境變數都是圍繞著bootargs來設定的。bootargs的種類非常非常的多,我們平常只是使用了幾種而已.bootargs非常的靈活,核心...