Bootstrap的啟動過程
一、 說明:
Bootstrap啟動代碼是官方提供的一級啟動代碼,包括匯編和C語言兩部分組成。對AT91SAM9260來說編譯完成后,代碼長度必須小於4KB,燒寫到dataflash中的0x00000000.
二、系統上電准備Bootstrap啟動。
當系統啟動選擇片內啟動(BMS=1)時,程序上電后,啟動內部ROM的的固化程序,自動將檢測dataflash中前48個字節的數據,如果數據正確,說明是Bootstrap啟動代碼。這時候系統自動將存在flashdta中的Bootstrap啟動代碼搬到SRAM0中去,接下來就進行存儲器的REMAP,經過remap后,SRAM0從映射前的0x200000地址被映射到了0x000000地址並且程序從此處開始執行。
三、Bootstrap匯編啟動過程
1、建立中斷向量表。
2、設置堆棧SP的值。
3、主晶振使能為主時鍾。
4、數據段的拷貝。
5、對零初始化的數據進行初始化。
6,跳轉到C語言main函數。
四、BootstrapC語言初始化過程
1、關閉看門狗。
writel(AT91C_WDTC_WDDIS, AT91C_BASE_WDTC + WDTC_WDMR);
2、配置PLLA時鍾
pmc_cfg_plla(PLLA_SETTINGS, PLL_LOCK_TIMEOUT);
3、配置MCK時鍾
pmc_cfg_mck(MCKR_SETTINGS, PLL_LOCK_TIMEOUT);
4、配置PLLB時鍾
pmc_cfg_pllb(PLLB_SETTINGS, PLL_LOCK_TIMEOUT);
5、配置CP15協處理器
6、配置PIO控制器
pio_setup(hw_pio);
7、配置外部總線接口EBI
writel((readl((AT91C_BASE_MATRIX+MATRIX_SCFG3))&~0xFF)|0x40,(AT91C_BASE_MATRIX+MATRIX_SCFG3));
8、初始化總線矩陣。
writel(readl(AT91C_BASE_CCFG + CCFG_EBICSA) | AT91C_EBI_CS1A_SDRAMC, AT91C_BASE_CCFG + CCFG_EBICSA);
9、配置SDRAM控制器
sdram_init(…….)
10、dataflash的SPI初始化
df_spi_init(pcs, DF_CS_SETTINGS);
11、dataflash的復原初始化
df_recovery(pDf);
12、將dataflash中以0x8400開始的連續0x80000字節的數據搬移到SDRAM中以0x23F00000為起始地址處。
df_download(pDf, img_addr, img_size, img_dest);
13、程序最后跳轉到0x23F00000處在sdram中運行K2CMSTART程序代碼。
注意:K2CMSTART程序代碼是真正的要運行的程序,存在dataflash中以0x8400開始的連續0x80000字節。是我們自己要正真編寫的程序。下面提到這程序中的函數變量都是以一個K2CMSTART程序例子來說的。
五、程序應用
該部分BOOT程序為系統的一級啟動程序,完成最低層最基本的硬件初始化,為進入到上一級程序進行引導。
AT91sam9260上電后,啟動內部ROM的的固化程序,按照dataflash、nandflash的順序依次來找合法的BOOT程序。所謂合法的指的是在這些存儲設備的開始地址處連續的存放的32個字節,也就是8條指令必須是跳轉指令或者裝載PC的指令,其實這樣規定就是把這8條指令當作是異常向量表來處理。必須注意的是第6條指令要包含將要裝載的映像的大小。一旦合法的映像找到之后,則固化程序會把找到的映像搬到SRAM中去,所以映像的大小是非常有限的,不能超過4K的大小。當固化程序完成了把合法的映像搬到SRAM的任務以后,接下來就進行存儲器的REMAP,經過REMAP之后,SRAM從映設前的0X200000地址處被映設到了0X0地址並且程序從0X0處開始執行。
上電后,我們一般把存儲在dataflash中的bootstrap 映像搬移到sram中,bootstrap 完成一些靜態初始化工作, 如PMCS,PIOs,再把第二級的K2CMSTART引導程序從dataflash中搬移到sdram中運行。
雖然是BOOT程序,但由於受到內部4KB的SRAM的限制,程序不能實現太多功能,比如進行人機交互操作,查看系統內部某些數據,更新程序軟件、更新數據等。當然在保證有足夠的SRAM空間的前提下,增加一個串口,進行簡單的輸入輸出信息查看還是可以的,但這也相對沒什么意義。但我們如果真要進行復雜的人機交互操作的話,肯定要進入二級引導程序K2CMSTART里進行。
K2CMSTART的啟動過程
一、 匯編啟動代碼
1、 建立中斷向量表。
2、 將此中斷向量表函數。(根據Scatter里的數據段的定義調用系統函數完成數據段的搬移)
二、C語言函數代碼。
3、 1、調用BoardVolMa拷貝到內部SRAM中0X200000起始處。
4、 設置7種異常模式下的堆棧區。
5、 進入低級初始化函數AT91F_LowLevelInit(void)。
程序進入C語言的__mainnageIni()初始化
2、調用ARMTargetInit()初始化硬件
3、調用InitLoadFile()初始化下載文件。
4、循環中調用ReadSmcSoftVolFromScb()函數,超時退出循環
5、主程序主循環中,調用DrvRunLedFlash(100,100,100)函數LED燈閃爍。
6、主程序主循環中,調用MainMenu()函數中的Loadfile()下的net_handle()函數,通過UDP/IP協議傳過來的數據進行判別執行相應的操作和更新。
6.1通過arp_rcv_packet()函數對上位機ARP包進行處理;
6.2通過ip_rcv_packet ()函數對上位機IP包進行處理;
6.2.1通過icmp_rcv_packet ()函數對上位機的ICMP網間控制報文協議進行處理;
6.2.2通過udp_rcv_packet ()函數對UDP協議包數據處理;
6.2.2.1用戶利用上位機通過TFTP協議可以讀取系統的參數信息,也可以更改系統的參數信息。
tftp_rcv_packet()函數實現具體操作,實現對文件的讀寫操作。tftp_rcv_wrq(struct sk_buff *skb)函數接收三個參數文件到緩沖區;tftp_rcv_rrq(struct sk_buff *skb)函數根據人機交互的命令要求讀三個參數文件。
6.2.2.2用戶利用上位機通過CCTP協議(端口號=2800)接收命令執行相應的操作。
cctp_rcv_data()函數實現具體操作。
6.2.2.3用戶利用上位機通過端口號=2002接收命令執行相應的操作。
AsyCmd_Rcv_Data()函數實現具體操作。
7、主程序主循環中,調用MainMenu()函數中的RcvCctpOptCmdDeal()函數,根據判斷結構體變量S_CctpRxBuf來執行操作。
7.1當((S_CctpRxBuf.buf[0]==0x1b)&&(S_CctpRxBuf.buf[2]==0x4d)時,進入JumpToApp_menu()函數時,執行read_dataflash( 0xd0088400,512*1024,0x23e00000 )函數,將dataflash中的應用程序(以0xd0088400為起始地址的512*1024字節)復制到0x23e00000為起始地址SDRAM中,最后程序執行(void (*)(void))0x23e00000 ()跳轉到應用程序處運行。
7.2 當(S_CctpRxBuf.buf[0]==0x1b)&&(S_CctpRxBuf.buf[4]==0x3e)時,進入ScbJumpToApp()函數。
三、程序應用。
1、經過一級BOOT程序的引導,我們可以很快進入到二級的引導程序中。在這里我們可以訪問系統的全部資源。我們可以更改一級BOOT程序、二級引導程序、包括之后要運行的主應用程序。
2、人機交互最常用的就是異步串口通信,連接簡單可靠,不需要專門的上位機軟件;缺點是傳輸距離近,數據傳輸速度慢,如果要進行大數據量傳輸肯定太慢。如果我們只簡單的傳輸命令和回傳一些簡單信息還是一種很好的工具。在系統啟動過程中通過串口輸出一些系統版本信息,方便我們查看。
3、我們可以利用以太網口進行文件傳輸、下載。通過INTERNET,我們甚至可以在不同城市間就可以與系統進行交互操作,方便故障診斷維修。
4、利用USB也可以進行數據傳輸拷貝,但相對來說用的比較少。
5、可以進行這樣設置:
5.1、系統開機進入一級BOOT程序后,進入二級程序引導,在進入二級程序引導的時候,正常的話就進入應用程序。如果不能進入應用程序或在引導時按DEL建,利用串口通信,則進入二級引導界面。
5.2、二級引導界面里設置很多選項,如:更新dataflash中一級BOOT程序、更新dataflash中二級引導程序、更新dataflash中應用程序、下載文件到指定地址的dataflash中、下載程序到指定地址的SDRAM中、程序跳到指定的SDRAM中運行、讀取指定dataflash中地址的數據、讀取指定SDRAM中地址的數據、重新啟動、網絡設置等
5.3、通過串口選擇相應的操作,按提示操作,數據傳輸的時候可以通過網絡傳輸。網絡的參數如IP、網關等也經過串口設置確保可以正常建立網絡連接。