uboot——官網下載直接移植(二)


1:做好上一章的准備工作,下面我們開始移植uboot

首先修改交叉編譯工具鏈:在主Makefile文件中的交叉編譯工具鏈修改為:

# set default to nothing for native builds ifeq ($(HOSTARCH),$(ARCH)) CROSS_COMPILE ?=
else CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi- endif

下面把燒錄文件移植到uboot中;

把三星移植好的uboot中的sd_fusing 復制到新的uboot的根目錄中,燒錄sd卡

輸出信息如下,說明校驗頭失敗;

分析sd_fusing目錄下的C110-EVT1-mkbl1.c文件

這段代碼中是把uboot的前8k中的前16個字節的內容當做頭來使用,相當於把uboot_inand.bin的前8k復制到SD-bl1-8k.bin,但是這前8k的前16個字節用作一個header 從bit8-bit11用作校驗頭,以前uboot中前16字節特意設置為0;

我們可以修改這個代碼,也修改修改uboot中的前16字節,一下為修改之后的代碼:

 #include <stdio.h> #include <string.h> #include <stdlib.h>

int main (int argc, char *argv[]) { FILE *fp; char        *Buf, *a, *b; int BufLen; int nbytes, fileLen; unsigned int checksum; int i; //////////////////////////////////////////////////////////////
    if (argc != 4) { printf("Usage: mkbl1 <source file> <destination file> <size> \n"); return -1; } //////////////////////////////////////////////////////////////
    BufLen = atoi(argv[3]); Buf = (char *)malloc(BufLen + 16); memset(Buf, 0x00, BufLen + 16); //////////////////////////////////////////////////////////////
    fp = fopen(argv[1], "rb"); if( fp == NULL) { printf("source file open error\n"); free(Buf); return -1; } fseek(fp, 0L, SEEK_END); fileLen = ftell(fp); fseek(fp, 0L, SEEK_SET); if ( BufLen > fileLen ) { printf("Usage: unsupported size\n"); free(Buf); fclose(fp); return -1; } /* ** bhc add */ b = Buf + 16; nbytes = fread(b, 1, BufLen, fp); if ( nbytes != BufLen ) { printf("source file read error\n"); free(Buf); fclose(fp); return -1; } fclose(fp); //////////////////////////////////////////////////////////////
    a = b; for(i = 0, checksum = 0; i < BufLen - 16; i++) checksum += (0x000000FF) & *a++; /* ** bhc add */ a = Buf; *( (unsigned int *)a ) = 0x2000; a = Buf + 8; *( (unsigned int *)a ) = checksum; //////////////////////////////////////////////////////////////
    fp = fopen(argv[2], "wb"); if (fp == NULL) { printf("destination file open error\n"); free(Buf); return -1; } a = Buf; nbytes = fwrite( a, 1, BufLen, fp); if ( nbytes != BufLen ) { printf("destination file write error\n"); free(Buf); fclose(fp); return -1; } free(Buf); fclose(fp); return 0; }

實驗現象同修改uboot前16字節一樣,說明校驗和對了,通過這個實驗我們可以知道,irom除了校驗和一致以外,第一字節的值應該為0x2000;

按照三星修改的uboot頭文件設置:

 

至於第一個為什么是0x2000按照三星irom_application_note中的說法第一個為uboot的大小,但是實際值也不是這樣的;

修改以后重新編譯如下所示:

下面我們來看一下start.S中的代碼 

最前面一段為設置異常向量表;

.globl _start _start: b reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq #ifdef CONFIG_SPL_BUILD _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_abort: .word _prefetch_abort _data_abort: .word _data_abort _not_used: .word _not_used _irq: .word _irq _fiq: .word _fiq _pad: .word 0x12345678 /* now 16*4=64 */
#else _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq _pad: .word 0x12345678 /* now 16*4=64 */
#endif    /* CONFIG_SPL_BUILD */

以及一些用到的全局變量的初始化

.globl _TEXT_BASE _TEXT_BASE: #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE) .word CONFIG_SPL_TEXT_BASE #else .word CONFIG_SYS_TEXT_BASE #endif

/* * These are defined in the board-specific linker script. */ .globl _bss_start_ofs _bss_start_ofs: .word __bss_start - _start .globl _bss_end_ofs _bss_end_ofs: .word __bss_end - _start .globl _end_ofs _end_ofs: .word _end - _start #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START IRQ_STACK_START: .word 0x0badc0de

/* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START FIQ_STACK_START: .word 0x0badc0de
#endif

/* IRQ stack memory (calculated at run-time) + 8 bytes */ .globl IRQ_STACK_START_IN IRQ_STACK_START_IN: .word 0x0badc0de

下面是真正的執行程序部分:

reset: bl save_boot_params /* * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, * except if in HYP mode already */ mrs r0, cpsr and r1, r0, #0x1f @ mask mode bits teq r1, #0x1a        @ test for HYP mode bicne r0, r0, #0x1f @ clear all mode bits orrne r0, r0, #0x13        @ set SVC mode orr r0, r0, #0xc0 @ disable FIQ and IRQ msr cpsr,r0

 save_boot_params 這個函數實際上就是直接 return 0;

ENTRY(save_boot_params)
  bx lr @ back to my caller      //直接轉到lr

下面是設置為svc模式,禁止fir、irq中斷;

下面是兩個關鍵性的函數

bl cpu_init_cp15 

cp15協處理器的初始化


bl cpu_init_crit 在看一下這個函數:

1 ENTRY(cpu_init_crit) 2     /*
3  * Jump to board specific initialization... 4  * The Mask ROM will have already initialized 5  * basic memory. Go here to bump up clock rate and handle 6  * wake up conditions. 7      */
8  b lowlevel_init @ go setup pll,mux,memory 9 ENDPROC(cpu_init_crit)

這個函數中就一個

b lowlevel_init

 --------------------------------------

 進入lowlevel_init函數中,在這里我們要進行串口的初始化並打印信息O

然后在進行dram的初始化,並打印信息K

dram初始化的時候記得把相關頭文件復制過去就可以了;

然后返回_start函數中,進行重定位、清bss跳轉到第二階段

這里要注意:串口輸出需要一個時間,所以要打印之前首先放一個delay函數;確定他發送完

注意在lowlevel_init函數中存在一些無關的代碼如下面,io復位等,這些代碼有可能會陷入死循環,跳轉不出去,這些代碼直接去掉;

返回到_start函數中並設置打印信息A

 

如下圖:打印出了A,下面進行重定位

因為要調用c語言函數,所以首先要設置棧;

然后判斷是否需要重定位,如果需要則重定位;

在鏈接腳本中設置的鏈接地址是從0x00000000開始的,但是

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM