简单BootLoader
目錄
- 簡(jiǎn)單BootLoader
- 概述
- NOR與NAND啟動(dòng)
- 鏈接腳本規(guī)劃
- 初始化規(guī)劃
- 參數(shù)設(shè)置
簡(jiǎn)單BootLoader
概述
目標(biāo):?啟動(dòng)內(nèi)核,也就是需要讀取內(nèi)核到內(nèi)存,也就是操作flash和內(nèi)存
一個(gè)最基本的BootLoader應(yīng)該有以下步驟:
優(yōu)化: 為了加快運(yùn)行速度,應(yīng)該提高主頻,打開Icach
/* 啟動(dòng)ICACHE */mrc p15, 0, r0, c1, c0, 0 @ read control regorr r0, r0, #(1<<12)mcr p15, 0, r0, c1, c0, 0 @ write it backNOR與NAND啟動(dòng)
參考文檔 ARM裸機(jī)>啟動(dòng)流程
-
NAND 啟動(dòng)自動(dòng)復(fù)制到4KRAM
-
NOR啟動(dòng),片內(nèi)RAM為0x4000,0000
鏈接腳本規(guī)劃
我們從上圖可以看到,SDRAM的起始地址為0x3000,0000,SDRAM大小為64M,也就是地址頂端為0x3400,0000.預(yù)留512K給Bootloader,也就是規(guī)劃hex(0x34000000-512*1024)=0x33f8,0000為Bootloader的起始地址.鏈接腳本考慮字節(jié)對(duì)齊.
SECTIONS {. = 0x33f80000;.text : { *(.text) }. = ALIGN(4);.rodata : {*(.rodata*)} . = ALIGN(4);.data : { *(.data) }. = ALIGN(4);__bss_start = .;.bss : { *(.bss) *(COMMON) }__bss_end = .; }鏈接腳本中有個(gè)COMMON段,這是未初始化的全局變量,一般情況下也是直接在鏈接階段放在bss段進(jìn)行清零.但是注意未初始化的全局變量與初始化為0的全局變量,并不對(duì)等.[未初始化的全局變量(COMMON段)為弱符號(hào),如果有同名的全局變量,可能會(huì)存在覆蓋的情況]
對(duì)于全局變量來說,如果初始化了不為0的值,那么該全局變量則被保存在data段,如果初始化的值為0,那么將其保存在bss段,如果沒有初始化,則將其保存在common段,等到鏈接時(shí)再將其放入到BSS段。關(guān)于第三點(diǎn)不同編譯器行為會(huì)不同,有的編譯器會(huì)把沒有初始化的全局變量直接放到BSS段。
鏈接腳本中值的獲取,具體參考./鏈接腳本.md
//匯編方法1 .global _bss_start _bss_start:.word __bss_start ldr r1, _bss_start //讀取內(nèi)存,這里是讀取label所在內(nèi)存的數(shù)據(jù) //匯編方法2 ldr r1, =__bss_start //C方法 extern int __bss_start; int val =&__bss_start; //!< 獲得__bss_start的值初始化規(guī)劃
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02)) #define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01)) #define MEM_CTL_BASE 0x48000000.text .global _start _start:/* 1. 關(guān)看門狗 */ldr r0, =0x53000000mov r1, #0str r1, [r0]/* 2. 設(shè)置時(shí)鐘 */ldr r0, =0x4c000014// mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1mov r1, #0x05; // FCLK:HCLK:PCLK=1:4:8str r1, [r0]/* 如果HDIVN非0,CPU的總線模式應(yīng)該從“fast bus mode”變?yōu)椤癮synchronous bus mode” */mrc p15, 0, r1, c1, c0, 0 /* 讀出控制寄存器 */ orr r1, r1, #0xc0000000 /* 設(shè)置為“asynchronous bus mode” */mcr p15, 0, r1, c1, c0, 0 /* 寫入控制寄存器 *//* MPLLCON = S3C2440_MPLL_200MHZ */ldr r0, =0x4c000004ldr r1, =S3C2440_MPLL_400MHZstr r1, [r0]/* 啟動(dòng)ICACHE */mrc p15, 0, r0, c1, c0, 0 @ read control regorr r0, r0, #(1<<12)mcr p15, 0, r0, c1, c0, 0 @ write it back/* 3. 初始化SDRAM */ldr r0, =MEM_CTL_BASEadr r1, sdram_config /* sdram_config的當(dāng)前地址 */add r3, r0, #(13*4) 1:ldr r2, [r1], #4str r2, [r0], #4cmp r0, r3bne 1b/* 4. 重定位 : 把bootloader本身的代碼從flash復(fù)制到它的鏈接地址去 */ldr sp, =0x34000000bl nand_initmov r0, #0ldr r1, =_startldr r2, =__bss_startsub r2, r2, r1bl copy_code_to_sdrambl clear_bss/* 5. 執(zhí)行main */ldr lr, =haltldr pc, =main halt:b haltsdram_config:.long 0x22011110 //BWSCON.long 0x00000700 //BANKCON0.long 0x00000700 //BANKCON1.long 0x00000700 //BANKCON2.long 0x00000700 //BANKCON3 .long 0x00000700 //BANKCON4.long 0x00000700 //BANKCON5.long 0x00018005 //BANKCON6.long 0x00018005 //BANKCON7.long 0x008C04F4 // REFRESH.long 0x000000B1 //BANKSIZE.long 0x00000030 //MRSRB6.long 0x00000030 //MRSRB7參數(shù)設(shè)置
nand_read(0x60000+64, (unsigned char *)0x30008000, 0x200000); setup_start_tag(); setup_memory_tags(); setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"); setup_end_tag();void setup_start_tag(void) {params = (struct tag *)0x30000100;params->hdr.tag = ATAG_CORE;params->hdr.size = tag_size (tag_core);params->u.core.flags = 0;params->u.core.pagesize = 0;params->u.core.rootdev = 0;params = tag_next (params); }內(nèi)核存儲(chǔ)在0x60000+64,讀取到運(yùn)行地址0x30008000,參數(shù)存儲(chǔ)在0x30000100,最后傳入機(jī)器ID=362
theKernel = (void (*)(int, int, unsigned int))0x30008000; theKernel(0, 362, 0x30000100);轉(zhuǎn)載:https://www.cnblogs.com/zongzi10010/p/10023691.html?
總結(jié)
以上是生活随笔為你收集整理的简单BootLoader的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构建根文件系统之busybox(四)完善
- 下一篇: uboot中的中断macro宏