該文檔的目的是總結(jié)我們?cè)诠ぷ髦械囊恍┙?jīng)驗(yàn),并把它們分享給喜歡
ARM和Linux的朋友, 如有錯(cuò)誤
之處,請(qǐng)大家多多指點(diǎn). 同樣, 我們也希望更多人能把自己的工作經(jīng)驗(yàn)和體會(huì)加入該文檔,讓大家共同進(jìn)步.
該文檔是一份交流性文檔, 只供個(gè)人學(xué)習(xí)與交流,不允許公司和企業(yè)用于商業(yè)行為.
第一部分前言
1硬件環(huán)境
1.1主機(jī)硬件環(huán)境
開(kāi)發(fā)機(jī):Pentium-4 CPU
內(nèi)存: 512MB
硬盤(pán): 60GB
1.2目標(biāo)板硬件環(huán)境
CPU: S3C2410
SDRAM: HY57V561620
Nand flash: K9F1208U0B(64MB)
以太網(wǎng)芯片:CS8900A (10M/100MB)
1.3工具介紹
仿真器:Dragon-ICE
電纜:串口線,并口線
2軟件環(huán)境
2.1主機(jī)軟件環(huán)境
2.1.1 Windows操作系統(tǒng)
ADS編譯工具:ADS1.2
仿真器軟件: Dragon-ICE daemon程序
2.1.2 Linux操作系統(tǒng)
GNU交叉編譯工具:
2.95.3:
作用:編譯u-boot
3.3.2, 3.4.4:
作用:編譯內(nèi)核和應(yīng)用程序
其它工作:
tree工具:
作用:查看文件目錄樹(shù)
下載:從
ftp://mama.indstate.edu/linux/tree/下載編譯
2.1.3目標(biāo)板最后運(yùn)行的環(huán)境
啟動(dòng)程序:
u-boot-1.1.4
內(nèi)核:
linux-2.6.14.1
應(yīng)用程序:
1. busybox-1.1.3
2. TinyLogin-1.4
3. Thttpd-2.25
2.2 Linux下工作用戶及環(huán)境
2.2.1交叉工具的安裝
工具鏈的編譯過(guò)程請(qǐng)參考第三部分.
1. 下載交叉工具
2.95.3 下載地址:ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross2.95.3.
tar.bz2
3.3.4 下載地址:
2. 編譯交叉工具
[root@localhost ~]mkdir /usr/local/arm
[root@localhost ~]cd /usr/local/arm
把cross-2.95.2.tar.bz2, cross-3.4.4.tar.gz 拷貝到/usr/local/arm目錄中。解壓這兩個(gè)包。
[root@localhost ~]tar -xjvf cross-2.95.2.tar.bz2
[root@localhost ~]tar -xzvf cross-3.4.4.tar.gz
2.2.2 u-boot移植工作目錄
1. 添加工作用戶
[root@localhost ~]#useradd -G root -g root -d/home/uboot uboot
2. 建立工作目錄
[uboot@localhost ~]$mkdir dev_home
[uboot@localhost ~]$cd dev_home
[uboot@localhost dev_home]$mkdir doc mybootloader uboot
.
|-- doc
|-- mybootloader
`-- uboot
3. 建立環(huán)境變量
[uboot@localhost ~]vi ~/.bashrc
export PATH=/usr/local/arm/2.95.3/bin:$PATH
2.2.3內(nèi)核及應(yīng)用程序移植工作
1. 添加工作用戶
[root@localhost ~]#useradd -G root -g root -d/home/arm arm
2. 建立工作目錄
[arm@localhost arm]$mkdir dev_home
[arm@localhost arm]$cd dev_home
[arm@localhost arm]$mkdir bootldr btools debug doc images kernel localapps \
rootfs sysapps tmp tools
[arm@localhost arm]$tree -L 1
.
|-- bootldr
|-- btools
|-- debug
|-- doc
|-- images
|-- kernel
|-- localapps
|-- rootfs
|-- sysapps
|-- tmp
`-- tools
可以看到如上樹(shù)形結(jié)構(gòu)。
注:tree命令
3. 建立環(huán)境變量設(shè)置腳本
[arm@localhost arm]$vi env_sh
#!/bin/bash
PRJROOT=~/dev_home
KERNEL=$PRJROOT/kernel
ROOTFS=$PRJROOT/rootfs
LAPP=$PRJROOT/localapps
DOC=$PRJROOT/doc
TMP=$PRJROOT/tmp
export PRJROOT KERNEL LAPP ROOTFS
export PATH=/usr/local/arm/3.4.4/bin:$PATH
4. 登陸時(shí)啟動(dòng)環(huán)境變量
[arm@localhost arm]$vi ~/.bashrc
. ~/dev_home/env_sh
重新登陸
arm用戶,環(huán)境變量生效
[arm@localhost arm]$su arm
2.3配置系統(tǒng)服務(wù)
2.3.1 tftp服務(wù)器的配置
如果用下面一條命令能夠看到服務(wù)已經(jīng)啟動(dòng), 則不用安裝, 否則需要按
1或
2點(diǎn)安裝tftp-server服務(wù)器.
[arm@localhost arm]#netstat -a | grep tftp
udp 0 0 *:tftp *:*
1. 從
RPM包安裝tftp-server
從對(duì)應(yīng)Linux操作系統(tǒng)版本的安裝光盤(pán)上找到tftp-server的安裝包.
下面
tftp-server-0.32-4.i386.rpm包為例,把rpm包拷貝到dev_home/btools/下.
[arm@localhost arm]#cp tftp-server-0.32-4.i386.rpm /home/arm/dev_home/btools/
[arm@localhost arm]#su root
[root@localhost arm]#rpm -q tftp-server
如果沒(méi)有安裝tftp-server,就要用下面命令安裝,否則,直接進(jìn)入第2步配置服務(wù).
[root@localhost arm]#cd /home/arm/dev_home/btools/
[root@localhost btools]#rpm -ivh tftp-server-0.32-4.i386.rpm
建立tftp的主工作目錄
[root@localhost btools]#mkdir /tftpboot
2. 修改配置文件并啟動(dòng)服務(wù)
備份配置文件
[root@localhost btools]#if [ -f /etc/xinetd.d/tftp ]
> then
> cp /etc/xinetd.d/tftp /etc/xinetd.d/tftp.old
> fi
修改配置文件
[root@localhost btools]#vi /etc/xinetd.d/tftp
service tftp
{
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
per_source = 11
cps = 100 2
flags = IPv4
}
檢查
tftp服務(wù)是否打開(kāi)
[root@localhost btools]#chkconfig --list
如果
tftp的服務(wù)沒(méi)有打開(kāi),則用下面命令打開(kāi)tftp服務(wù)開(kāi)關(guān)
[root@localhost btools]#chkconfig tftp on
重啟服務(wù)
#/etc/init.d/xinetd restart
#netstat -a | grep tftp
udp 0 0 *:tftp *:*
2.3.2 NFS服務(wù)器的配置
1. 安裝NFS服務(wù)器
[root@localhost btools]#rpm -q nfs-utils
如果沒(méi)有安裝,從對(duì)應(yīng)Linux操作系統(tǒng)版本的安裝光盤(pán)上找到nfs-utils的安裝包.Fedora 5中的安裝包
名稱為nfs-utils-1.0.8.rc2-4.FC5.2.i386.rpm。下面以該安裝包為例說(shuō)明:
[root@localhost btools]#rpm -ivh nfs-utils-1.0.8.rc2-4.FC5.2.i386.rpm
2. 配置NFS服務(wù)器
[root@localhost btools]#vi /etc/exports
#加入要允許被另外計(jì)算機(jī)mount的目錄:
#/home/arm/dev_home/tmp 為被另外計(jì)算機(jī)mount的目錄
#192.168.1.134 允許另外計(jì)算機(jī)mount的IP
#rw,sync,no_root_squash表示訪問(wèn)限制,更詳細(xì)說(shuō)明見(jiàn)相關(guān)手冊(cè).
/home/arm/dev_home/tmp 192.168.1.134(rw,sync,no_root_squash)
3. 啟動(dòng)NFS服務(wù)器
第一啟動(dòng)NFS服務(wù)器時(shí)用下面命令.
[root@localhost btools]#/etc/init.d/nfs start
如果你已經(jīng)啟動(dòng)了
NFS服務(wù)器時(shí),并且重新修改了/etc/exports文件,用如下命令使新加入的目錄生效:
[root@localhost btools]#/etc/init.d/nfs reload
4. 測(cè)試NFS服務(wù)器
[root@localhost btools]#netstat -a | grep nfs
5. 顯示被
export出的目錄列表
[root@localhost btools]#exportfs
2.4工具使用
2.4.1 minicom的使用
1.切換到root用戶.
[root@localhost btools]#su 2.
查找有效的串設(shè)備.
[root@localhost ~]#cat /proc/devices
...
4 ttyS
...
188 ttyUSB
...
如果是普通串口設(shè)備, 設(shè)備名前綴為ttyS, 第一串口為ttyS0, 第二串口為ttyS1,依次類(lèi)推.
如果是
USB轉(zhuǎn)串口的設(shè)備, 設(shè)備名前綴為ttyUSB, 第一串口為ttyUSB0.
3. 配置ttyUSB設(shè)備
[root@localhost ~]#minicom -s ttyUSB0
會(huì)出現(xiàn)一個(gè)configuration窗口,
┌──[configuration]────┐
│
Filenames and paths │
│
File transfer protocols │
│
Serial port setup │
│
Modem and dialing │
│
Screen and keyboard │
│
Save setup as ttyUSB0 │
│
Save setup as.. │
│
Exit │
│
Exit from Minicom │
└───────────────┘
選擇Serial port setup配置. 會(huì)出現(xiàn)如下窗口:
┌────────────────────────────────────────────┐
│
A -Serial Device : /dev/ttyUSB0 │
│
B -Lockfile Location : /var/lock │
│
C -Callin Program : │
│
D -Callout Program : │
│
E -Bps/Par/Bits : 115200 8N1 │
│
F -Hardware Flow Control : No │
│
G -Software Flow Control : No │
││
│
Change which setting? │
└───────────────────────────────────────────┘
我的設(shè)置如上所示, 設(shè)置完成后, Change which setting?項(xiàng)上按回車(chē)退出當(dāng)前窗口, 回到第一個(gè)窗口.按
Save
setup as ttyUSB0保存設(shè)置. 再按
Exit from Minicom退出
Minicom.
4. 啟動(dòng)minicom
[root@localhost ~]#minicom
3作者介紹
3.1策劃,組織,指導(dǎo),發(fā)布者
劉勇
email: littlegenius2008@163.com
如果您有新的內(nèi)容,請(qǐng)發(fā)到這個(gè)電子郵件,我們會(huì)把您的內(nèi)容加入文檔,并在作者列表中加入您的名字.
3.2 ADS bootloader部分
作者:劉勇
email:
littlegenius2008@163.com
3.3交叉工具部分
作者:孫賀
email:
msunhe@gmail.com
3.4 uboot部分
作者:聶強(qiáng)
email:
wolfwind9779@yahoo.com.cn
作者:孫賀
email:
msunhe@yahoo.com.cn
3.5內(nèi)核部分
作者:聶大鵬
email:dozec@mail.csdn.net
作者:牛須樂(lè)(8900a網(wǎng)卡移植部分)
email:clizniu@hotmail.com
3.6應(yīng)用程序部分
作者:聶大鵬
email:dozec@mail.csdn.net
3.7 Nand Flash 驅(qū)動(dòng)部分
作者:孫磊,劉勇
email:sunlei3448@yahoo.com.cn
第部分系統(tǒng)啟動(dòng) bootloader的編寫(xiě)(ADS)
1工具介紹
1.1 ADS命令行命令介紹
1.1.1 armasm
1. 命令:armasm [選項(xiàng)] -o 目標(biāo)文件源文件
2. 選項(xiàng)說(shuō)明
-Errors 錯(cuò)誤文件名
;指定一個(gè)錯(cuò)誤輸出文件
-I 目錄[,目錄](méi) ;指定源文件搜索目錄
-PreDefine 預(yù)定義宏
;指定預(yù)定義的宏
-NOCache ;編譯源代碼時(shí)禁止使用Cache進(jìn)行優(yōu)化
-MaxCache
-NOWarn ;關(guān)閉所有的警告信息
-G ;輸出調(diào)試表
-keep ;在目標(biāo)文件中保存本地符號(hào)表
-LIttleend ;生成小端(Little-endian) ARM代碼
-BIgend ;生成大端(Big-endian) ARM代碼
-CPU
-16 ;建立16位的thumb指令.
-32 ;建立32位的ARM指令.
3. 編譯一個(gè)匯編文件
c:\adsloader>armasm -LIttleend -cpu ARM920T -32 bdinit.s
把匯編語(yǔ)言編譯成小端, 32位, ARM920T CPU.
1.1.2 armcc, armcpp
1. 命令:armcc [選項(xiàng)] 源文件1 源文件2 ... 源文件n
2. 選項(xiàng)說(shuō)明
-c ;編譯但是不連接
-D ;指定一個(gè)編譯時(shí)使用的預(yù)定義宏常量
-E ;僅僅對(duì)
C源文件做預(yù)處理
-g ;產(chǎn)生調(diào)試信息表
-I ;指頭文件的搜索路徑
-o
-O[0/1/2] ;指定源代碼的優(yōu)化級(jí)別
-S ;輸出匯編代碼來(lái)代替目標(biāo)文件
-CPU
3.編譯一個(gè)C程序
c:\adsloader>armcc -c -O1 -cpu ARM920T bdisr.c
編譯不連接, 二級(jí)優(yōu)化, ARM920T CPU.
1.1.3 armlink
1. 命令:armlink [選項(xiàng)] 輸入文件
2. 選項(xiàng)說(shuō)明
-partial ;合并目標(biāo)文件
-Output 文件 ;指定輸出文件名
-scatter 文件 ;按照指定的文件為可執(zhí)行文件建立內(nèi)存映射
-ro-base 地址值
;只讀代碼段的起始地址
-rw-base 地址值
;RW/ZI段的起始地址
3. 把多個(gè)目標(biāo)文件合并成一個(gè)目標(biāo)文件
c:\adsloader>armlink -partial bdmain.o bdport.o bdserial.o bdmmu.o bdisr.o -o
bd.o
4. 把幾個(gè)目標(biāo)文件編譯一個(gè)可執(zhí)地文件
c:\adsloader>armlink bd.o bdinit.o -scatter bdscf.scf -o bd.axf
1.1.4 fromelf
1. 命令:fromelf [選項(xiàng)] 輸入文件
2. 選項(xiàng)說(shuō)明
-bin 二進(jìn)制文件名
;產(chǎn)生的二進(jìn)制文件
-elf elf文件名
;產(chǎn)生一個(gè)elf文件
-text text文件名
;產(chǎn)生text文件
3. 產(chǎn)生一個(gè)可執(zhí)行的二進(jìn)制代碼
c:\adsloader>fromelf.bd.axf.bin.o.bd.
bin
2基本原理
2.1可執(zhí)行文件組成及內(nèi)存映射
2.1.1可執(zhí)行文件的組成
在ADS下,可執(zhí)行文件有兩種,一種是.axf文件,帶有調(diào)試信息,可供AXD調(diào)試工具使用.另一種是.bin
文件,可執(zhí)行的二進(jìn)制代碼文件。我們重點(diǎn)是講描.bin文件的組成。
我們把可執(zhí)行文件分為兩種情況:分別為存放態(tài)和運(yùn)行態(tài)。
1. 存放態(tài)
存放態(tài)是指可執(zhí)行文件通過(guò)fromelf產(chǎn)生后,在存儲(chǔ)介質(zhì)(flash或磁盤(pán))上的分布. 此時(shí)可執(zhí)行文件一
般由兩部分組成:分別是代碼段和數(shù)據(jù)段。代碼段又分為可執(zhí)行代碼段(.text)和只讀數(shù)據(jù)段(.rodata),
數(shù)據(jù)段又分為初始化數(shù)據(jù)段(.data)和未初始化數(shù)據(jù)段(.bss)??蓤?zhí)行文件的存放態(tài)如下:
+-------------+----------|
.bss |
+-------------+--數(shù)據(jù)段
| .data |
+-------------+----------|
.rodata |
|_____________| 代碼段
| .text |
+-------------+----------
2. 運(yùn)行態(tài)
可執(zhí)行文件通過(guò)裝載過(guò)程, 搬入到RAM中運(yùn)行, 這時(shí)候可執(zhí)行文件就變成運(yùn)行態(tài)。在ADS下對(duì)可執(zhí)行代
碼各段有另一個(gè)名稱:
| ... |
+-------------+----------|
.bss | ZI 段
+-------------+--數(shù)據(jù)段
| .data | RW 段
+-------------+----------|
.rodata |
|_____________| 代碼段(RO 段)
| .text |
+-------------+----------|
... |
裝載前
當(dāng)可執(zhí)行文件裝載后, 在RAM中的分布如下:
| ... |
+-------------+-- ZI段結(jié)束地址
| ZI 段 |
+-------------+-- ZI段起始地址
| 保留區(qū)2 |
+-------------+-- RW段結(jié)束地址
| RW 段 |
+-------------+-- RW段起始地址
| 保留區(qū)1 |
+-------------+-- RO段結(jié)束地址
| RO 段 |
+-------------+-- RO段起始地址
| ... |
裝載后
所以裝載過(guò)程必須完成把執(zhí)行文件的各個(gè)段從存儲(chǔ)介質(zhì)上搬到RAM指定的位置。而這個(gè)裝載過(guò)程由誰(shuí)來(lái)完
成呢?由我們的啟動(dòng)程序來(lái)完成.
2.1.2裝載過(guò)程
在ADS中,可以通過(guò)兩種方式來(lái)指定可執(zhí)行代碼各段在RAM中的位置,一個(gè)是用armlink來(lái)指定,一種是
用scatter文件來(lái)指定.RAM區(qū)的起始地址:0x30000000.
1. armlink指定代碼段地址
我們通常的代碼,只用指定兩個(gè)段開(kāi)始地址, RO段的起始地址和RW段的起始地址, ZI段緊接在RW段之
后.示例見(jiàn)該部分的1.1.3.
2. scatter指定代碼段地址
我們也可以通過(guò)scatter文件指定可執(zhí)行文件各段的詳細(xì)地址. Scatter文件如下:
MYLOADER.0x30000000
;MYLOADER:為可執(zhí)行文件的名稱,.可自定義
;0x3000000:起始地址
{
RO.0x30000000
;RO只讀代碼段的名稱
;0x30000000:只讀代碼段的起始地址
{
init.o.(Init,.+First)
.....;.Init代碼段為可執(zhí)行文件的第一部分.
*.(+RO).;所有其它的代碼段和只讀數(shù)據(jù)段放在該部分
}
RW.+0
;RW:.RW段的名稱
;+0:表示
RW段緊接著
RO段
{
*.(+RW).;所有RW段放在該部分
}
ZI..+0
;ZI:.ZI段的名稱
;+0:表示
ZI段緊接著
RW段
{
*(+ZI).;所有ZI段放在該部分
}
}
3..ADS產(chǎn)生的各代碼段宏
|Image$$RO$$Base|./*.RO代碼段起始地址 */
|Image$$RO$$Limit|./*.RO代碼段結(jié)束地址 */
|Image$$RW$$Base|./*.RW代碼段起始地址 */
|Image$$RW$$Limit|./*.RW代碼段結(jié)束地址 */
|Image$$ZI$$Base|./*.ZI代碼段起始地址 */
|Image$$ZI$$Limit|./*.ZI代碼段結(jié)束地址 */
注意:在兩個(gè)$$之間的名稱,.與scatter中指定的段的名稱相同..
4..裝載過(guò)程說(shuō)明
當(dāng)從
NorFlash啟動(dòng)時(shí),.要把flash芯片的首地址映射到0x00000000位置,.系統(tǒng)啟動(dòng)后,.啟動(dòng)程序本身把自己從
flash中搬到RAM中運(yùn)行..搬移后的各段起始地址,.由以上宏來(lái)確定.
當(dāng)從
NandFlash啟動(dòng)時(shí),.S3C2410會(huì)自動(dòng)把前NandFlash的前4k搬到S3C2410的內(nèi)部RAM中,并把內(nèi)部
RAM的首地址設(shè)為0x00000000,CPU從
0x00000000開(kāi)始執(zhí)行..所以,.在nandFlash的前4k程序中,必須包含從
NandFlash把BootLoader的其余部分裝入RAM的程序.
2.1.3啟動(dòng)過(guò)程的匯編部分
當(dāng)系統(tǒng)啟動(dòng)時(shí),.ARM.CPU會(huì)跳到0x00000000去執(zhí)行。一般
BootLoader都包括如下幾個(gè)部分:
1..建立中斷向量異常表
2..顯示的切換到SVC且
32指令模式
3..關(guān)閉S3C2410的內(nèi)部看門(mén)狗
4..禁止所有的中斷
5..配置系統(tǒng)時(shí)鐘頻率和總線頻率
6..設(shè)置內(nèi)存區(qū)的控制寄存器
7..初始化中斷
8..安裝中斷向表量
9..把可執(zhí)行文件的各個(gè)段搬到運(yùn)行態(tài)的各個(gè)位置
10..跳到C代碼部分執(zhí)行
2.1.4啟動(dòng)過(guò)程的C部分
1..初始化MMU
2.初始化外部端口
3..中斷處理程序表初始化
4..串口初始化
5..其它部分初始化(可選)
6..主程序循環(huán)
3 AXD的使用以及源代碼說(shuō)明
3.1源代碼說(shuō)明
3.1.1匯編源代碼說(shuō)明
;===============================================================================
;引用頭文件
;===============================================================================
get bdinit.h
;===============================================================================
;引用標(biāo)準(zhǔn)變量
;===============================================================================
IMPORT |Image$$RO$$Base| ; Base address of RO section
IMPORT |Image$$RO$$Limit| ; End address of RO section
IMPORT |Image$$RW$$Base| ; Base address of RW section
IMPORT |Image$$RW$$Limit| ; End address of RW section
IMPORT |Image$$ZI$$Base| ; Base address of ZI section
IMPORT |Image$$ZI$$Limit| ; End addresss of ZI section
IMPORT bdmain ; The entry function of C program
;===============================================================================
;宏定義
;===============================================================================
; macro HANDLER
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;Decrement sp (to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack
ldr r0,=$HandleLabel;Load the address of HandleXXX to r0
ldr r0,[r0] ;Load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;Store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
;===============================================================================
;匯編語(yǔ)言的入口代碼
;===============================================================================
AREA Init,CODE,READONLY
CODE32
ENTRY
;=====================
; 建立中斷向量表
;=====================
b reset_handler ;0x00000000: Reset (SVC)
b undef_handler ;0x00000004: Undefined instruction (Undef)
b swi_handler ;0x00000008: Software Interrupt (SVC)
b iabr_handler ;0x0000000C: Instruction Abort (Abort)
b dabr_handler ;0x00000010: Data Abort (Abort)
b no_handler ;0x00000014:
b irq_handler ;0x00000018: IRQ (IRQ)
b fiq_handler ;0x0000001C: FIQ (FIQ)
LTORG
undef_handler HANDLER HandleUndef
swi_handler HANDLER HandleSWI
iabr_handler HANDLER HandlePabort
dabr_handler HANDLER HandleDabort
no_handler HANDLER HandleReserved
irq_handler HANDLER HandleIRQ
fiq_handler HANDLER HandleFIQ
;=============================
;復(fù)位時(shí)運(yùn)行的主程序
;=============================
reset_handler
;Set the cpu to SVC32 mode
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr_cxsf,r0
;Turn off watchdog
ldr r0,=WTCON
ldr r1,=0x0
str r1,[r0]
;Disable all the first level interrupts
ldr r0,=INTMSK
ldr r1,=0xffffffff
str r1,[r0]
;Disable all the second level interrupts
ldr r0,=INTSUBMSK
ldr r1,=0x7ff
str r1,[r0]
;Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
str r1,[r0]
;Set FCLK:HCLK:PCLK = 1:2:4
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
;Set memory control registers
ldrr0,=SMRDATA
;Fin=12MHz,Fout=200MHz
ldr r1,=BWSCON
add r2, r0, #52 ;End address of SMRDATA
0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne %B0
;Initialize stacks
bl InitStacks
;Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ
str r1,[r0]
;Copy RW/ZI section into RAM
ldr r0, =|Image$$RO$$Limit|;Get pointer to ROM data
ldr r1, =|Image$$RW$$Base| ;and RAM copy
ldr r3, =|Image$$ZI$$Base|
cmp r0, r1 ; Check that they are different
beq %F2
1
cmp r1, r3 ; Copy init data
ldrcc r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4
strcc r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4
bcc %B1
2
ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment
mov r2, #0
3
cmp r3, r1 ; Zero init
strcc r2, [r3], #4
bcc %B3
bl bdmain ;Jump to the main function
;Dead loop
1
nop
b %B1
;===============================================================================
;初始中斷處理程序
;===============================================================================
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
;===============================================================================
;初始化各個(gè)模式下堆棧
;===============================================================================
InitStacks
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack
mov pc,lr ;Return the call routine
LTORG
;===============================================================================
;內(nèi)存區(qū)控制寄存器值表;你可根據(jù)需要修改bdinit.h文件,.下面代碼不用做任何改動(dòng)
;===============================================================================
SMRDATA DATA
DCD
(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(
B7_BWSCON<<28))
DCD
((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD
((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD
((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD
((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD
((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD
((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7
ALIGN
;===============================================================================
;異常及中斷向量表空間;安裝異?;蛑袛嗵幚沓绦蛟赽disr.c中,isr_setup()來(lái)完成.
;===============================================================================
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ;表示下面數(shù)據(jù)區(qū)從_ISR_STARTADDRESS指定的位置開(kāi)始
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;=============================
;.The.Interrupt.table
;=============================
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
END
3.1.2 C語(yǔ)言源代碼說(shuō)明
void bdmain(void)
{
/* 禁止Cache 和MMU */
cache_disable();
mmu_disable();
/* 端口初始化 */
port_init();
/* 中斷處理程序 */
isr_init();
/* 串口初始化 */
serial_init(0, 115200);
/* 輸出信息進(jìn)行主循環(huán) */
serial_printf('is ok!\n');
while(1) {
}
}
通?;続DS的測(cè)試程序都可以在這個(gè)架構(gòu)上加入自己的代碼..
3.2 AXD的使用
3.2.1配置仿真器
1..為仿真器安裝Server
一般的仿真器都對(duì)應(yīng)有一個(gè)Server程序,所以在使用在線仿真之前,必須先安裝這個(gè)Server程序。我使用
是
DragonICE
仿真器,.所以先要安裝DragonICE.Server
程序。
2..連接仿真器
把dragonICE
仿真器的JTAG口連接上
ARM板(注意:ARM板要斷電連接),.另一端通過(guò)并口連接到PC上,
有的仿真器是通過(guò)USB口連接到PC上,.這與仿真器的硬件相關(guān)。連接好后,.打開(kāi)ARM電源,啟動(dòng)ARM板。
當(dāng)ARM通電啟動(dòng)后,啟動(dòng)DragonICE.Server
檢測(cè)ARM板,詳細(xì)步驟及設(shè)置參見(jiàn)對(duì)應(yīng)的仿真器手冊(cè)。我的
dragonICE.Server
啟動(dòng),.按”自動(dòng)檢測(cè)”可以檢測(cè)到ARM920T。
3.2.2啟動(dòng)AXD配置開(kāi)發(fā)板
1..啟動(dòng)AXD
先啟動(dòng)DragonICE.Server
程序.
按如下步聚啟動(dòng)AXD:
開(kāi)始>
所有程序>
ARM.Developer.Suite.v1.2>
AXD.Debugger
2..裝載仿真器庫(kù)文件
從
AXD菜單的Options>
.Configure.Target...啟動(dòng)”Choose.Target”目標(biāo)板配置窗口.
在”Choose.Target”窗口中,點(diǎn)擊”
Add”按鈕,選擇仿真器的庫(kù)文件..我的仿真器服務(wù)器程序安裝在
c:\DragonICE
下,所以選擇項(xiàng)
c:\DragonICE\
dragonice.
dll文件.
3..為AXD在線仿真配置仿真器
在'Target.Environments'中選中DragonICE
中,點(diǎn)擊右邊的'Configure'按鈕.
在”FJB.DragonICE.Release.v1.2”
窗口點(diǎn)擊'This.computer...'按鈕,再點(diǎn)擊'OK'按鈕。
回到”Choose.Target”窗口,點(diǎn)擊'OK'按鈕。完成配置.
回到主界面,.在右邊的”Target”窗口會(huì)出現(xiàn)
ARM920T_0.這表明AXD已經(jīng)進(jìn)入ARM板的在線仿真狀態(tài).
點(diǎn)擊菜單'System.Views'>'
Controls.Monitors'.會(huì)出現(xiàn)'ARM920TRegister'
窗口.此時(shí),會(huì)顯示當(dāng)前ARM板上所
有寄存器的狀態(tài)。
4..配置ARM板
如果
ARM板通電后,沒(méi)有程序運(yùn)行并把內(nèi)存區(qū)控制寄存器配置好的說(shuō),外部RAM是不能使用的..所以必須
通過(guò)仿真器來(lái)設(shè)置這些寄存器..如果
ARM板已經(jīng)有啟動(dòng)程序并且已經(jīng)配置好,.這一步可以省略.
首先把2410cfg.txt拷貝到c:\下.
回到AXD主界面,.從菜單”
System.Views”.>
.“Command.Line.Interface”。會(huì)出現(xiàn)一個(gè)Command.Line
Interface的調(diào)試命令行窗口,并顯示如下提示符:
Debug.>
輸入obey.c:\2410cfg.txt裝載所有配置命令.
Debug.>obey.c:\2410cfg.txt
5..2410cfg.txt文件說(shuō)明
sreg.psr,.0x00000013
;設(shè)置當(dāng)前CPSR的值,.把CPU的模式切換到SVC模式和32位指令集,.關(guān)閉IRQ和FIQ。
smem.0x53000000,0,32
;設(shè)置看門(mén)狗控制寄存器WTCON
;禁止看門(mén)狗定時(shí)器
smem.0x4C000004,((0x74<<12)+(0x3<<4)+0x1),32
;設(shè)置主頻率設(shè)置寄存器MPLLCON
;目前CPU的工作頻率FCLK是
124.00MHz
smem.0x4C000014,0x3,32
;設(shè)置時(shí)鐘分頻寄存器CLKDIVN
;設(shè)置FCLK/HCLK/PCLK.的頻率比例
1:2:4
smem.0x48000000,((2<<28)+(2<<24)+(1<<20)+(1<<16)+(1<<12)+(1<<8)+(1<<4)+0),32
;設(shè)置內(nèi)存總線控制BWSCON
;SDRAM.BANK.6&7.is.32位
;其它
BANK.is.16位
smem.0x48000004,((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+3),32
;設(shè)置寄存器區(qū)0控制寄存器:BANKCON0
smem.0x4800001c,((3<<15)+(1<<2)+1),32
;設(shè)置寄存器區(qū)6控制寄存器:.BANKCON6(SDRAM)
;RAS.to.CAS延時(shí)3.時(shí)鐘周期
;列地址是
9位
smem.0x48000020,((3<<15)+(1<<2)+1),32
;設(shè)置寄存器區(qū)7控制寄存器:.BANKCON7(SDRAM)
;RAS.to.CAS延時(shí) 3.時(shí)鐘周期
;列地址是
9位
smem.0x48000024,((1<<23)+(3<<18)+(2<<16)+1113),32
;set外部RAM刷新寄存器:REFRESH
;允許自刷新
;HCLK=FCLK/2,.60MHz,刷新計(jì)算器是
1113
smem.0x48000028,0x31,32
;設(shè)置寄存器的大小
;禁止burst操作
;允許
SDRAM.power.down模式
;SCLK在訪問(wèn)期間仍在活動(dòng)狀態(tài)
;SDRAM模式寄存器設(shè)置
smem.0x4800002c,0x30,32
smem.0x48000030,0x30,32
3.2.3使用AXD在線仿真調(diào)試程序
1..裝載可執(zhí)行的文件
AXD只支持.axf格式的可執(zhí)行文件.
啟動(dòng)AXD,.在菜單的File中,選擇Load.Image...,.選擇c:\adsbloadter\prj\prj_Data\DebugRel\prj.axf加載執(zhí)行
image..就可以執(zhí)行并調(diào)試了..AXD提供了非常方便的調(diào)試手段,.包括在線單步,.自由設(shè)置斷點(diǎn)等.
第三部分 GNU交叉工具鏈
1設(shè)置環(huán)境變量,準(zhǔn)備源碼及相關(guān)補(bǔ)丁
1.1設(shè)置環(huán)境變量
[arm@localhost arm]#vi.~/.bashrc
export.PREFIX=/usr/local/arm/3.4.4
export.TARGET=armlinux
export.SYSROOT=${PREFIX}/sysroot
export.ARCH=arm
export.CROSS_COMPILE=${TARGET}export.PATH=${
PREFIX}/bin:$PATH
export.SRC=/home/arm/dev_home/btools/tchain3.4.4
1. 2準(zhǔn)備源碼包
1.2.1 binuils
名稱:binutils2.16.
tar.gz
下載地址:http://ftp.gnu.org/gnu/binutils/binutils2.16.
tar.gz
1.2.2 gcc
名稱:gcc3.4.4.
tar.bz2
下載地址:http://ftp.gnu.org/gnu/gcc/gcc3.4.4/
gcc3.4.4.
tar.bz2
1.2.3 glibc
名稱:glibc2.3.5.
tar.gz
glibclinuxthreads2.3.5.
tar.gz
下載地址:
http://ftp.gnu.org/gnu/glibc/glibc2.3.5.
tar.gz
http://ftp.gnu.org/gnu/glibc/glibclinuxthreads2.3.5.
tar.gz
1.2.4 linux kernel
名稱:linux2.6.14.1.
tar.gz
下載地址:
http://ftp.kernel.org/pub/linux/kernel/v2.6/linux2.6.14.1.
tar.gz
1.3準(zhǔn)備補(bǔ)丁
1.3.1 ioperm.c.diff
作用:打修正
ioperm()函數(shù).
下載地址:http://frank.harvard.edu/~coldwell/toolchain/ioperm.c.diff
1.3.2 flow.c.diff
作用:該補(bǔ)丁用于產(chǎn)生crti.o和crtn.o文件。
下載地址:http://gcc.gnu.org/cgibin/
cvsweb.cgi/gcc/gcc/flow.c.diff?cvsroot=gcc&only_with_tag=cslarmbranch&
r1=1.563.4.2&r2=1.563.4.3
1.3.3 t-linux.diff
作用:修改gcc一處
bug
下載地址:http://frank.harvard.edu/~coldwell/toolchain/tlinux.
diff
1.4編譯 GNU binutils
重新以arm用戶登陸,讓新設(shè)置的環(huán)境變量起作用.
[arm@localhost.arm]#su.arm
[arm@localhost.arm]#cd.${SRC}
[arm@localhost.tchain3.4.4]#tar.xzvf.binutils2.16.
tar.gz
[arm@localhost.tchain3.4.4]#mkdir.p.BUILD/
binutils2.16
[arm@localhost.binutils2.16]#
cd.BUILD/binutils2.16
[arm@localhost.binutils2.16]#
.../../binutils2.16/
configure.prefix=${
PREFIX}.target=${
TARGET}.\
withsysroot=${
SYSROOT}
[arm@localhost.binutils2.16]#
make
[arm@localhost.binutils2.16]#
su.root
[root@localhost.binutils2.16]#
make.install
[root@localhost.binutils2.16]#
exit
[arm@localhost.binutils2.16]#
1.5準(zhǔn)備內(nèi)核頭文件
1.5.1使用當(dāng)前平臺(tái)的gcc編譯內(nèi)核頭文件
[arm@localhost tchain3.4.4]#cd.${KERNEL}
[arm@localhost.kernel]#tar.xvfz.linux2.6.14.1.
tar.gz
[arm@localhost.kernel]#cd..linux2.6.14.1
[arm@localhost.linux2.6.14.1]#
make.ARCH=arm.menuconfig
[arm@localhost.linux2.6.14.1]#
make
1.5.2復(fù)制內(nèi)核頭文件
[arm@localhost.kernel]#su.root
[root@localhost.kernel]#mkdir.p.${
SYSROOT}/usr/include
[root@localhost.kernel]#cp.a.include/
linux.${SYSROOT}/usr/include/linux
[root@localhost.kernel]#cp.a.include/
asmi386.${
SYSROOT}/usr/include/asm
[root@localhost.kernel]#cp.a.include/
asmgeneric.${
SYSROOT}/usr/include/asmgeneric
[root@localhost.kernel]#exit
[arm@localhost.kernel]#
1.6譯編glibc頭文件
[arm@localhost.kernel]#cd.${SRC}
[arm@localhost.chain3.4.4]#tar.xvfz.glibc2.3.5.
tar.gz
[arm@localhost.chain3.4.4]#patch.d.glibc2.3.5.p1.<
.ioperm.c.diff
[arm@localhost.glibc2.3.5]#
cd.glibc2.3.5
[arm@localhost.glibc2.3.5]#
tar.xvfz.../glibclinuxthreads2.3.5.
tar.gz
[arm@localhost.chain3.4.4]#cd...
[arm@localhost.chain3.4.4]#mkdir.BUILD/glibc2.3.5headers
[arm@localhost.chain3.4.4]#cd.BUILD/glibc2.3.5headers
[arm@localhost.glibc2.3.5headers]#../../
glibc2.3.5/
configure.prefix=/
usr.host=${
TARGET}.\
enableaddons=
linuxthreads.–withheaders=${
SYSROOT}/usr/include
[arm@localhost.glibc2.3.5headers]#
su.root
[root@localhost.glibc2.3.5headers]#
make.crosscompiling=
yes.install_root=${SYSROOT}.installheaders
[root@localhost.glibc2.3.5headers]#
touch.${SYSROOT}/usr/include/gnu/stubs.h.[root@localhost.glibc2.3.5headers]#
touch.${SYSROOT}/usr/include/bits/stdio_lim.h
[root@localhost.glibc2.3.5headers]#
exit
[arm@localhost.glibc2.3.5headers]#
注意:.prefix=/
usr.:是
gcc尋找?guī)斓乃阉髀窂健?/p>
1.7編譯gcc第一階段
[arm@localhost.glibc2.3.5headers]#
cd.${SRC}
[arm@localhost.chain3.4.4]#tar.xjvf.gcc3.4.4.
tar.bz2
[arm@localhost.chain3.4.4]#patch.d.gcc3.4.4.p1.<
.flow.c.diff
[arm@localhost.chain3.4.4]#patch.d.gcc3.4.4.p1.<
.tlinux.
diff
[arm@localhost.chain3.4.4]#mkdir.p.BUILD/
gcc3.4.4stage1
[arm@localhost.chain3.4.4]#cd.BUILD/gcc3.4.4stage1
[arm@localhost.gcc3.4.4stage1]#../../
gcc3.4.4/
configure.prefix=${
PREFIX}.target=${
TARGET}.\
enablelanguages=
c.withsysroot=${
SYSROOT}
注意:不能加上'disableshared'
選項(xiàng)。
[arm@localhost.gcc3.4.4stage1]#
make.allgcc
[arm@localhost.gcc3.4.4stage1]#
su.root
[root@localhost.gcc3.4.4stage1]#
make.installgcc
[root@localhost.gcc3.4.4stage1]#
exit
[arm@localhost.gcc3.4.4stage1]#
1.8編譯完整的glibc
[arm@localhost.gcc3.4.4stage1]
.#cd.${SRC}
[arm@localhost.tchain3.4.4]#mkdir.BUILD/glibc2.3.5
[arm@localhost.tchain3.4.4]#cd.BUILD/glibc2.3.5
[arm@localhost.glibc2.3.5]#
BUILD_CC=gcc.CC=${CROSS_COMPILE}gcc.AR=${CROSS_COMPILE}ar.\
RANLIB=${CROSS_COMPILE}ranlib.AS=${CROSS_COMPILE}as.LD=${CROSS_COMPILE}ld.\
../../glibc2.3.5/
configure.prefix=/
usr.build=
i386redhatlinux.host=
armunknownlinuxgnu.\
target=
armunknownlinuxgnu.without__
thread.enableaddons=
linuxthreads.\
withheaders=${
SYSROOT}/usr/include
說(shuō)明:
prefix:
指定安裝路徑。
target:
指定目標(biāo)平臺(tái)。
host:
指定當(dāng)前平臺(tái)。
build:
指定編譯平臺(tái)。
withsysroot:
用于指定編譯所需要的頭文件,及鏈接庫(kù)。
enableaddons:
加入其它的庫(kù),如線程庫(kù)等。
enablelanguages:
指定gcc所支持的語(yǔ)言。
[arm@localhost.glibc2.3.5]#
make
[arm@localhost.glibc2.3.5]#
su.root
[root@localhost.glibc2.3.5]#
make.install_root=${SYSROOT}.install
[root@localhost.glibc2.3.5]#
exit
[arm@localhost.glibc2.3.5]#
1.9編譯完整的gcc
[arm@localhost.glibc2.3.5]#
cd.${SRC}
[arm@localhost.tchain3.4.4]#mkdir.BUILD/gcc3.4.4
[arm@localhost.tchain3.4.4]#cd.BUILD/gcc3.4.4
[arm@localhost.gcc3.4.4]#../../
gcc3.4.4/
configure.prefix=${
PREFIX}.target=${
TARGET}.\
enablelanguages=
c.withsysroot=${
SYSROOT}
[arm@localhost.gcc3.4.4]#
make
[arm@localhost.gcc3.4.4]#
su.root
[root@localhost.gcc3.4.4]#
make.install
[root@localhost.gcc3.4.4]#
exit
[arm@localhost.gcc3.4.4]#
2 GNU交叉工具鏈的下載
2.1 ARM官方網(wǎng)站
工具鏈的官方下載地址:
http://www.arm.linux.org.uk....
可以從該站點(diǎn)下載2.95.3,.3.0以及3.2工具鏈
ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross2.95.3.
tar.bz2
ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross3.0.
tar.bz2
ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross3.2.
tar.bz2
3 GNU交叉工具鏈的介紹與使用
3.1常用工具介紹
名稱歸屬作用
armlinuxas
binutils編譯ARM匯編程序
armlinuxar
binutils把多個(gè).o合并成一個(gè).o或靜態(tài)庫(kù)(.a)
armlinuxranlib
binutils為庫(kù)文件建立索引,相當(dāng)于
armlinuxar.s
armlinuxld
binutils連接器(Linker),.把多個(gè).o或庫(kù)文件連接成一個(gè)可執(zhí)行文件
名稱歸屬作用
armlinuxobjdump
binutils查看目標(biāo)文件(.o)和庫(kù)(.a)的信息
armlinuxobjcopy
binutils轉(zhuǎn)換可執(zhí)行文件的格式
armlinuxstrip
binutils去掉elf可執(zhí)行文件的信息..使可執(zhí)行文件變小
armlinuxreadelf
binutils讀
elf可執(zhí)行文件的信息
armlinuxgcc
gcc編譯.c或.S開(kāi)頭的C程序或匯編程序
armlinuxg++
gcc編譯c++程序
3.2主要工具的使用
3.2.1 arm-linux-gcc的使用
1..編譯C文件,生成elf可執(zhí)行文件
h1.c源文件
#include.
void.hellofirst(void)
{
printf('The.first.hello!.\n');
}
h2.c源文件
#include.
void.hellosecond(void)
{
printf('The.second.hello!.\n');
}
hello.c源文件
#include.
void.hellosecond(void);
void.hellofirst(void);
int.main(int.argc,.char.*argv[])
{
hellofirst();
hellosecond();
return(0);
}
編譯以上
3個(gè)文件,有如下幾種方法:
方法1:
[arm@localhost.gcc]#armlinuxgcc.c.h1.
c
[arm@localhost.gcc]#armlinuxgcc.c.h2.
c
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.h1.o.h2.o
方法2:
[arm@localhost.gcc]#armlinuxgcc.c.h1.
c.h2.c
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.h1.o.h2.o
方法3:
[arm@localhost.gcc]#armlinuxgcc.c.o.h1.
o.h1.c
[arm@localhost.gcc]#armlinuxgcc.c.o.h1.
o.h1.c
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.h1.o.h2.o
方法4:
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.h1.c.h2.c
c:
只編譯不連接。
o:
編譯且連接。
2..產(chǎn)生一個(gè)預(yù)處理文件
當(dāng)要看一個(gè)宏在源文件中產(chǎn)生的結(jié)果時(shí),比較合適。
[arm@localhost.gcc]#armlinuxgcc.E.h1.
i.h1.c
E:
產(chǎn)生一個(gè)預(yù)處理文件.
3..產(chǎn)生一個(gè)動(dòng)態(tài)庫(kù)
動(dòng)態(tài)庫(kù)是在運(yùn)行時(shí)需要的庫(kù)。
[arm@localhost.gcc]#armlinuxgcc.c.fpic.h1.
c.h2.c
[arm@localhost.gcc]#armlinuxgcc.shared.h1.
o.h2.o.o.hello.
so
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.hello.so
把hello.so拷貝到目標(biāo)板的/lib目錄下,把可執(zhí)行文件拷貝目標(biāo)板的/tmp目錄下,在目標(biāo)板上運(yùn)行hello.
#/tmp/hello
或把hello.so和hello一起拷貝到/tmp目標(biāo)下,并設(shè)置LD_LIBRARY_PATH環(huán)境變量
#export.LD_LIBRARY_PATH.=/tmp:$LD_LIBRARY_PATH
#/tmp/hello
3.2.2 arm-linux-ar和 arm-linux-ranlib的使用
靜態(tài)庫(kù)是在編譯時(shí)需要的庫(kù)。
1..建立一個(gè)靜態(tài)庫(kù)
[arm@localhost.gcc]#armlinuxar.r.libhello.
a.h1.o.h2.o
2..為靜態(tài)庫(kù)建立索引
[arm@localhost.gcc]#armlinuxar.s.libhello.
a
[arm@localhost.gcc]#armlinuxranlib.libhello.
a
3..由靜態(tài)庫(kù)產(chǎn)生可執(zhí)行文件
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.lhello.L./
[arm@localhost.gcc]#armlinuxgcc.o.hello.hello.
c.libhello.a
hello文件可以直接拷貝到/tmp目錄下運(yùn)行,不需
libhello.a.
3.2.3 arm-linux-objdump的使用
1..查看靜態(tài)庫(kù)或.o文件的組成文件
[arm@localhost.gcc]$.armlinuxobjdump.a.libhello.
a
2..查看靜態(tài)庫(kù)或.o文件的絡(luò)組成部分的頭部分
[arm@localhost.gcc]$.armlinuxobjdump.h.libhello.
a
3..把目標(biāo)文件代碼反匯編
[arm@localhost.gcc]$.armlinuxobjdump.d.libhello.
a
3.2.4 arm-linux-readelf的使用
1..讀
elf文件開(kāi)始的文件頭部
[arm@localhost.gcc]$.armlinuxreadelf.h.hello
ELF.Header:
Magic:...7f.45.4c.46.01.01.01.61.00.00.00.00.00.00.00.00
Class:
Data:
Version:
OS/ABI:
ABI.Version:
Type:
Machine:
Version:
Entry.point.address:
Start.of.program.headers:
Start.of.section.headers:
Flags:
Size.of.this.header:
Size.of.program.headers:
.....................................ELF32
......................................2's.complement,.little.endian
................................1.(current)
................................ARM
0
.....................................EXEC.(Executable.file)
................................ARM
0x1
0x82b4
......52.(bytes.into.file)
........10240.(bytes.into.file)
.....................................0x2,.has.entry.point
................52.(bytes)
.......32.(bytes)
Number.of.program.headers:.6
Size.of.section.headers:..........40.(bytes)
Number.of.section.headers:.28
Section.header.string.table.index:.25
2..讀
elf文件中所有ELF的頭部:
[arm@localhost.gcc]#armlinuxreadelf.e.hello
......
3..顯示整個(gè)文件的符號(hào)表
[arm@localhost.gcc]#armlinuxreadelf.s.hello
......
4..顯示使用的動(dòng)態(tài)庫(kù)
[arm@localhost.gcc]#armlinuxreadelf.d.hello
......
3.2.5 arm-linux-strip的使用
1..移除所有的符號(hào)信息
[arm@localhost.gcc]#cp.hello.hello1
[arm@localhost.gcc]#armlinuxstrip.stripall.hello
stripall:
是移除所有符號(hào)信息
[arm@localhost.gcc]#ll
rwxrxrx..1.arm.root.2856.7
月
3.15:14.hello
rwxrxrx..1.arm.root.13682..7
月
3.15:13.hello1
被
strip后的hello程序比原來(lái)的hello1程序要小很多。
2..移除調(diào)試符號(hào)信息
[arm@localhost.gcc]#armlinuxstrip.g.hello
[arm@localhost.gcc]#ll
rwxrxrx..1.arm.root.4501.7
月
3.15:17.hello
rwxrxrx..1.arm.root.13682..7
月
3.15:13.hello1
3.2.6 arm-linux-copydump的使用
生成可以執(zhí)行的2進(jìn)制代碼
[arm@localhost.gcc]#armlinuxcopydump.O.binary.hello.hello.
bin
4 ARM GNU常用匯編語(yǔ)言介紹
4.1 ARM GNU常用匯編偽指令介紹
1..abort
.abort:停止匯編
.align.ab***pr1,
.ab***pr2:
以某種對(duì)齊方式,在未使用的存儲(chǔ)區(qū)域填充值..第一個(gè)值表示對(duì)齊方式,4,.8,16或
32..第
二個(gè)表達(dá)式值表示填充的值.
2..if...else...endif
.if
.else
.endif:支持條件預(yù)編譯
3..include
.include.'file':包含指定的頭文件,.可以把一個(gè)匯編常量定義放在頭文件中.
4..comm
.comm.symbol,.length:在bss段申請(qǐng)一段命名空間,該段空間的名稱叫
symbol,.長(zhǎng)度為length...Ld連接器在連接會(huì)
為它留出空間.
5..data
.data.subsection:說(shuō)明接下來(lái)的定義歸屬于
subsection數(shù)據(jù)段.
6..equ
.equ.symbol,.expression:把某一個(gè)符號(hào)(symbol)定義成某一個(gè)值(expression).該指令并不分配空間.
7..global
.global.symbol:定義一個(gè)全局符號(hào),.通常是為ld使用.
8..ascii
.ascii.'string':定義一個(gè)字符串并為之分配空間.
9..byte
.byte.expressions:定義一個(gè)字節(jié),.并為之分配空間.
10..short
.short.expressions:定義一個(gè)短整型,.并為之分配空間.
11..int
.int.expressions:定義一個(gè)整型,并為之分配空間.
12.long
.long.expressions:定義一個(gè)長(zhǎng)整型,.并為之分配空間.
13.word
.word.expressions:定義一個(gè)字,并為之分配空間,.4bytes.
14..macro/endm
.macro:定義一段宏代碼,..macro表示代碼的開(kāi)始,..endm表示代碼的結(jié)束.
15..req
name..req.register.name:為寄存器定義一個(gè)別名.
16..code
.code.[16|32]:指定指令代碼產(chǎn)生的長(zhǎng)度,.16表示
Thumb指令,.32表示
ARM指令.
17..ltorg
.ltorg:表示當(dāng)前往下的定義在歸于當(dāng)前段,并為之分配空間.
4.2 ARM GNU專(zhuān)有符號(hào)
1..@
表示注釋從當(dāng)前位置到行尾的字符.
2..#
注釋掉一整行.
3..;
新行分隔符.
4.3操作碼
1..NOP
nop
空操作,.相當(dāng)于
MOV.r0,.r0
2..LDR
ldr.
相當(dāng)于
PC寄存器或其它寄存器的長(zhǎng)轉(zhuǎn)移.
3.ADR
adr.
ADRL
adrl.
5可執(zhí)行生成說(shuō)明
5.1 lds文件說(shuō)明
5.1.1主要符號(hào)說(shuō)明
1..OUTPUT_FORMAT(bfdname)
指定輸出可執(zhí)行文件格式.
2.
.
OUTPUT_ARCH(bfdname)
指定輸出可執(zhí)行文件所運(yùn)行CPU平臺(tái)
3..ENTRY(symbol)
指定可執(zhí)行文件的入口段
5.1.2段定義說(shuō)明
1.
.
段定義格式
SECTIONS.{....
段名
:.{
內(nèi)容
}
...
}
5.1.3.uboot.
lds文件說(shuō)明
OUTPUT_FORMAT('elf32littlearm',
.'elf32littlearm',
.'elf32littlearm')
;指定輸出可執(zhí)行文件是
elf格式,32位
ARM指令,小端
OUTPUT_ARCH(arm)
;指定輸出可執(zhí)行文件的平臺(tái)為ARM
ENTRY(_start)
;指定輸出可執(zhí)行文件的起始代碼段為_(kāi)start.
SECTIONS
{
..=.0x00000000..;從
0x0位置開(kāi)始
..=.ALIGN(4).;代碼以4字節(jié)對(duì)齊
.text.:.;指定代碼段
{
cpu/arm920t/start.o..(.text).;代碼的第一個(gè)代碼部分
*(.text).;其它代碼部分
}
..=.ALIGN(4)
.rodata.:.{.*(.rodata).}.;指定只讀數(shù)據(jù)段
..=.ALIGN(4);
.data.:.{.*(.data).}.;指定讀/寫(xiě)數(shù)據(jù)段
..=.ALIGN(4);
.got.:.{.*(.got).}.;指定got段,.got段式是
uboot自定義的一個(gè)段,.非標(biāo)準(zhǔn)段
__u_boot_cmd_start.=...;把__u_boot_cmd_start賦值為當(dāng)前位置,.即起始位置
.u_boot_cmd.:.{.*(.u_boot_cmd).}.;指定u_boot_cmd段,.uboot把所有的uboot命令放在該段.
__u_boot_cmd_end.=..;把__u_boot_cmd_end賦值為當(dāng)前位置,即結(jié)束位置
..=.ALIGN(4);
__bss_start.=..;把__bss_start賦值為當(dāng)前位置,即
bss段的開(kāi)始位置
.bss.:.{.*(.bss).};指定bss段
_end.=..;把_end賦值為當(dāng)前位置,即
bss段的結(jié)束位置
}
第四部分 u-boot的移植
1 u-boot的介紹及系統(tǒng)結(jié)構(gòu)
1.1 u-boot介紹
Uboot
是德國(guó)
DENX小組的開(kāi)發(fā)用于多種嵌入式CPU的bootloader程序,.UBoot
不僅僅支持嵌入式Linux
系統(tǒng)的引導(dǎo),當(dāng)前,它還支持NetBSD,.VxWorks,.QNX,.RTEMS,.ARTOS,.LynxOS嵌入式操作系統(tǒng)。UBoot
除
了支持PowerPC系列的處理器外,還能支持MIPS、
x86、ARM、NIOS、XScale等諸多常用系列的處理器。
1.2獲取u-boot
以u(píng)boot用戶登陸.
[uboot@localhost.~]#mkdir.p.dev_
home/uboot
[uboot@localhost.~]#cd.dev_home/uboot
從下面地址下載uboot
的源代碼。
http://sourceforge.net/projects/uboot
[uboot@localhost.uboot]#tar.xjvf.uboot1.1.4.
tar.bz2
[uboot@localhost.uboot]#cd.uboot1.1.4
1.3 u-boot體系結(jié)構(gòu)
1.3.1 u-boot目錄結(jié)構(gòu)
1..目錄樹(shù)
[uboot@localhost.uboot1.1.4]#
tree.L.1.d
.
|board
|common
|cpu
|disk
|doc
|drivers
|dtt
|examples
|fs
|include
|lib_
arm
|lib_
generic
|lib_
i386
|lib_
m68k
|lib_
microblaze
|lib_
mips
|lib_
nios
|lib_
nios2
|lib_
ppc
|net
|post
|rtc
`tools
2..board:和一些已有開(kāi)發(fā)板有關(guān)的文件..每一個(gè)開(kāi)發(fā)板都以一個(gè)子目錄出現(xiàn)在當(dāng)前目錄中,比如說(shuō):SMDK2410,
子目錄中存放與開(kāi)發(fā)板相關(guān)的配置文件.
3..common:實(shí)現(xiàn)
uboot
命令行下支持的命令,每一條命令都對(duì)應(yīng)一個(gè)文件。例如
bootm命令對(duì)應(yīng)就是
cmd_bootm.c。
4..cpu:與特定CPU架構(gòu)相關(guān)目錄,每一款
Uboot
下支持的CPU在該目錄下對(duì)應(yīng)一個(gè)子目錄,比如有子目錄
arm920t等。
5..disk:對(duì)磁盤(pán)的支持。
5..doc:文檔目錄。Uboot
有非常完善的文檔,推薦大家參考閱讀。
6..drivers:Uboot
支持的設(shè)備驅(qū)動(dòng)程序都放在該目錄,比如各種網(wǎng)卡、支持CFI的Flash、串口和USB等。
7..fs:支持的文件系統(tǒng),Uboot
現(xiàn)在支持cramfs、fat、fdos、jffs2和registerfs。
8..include:Uboot
使用的頭文件,還有對(duì)各種硬件平臺(tái)支持的匯編文件,系統(tǒng)的配置文件和對(duì)文件系統(tǒng)支持的
文件。該目錄下configs目錄有與開(kāi)發(fā)板相關(guān)的配置頭文件,如
smdk2410.h。該目錄下的asm目錄有與CPU體
系結(jié)構(gòu)相關(guān)的頭文件,asm對(duì)應(yīng)的是
asmarm.
9..lib_xxxx:與體系結(jié)構(gòu)相關(guān)的庫(kù)文件。如與ARM相關(guān)的庫(kù)放在lib_arm中。
10..net:與網(wǎng)絡(luò)協(xié)議棧相關(guān)的代碼,BOOTP協(xié)議、TFTP協(xié)議、RARP協(xié)議和NFS文件系統(tǒng)的實(shí)現(xiàn)。
11..tools:生成Uboot
的工具,如:mkimage,.crc等等。
2 uboot的啟動(dòng)過(guò)程及工作原理
2.1啟動(dòng)模式介紹
大多數(shù) Boot.Loader都包含兩種不同的操作模式:'啟動(dòng)加載'模式和'下載'模式,這種區(qū)別僅對(duì)于開(kāi)發(fā)人
員才有意義。但從最終用戶的角度看,Boot.Loader的作用就是用來(lái)加載操作系統(tǒng),而并不存在所謂的啟動(dòng)加
載模式與下載工作模式的區(qū)別。
啟動(dòng)加載(Boot.loading)模式:這種模式也稱為'自主'(Autonomous)模式。也即
Boot.Loader從目標(biāo)機(jī)
上的某個(gè)固態(tài)存儲(chǔ)設(shè)備上將操作系統(tǒng)加載到 RAM中運(yùn)行,整個(gè)過(guò)程并沒(méi)有用戶的介入。這種模式是
Boot
Loader的正常工作模式,因此在嵌入式產(chǎn)品發(fā)布的時(shí)侯,Boot.Loader顯然必須工作在這種模式下。
下載(Downloading)模式:在這種模式下,目標(biāo)機(jī)上的 Boot.Loader將通過(guò)串口連接或網(wǎng)絡(luò)連接等通信手
段從主機(jī)(Host)下載文件,比如:下載內(nèi)核映像和根文件系統(tǒng)映像等。從主機(jī)下載的文件通常首先被
Boot
Loader保存到目標(biāo)機(jī)的 RAM中,然后再被
BootLoader寫(xiě)到目標(biāo)機(jī)上的FLASH.類(lèi)固態(tài)存儲(chǔ)設(shè)備中。Boot
Loader的這種模式通常在第一次安裝內(nèi)核與根文件系統(tǒng)時(shí)被使用;此外,以后的系統(tǒng)更新也會(huì)使用 Boot
Loader的這種工作模式。工作于這種模式下的 Boot.Loader通常都會(huì)向它的終端用戶提供一個(gè)簡(jiǎn)單的命令
行接口。
UBoot
這樣功能強(qiáng)大的 Boot.Loader同時(shí)支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進(jìn)行
切換。
大多數(shù)bootloader都分為階段1(stage1)和階段2(stage2)兩大部分,uboot
也不例外。依賴于
CPU體系結(jié)構(gòu)
的代碼(如
CPU初始化代碼等)通常都放在階段1中且通常用匯編語(yǔ)言實(shí)現(xiàn),而階段2則通常用C語(yǔ)言來(lái)實(shí)
現(xiàn),這樣可以實(shí)現(xiàn)復(fù)雜的功能,而且有更好的可讀性和移植性。
2.2階段1介紹
uboot
的stage1代碼通常放在start.s文件中,它用匯編語(yǔ)言寫(xiě)成,其主要代碼部分如下:
2.2.1定義入口
由于一個(gè)可執(zhí)行的Image必須有一個(gè)入口點(diǎn),并且只能有一個(gè)全局入口,通常這個(gè)入口放在ROM(Flash)的0x0
地址,因此,必須通知編譯器以使其知道這個(gè)入口,該工作可通過(guò)修改連接器腳本來(lái)完成。
1..board/crane2410/uboot.
lds:..ENTRY(_start)...==>.cpu/arm920t/start.S:..globl._start
2..uboot代碼區(qū)(TEXT_BASE.=.0x33F80000)定義在board/crane2410/config.mk
2.2.2設(shè)置異常向量
_start: b reset @ 0x00000000
ldr pc, _undefined_instruction @ 0x00000004
ldr pc, _software_interrupt @ 0x00000008
ldr pc, _prefetch_abort @ 0x0000000c
ldr pc, _data_abort @ 0x00000010
ldr pc, _not_used @ 0x00000014
ldr pc, _irq @ 0x00000018
ldr pc, _fiq @ 0x0000001c
當(dāng)發(fā)生異常時(shí),執(zhí)行cpu/arm920t/interrupts.c中定義的中斷處理函數(shù)。
2.2.3設(shè)置CPU的模式為SVC模式
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
2.2.4關(guān)閉看門(mén)狗
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ldr r0, =pWTCON
mov r1, #0x0 @ 根據(jù)三星手冊(cè)進(jìn)行調(diào)置。
str r1, [r0]
2.2.5禁掉所有中斷
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
2.2.6設(shè)置以CPU的頻率
默認(rèn)頻率為 FCLK:HCLK:PCLK = 1:2:4,默認(rèn)FCLK的值為120 MHz,該值為S3C2410手冊(cè)的推薦值。
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
2.2.7設(shè)置CP15
設(shè)置CP15,.失效指令(I)Cache和數(shù)據(jù)(D)Cache后,.禁止MMU與Cache。
cpu_init_crit:
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* 失效 I/D cache, 見(jiàn) S3C2410手冊(cè)附錄的 2-16 */
mcr p15, 0, r0, c8, c7, 0 /* 失效 TLB, 見(jiàn) S3C2410手冊(cè)附錄的 2-18 */
/*
* 禁止 MMU 和caches, 詳見(jiàn)S3C2410手冊(cè)附錄2-11
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 /* 清除 bits 13, 9:8 (--V- --RS)
* Bit 8: Disable System Protection
* Bit 7: Disable ROM Protection
* Bit 13: 異常向量表基地址: 0x0000 0000
*/
bic r0, r0, #0x00000087 /* 清除 bits 7, 2:0 (B--- -CAM)
* Bit 0: MMU disabled
* Bit 1: Alignment Fault checking disabled
* Bit 2: Data cache disabled
* Bit 7: 0 = Little-endian operation
*/
orr r0, r0, #0x00000002 /* set bit 2 (A) Align, 1 = Fault checking enabled */
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache, 1 = Instruction cache enabled
*/
mcr p15, 0, r0, c1, c0, 0
2.2.8配置內(nèi)存區(qū)控制寄存器
配置內(nèi)存區(qū)控制寄存器,寄存器的具體值通常由開(kāi)發(fā)板廠商或硬件工程師提供..如果您對(duì)總線周期及外圍
芯片非常熟悉,.也可以自己確定,.在UBOOT
中的設(shè)置文件是
board/crane2410/lowlevel_init.S,.該文件包含
lowleve_init程序段..詳細(xì)寄存器設(shè)置及值的解釋見(jiàn)
3.2.2.啟動(dòng)AXD配置開(kāi)發(fā)板一節(jié)中的第5點(diǎn).
mov ip, lr
bl lowlevel_init
mov lr, ip
2.2.9安裝U-BOOT使的棧空間
下面這段代碼只對(duì)不是從
Nand.Flash啟動(dòng)的代碼段有意義,對(duì)從
Nand.Flash啟動(dòng)的代碼,沒(méi)有意義。因?yàn)?br style='margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; '>從
Nand.Flash中把UBOOT執(zhí)行代碼搬移到RAM,由
2.1.9中代碼完成..
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
...
#endif
stack_setup:
ldr r0, _TEXT_BASE /* 代碼段的起始地址 */
sub r0, r0, #CFG_MALLOC_LEN/* 分配的動(dòng)態(tài)內(nèi)存區(qū) */
sub r0, r0, #CFG_GBL_DATA_SIZE /* UBOOT開(kāi)發(fā)板全局?jǐn)?shù)據(jù)存放 */
#ifdef CONFIG_USE_IRQ/* 分配IRQ和FIQ??臻g */
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* 留下3個(gè)字為Abort */
2.2.10 BSS段清0
clear_bss:
ldr r0, _bss_start/* BSS段的起始地址 */
ldr r1, _bss_end/* BSS段的結(jié)束地址 */
mov r2, #0x00000000/* BSS段置0 */
clbss_l:str r2, [r0]/* 循環(huán)清除BSS段 */
add r0, r0, #4
cmp r0, r1
ble clbss_l
2.2.11搬移Nand Flash代碼
從
Nand.Flash中,.把數(shù)據(jù)拷貝到RAM,.是由
copy_myself程序段完成,.該程序段詳細(xì)解釋見(jiàn):第七部分的3.1節(jié).
#ifdef CONFIG_S3C2410_NAND_BOOT
bl copy_myself
@ jump to ram
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1: b 1b @ infinite loop
on_the_ram:
#endif
2.2.12進(jìn)入C代碼部分
ldr pc, _start_armboot
_start_armboot: .word start_armboot
2.3階段2的C語(yǔ)言代碼部分
lib_arm/board.c中的start.armboot是
C語(yǔ)言開(kāi)始的函數(shù),也是整個(gè)啟動(dòng)代碼中C語(yǔ)言的主函數(shù),同時(shí)還是整個(gè)
uboot(
armboot)的主函數(shù),該函數(shù)主要完成如下操作:
2.3.1調(diào)用一系列的初始化函數(shù)
1..指定初始函數(shù)表:
init_fnc_t *init_sequence[] = {
cpu_init,
board_init,
interrupt_init,
env_init,
init_baudrate,
serial_init,
console_init_f,
display_banner,
dram_init,
display_dram_config,
/* cpu的基本設(shè)置 */
/* 開(kāi)發(fā)板的基本初始化 */
/* 初始化中斷 */
/* 初始化環(huán)境變量 */
/* 初始化波特率 */
/* 串口通訊初始化 */
/* 控制臺(tái)初始化第一階段 */
/* 通知代碼已經(jīng)運(yùn)行到該處 */
/* 配制可用的內(nèi)存區(qū) */
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)
checkboard,
#endif
NULL,
};
執(zhí)行初始化函數(shù)的代碼如下:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
2..配置可用的Flash區(qū)
flash_init ()
3..初始化內(nèi)存分配函數(shù)
mem_malloc_init()
4..nand.flash初始化
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ('NAND:');
nand_init();/* 初始化 NAND */
見(jiàn)第七部分3.2.3 節(jié)中的第3點(diǎn)nand_init()函數(shù).
5..初始化環(huán)境變量
env_relocate.();
6.
.
外圍設(shè)備初始化
devices_init()
7..I2C總線初始化
i2c_init();
8..LCD初始化
drv_lcd_init();
9..VIDEO初始化
drv_video_init();
10..鍵盤(pán)初始化
drv_keyboard_init();
11..系統(tǒng)初始化
drv_system_init();
2.3.2初始化網(wǎng)絡(luò)設(shè)備
初始化相關(guān)網(wǎng)絡(luò)設(shè)備,填寫(xiě)IP、MAC地址等。
1..設(shè)置IP地址
/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ('ipaddr');
/* MAC Address */
{
int i;
ulong reg;
char *s, *e;
uchar tmp[64];
i = getenv_r ('ethaddr', tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL;
for (reg = 0; reg < 6; ++reg) {
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
}
2.3.3進(jìn)入主UBOOT命令行
進(jìn)入命令循環(huán)(即整個(gè)boot的工作循環(huán)),接受用戶從串口輸入的命令,然后進(jìn)行相應(yīng)的工作。
for (;;) {
main_loop (); /* 在common/main.c */
}
聯(lián)系客服