S3C2440學習之自己寫bootloader
阿新 • • 發佈:2018-12-01
最簡單bootloader包含以下幾個內容
第一階段: (1)關看門狗 (2)設定時鐘 (3)初始化SDRAM (4)重定位:bootloader可能大於4K, 把flash中的bootloader拷貝到SDRAM中。 (5)跳轉到main 第二階段: (6)初始化串列埠,核心啟動列印引數 (7)設定啟動引數,供核心啟動時解析使用 (8)跳轉啟動核心一.編寫第1階段
1.bootloader目標:啟動核心。(1)從flash把核心讀入記憶體
1.1 初始化硬體:關看門狗、設定時鐘、設定SDRAM、初始化NAND FLASH
1.2 如果bootloader比較大,要把它重定位到SDRAM
1.3 把核心從NAND FLASH讀到SDRAM
1.4 設定"要傳給核心的引數"
1.5 跳轉執行核心 2.首先寫start.S,主要內容如下: /* 1. 關看門狗 */ [cpp]
- ldr r0, =0x53000000
- mov r1, #0
- str r1, [r0]
/* 2. 設定時鐘 */ [cpp] view plain copy
- <span style="white-space:pre"> </span>ldr r0, =0x4c000014
- mov r1, #0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
- str r1, [r0]
- /* 如果HDIVN非0,CPU的匯流排模式應該從“fast bus mode”變為“asynchronous bus mode” */
- mrc p15, 0, r1, c1, c0, 0 /* 讀出控制暫存器 */
- orr r1, r1, #0xc0000000 /* 設定為“asynchronous bus mode” */
- mcr p15, 0, r1, c1, c0, 0 /* 寫入控制暫存器 */
- /* MPLLCON = S3C2440_MPLL_200MHZ */
- ldr r0, =0x4c000004
- ldr r1, =S3C2440_MPLL_200MHZ
- str r1, [r0]
- <span style="white-space:pre"> </span>#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
- <span style="white-space:pre"> </span>#define MEM_CTL_BASE 0x48000000
- ldr r0, =MEM_CTL_BASE
- adr r1, sdram_config /* sdram_config的當前地址 */
- add r3, r0, #(13*4)
- 1:
- ldr r2, [r1], #4
- str r2, [r0], #4
- cmp r0, r3
- bne 1b
- sdram_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
- void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
- {
- int i = 0;
- /* 如果是NOR啟動 */
- if (isBootFromNorFlash())
- {
- while (i < len)
- {
- dest[i] = src[i];
- i++;
- }
- }
- else
- {
- //nand_init();
- nand_read((unsigned int)src, dest, len);
- }
- }
- int isBootFromNorFlash(void)
- {
- volatile int *p = (volatile int *)0;
- int val;
- val = *p;
- *p = 0x12345678;
- if (*p == 0x12345678)
- {
- /* 寫成功, 是nand啟動 */
- *p = val;
- return 0;
- }
- else
- {
- /* NOR不能像記憶體一樣寫 */
- return 1;
- }
- }
- void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
- {
- int i = 0;
- /* 如果是NOR啟動 */
- if (isBootFromNorFlash())
- {
- while (i < len)
- {
- dest[i] = src[i];//從原地址讀出一個值給目的地址
- i++;
- }
- }
- else
- {
- //nand_init();
- nand_read((unsigned int)src, dest, len);
- }
- }
[cpp] view plain copy print ?
- ldr sp, =0x34000000
- bl nand_init
- mov r0, #0
- ldr r1, =_start
- ldr r2, =__bss_start
- sub r2, r2, r1
- bl copy_code_to_sdram
- bl clear_bss