1. 程式人生 > >uboot移植第一天——程式碼分析(1)

uboot移植第一天——程式碼分析(1)

uboot版本 :u-boot-1.1.6
編譯器 :gcc version 3.4.5
開發板 :jz2440

.globl _start
_start: b       reset
*跳轉到reset執行*

1、set the cpu to SVC32 mode——設定為管理模式
2、turn off the watchdog——關閉看門狗
3、mask all IRQs by setting all bits in the INTMR——關閉外部中斷
4、設定時鐘比例
5、bl cpu_init_crit

  1. flush v4 I/D caches——用於同步
  2. disable MMU stuff and caches——關閉mmu和cache
  3. bl lowlevel_init——儲存控制器初始化
    • 這裡要注意SMRDATA中的值,根據資料手冊和當前時鐘配置
  4. 重定位——即就是把falsh中的程式碼複製到ram中,本開發板複製到sdram中;
  5. stack_setup——設定堆疊,因為接下來要調c函式,來進行更復雜的處理。
  6. clear_bss——清bss段,該段存放的是初始化為零或為未初始化的變數,只要額外的放在一個段就行,使用時取就行;
  7. 進入uboot的第二階段
ldr pc, _start_armboot
_start_armboot: .word start_armboot

第二階段分析:

void start_armboot (void
) { init_fnc_t **init_fnc_ptr;//函式指標的指標,在下面的for迴圈中迴圈呼叫init_sequence陣列中的函式,進行對板子的各種初始化 char *s; #ifndef CFG_NO_FLASH ulong size; #endif #if defined(CONFIG_VFD) || defined(CONFIG_LCD) unsigned long addr; #endif /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN
- sizeof(gd_t));//為全域性變數(儲存在一個結構體中)分配空間,在連結地址(程式碼執行時的所在的地址)-堆空間大小(#define設定)-結構體大小gd指向地址 /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); memset ((void*)gd, 0, sizeof (gd_t)); gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));//bd指向板子相關資訊儲存的地址 memset (gd->bd, 0, sizeof (bd_t)); monitor_flash_len = _bss_start - _armboot_start; //計算出uboot的程式碼段大小,自己看程式碼這個跟lds連結指令碼有關 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } //上面的for迴圈是呼叫各種初始化函式,init_fnc_ptr 是函式指標的指標,init_sequence[]函式指標陣列 #ifndef CFG_NO_FLASH /* configure available FLASH banks */ size = flash_init ();//初始化並識別開發板的norflash display_flash_config (size); #endif /* CFG_NO_FLASH */ #ifdef CONFIG_VFD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif /* * reserve memory for VFD display (always full pages) */ /* bss_end is defined in the board-specific linker script */ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); size = vfd_setmem (addr); gd->fb_base = addr; #endif /* CONFIG_VFD */ #ifdef CONFIG_LCD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif /* * reserve memory for LCD display (always full pages) */ /* bss_end is defined in the board-specific linker script */ addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); size = lcd_setmem (addr); gd->fb_base = addr; #endif /* CONFIG_LCD */ /* armboot_start is defined in the board-specific linker script */ mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); #if (CONFIG_COMMANDS & CFG_CMD_NAND) puts ("NAND: "); nand_init(); /* go init the NAND */ //初始化並識別開發板的nandflash #endif

以上對uboot做了個非常粗略的分析,因本人初學記錄下的學習筆記,若有不對之處,望各位指出。