0K6410學習之初學Uboot_stage2

來源:互聯網
上載者:User

0K6410學習之初學Uboot_stage2

唉,剛剛老同學們打電話來找我月底出去聚一聚,我發誓這是我第一次這麼冷靜,也就是不像以前一樣,不經過考慮,就一口答應下來。因為,我覺得我有很多重要的事情要做,像我這種不準備考研的學生,我必須要抓住假期的時間給自己充電,老朋友們,不好意思,請原諒我這次善意的謊言,給我在校的學習時間不多了,請接受我這次偷偷的道歉。好吧,既然已經燒好一壺水了,那就開始我的uboot
stage2的學習吧!!

 

當第一階段的彙編部分執行完,跳到stage2時,開始執行c函數start_armboot,該函數就是整個u-boot的主函數。

1、開頭首先聲明一個全域指標變數DECLARE_GLOBAL_DATA_PTR;這個宏定義在標頭檔

include/asm-arm/global_data.h 中#define DECLARE_GLOBAL_DATA_PTR                             register volatilegd_t *gd asm ("r8")

聲明一個寄存器變數 gd
佔用 r8。這個宏在所有需要引用全域資料指標gd_t *gd
的源

碼中都有申明,這個申明也避免編譯器把r8
分配給其它的變數.
所以 gd 就是 r8,這個指標變數不另外分配記憶體。

2、 /* Pointer is writable since weallocated a register for it */         gd= (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));         /*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));

         memset (gd->bd, 0, sizeof (bd_t))強制轉換類型,給指標gd、gd賦一個地址,進行地址分配。都說下面是張經典的uboot映射圖,確實不錯啊,它把整個Uboot啟動過程中的記憶體配置描述的相當清楚的。

monitor_flash_len = _bss_start - _armboot_start; 按照可以知道,這是uboot的長度。

3、接下來是一個迴圈,對板子的資訊以及相關函數進行初始化。

for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {                   if((*init_fnc_ptr)() != 0) {                            hang();                   }}

4、/*
初始化堆空間 */

/* armboot_start is defined in theboard-specific linker script */mem_malloc_init (_armboot_start -CONFIG_SYS_MALLOC_LEN,CONFIG_SYS_MALLOC_LEN);  /*配置flash*/ #ifndef CONFIG_SYS_NO_FLASH         /*configure available FLASH banks */         display_flash_config(flash_init ());#endif /* CONFIG_SYS_NO_FLASH */

5、接下來是一系列的初始化,不一一分析,其實是我有些函數分析不來,指標指的我頭暈。。

#ifdef CONFIG_VFD#       ifndefPAGE_SIZE#         define PAGE_SIZE 4096#       endif         /*          * reserve memory for VFD display (always fullpages)          */         /*bss_end is defined in the board-specific linker script */         addr= (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);         vfd_setmem(addr);         gd->fb_base= addr;#endif /* CONFIG_VFD */ #ifdef CONFIG_LCD         /*board init may have inited fb_base */         if(!gd->fb_base) {#                ifndefPAGE_SIZE#                  define PAGE_SIZE 4096#                endif                   /*                    * reserve memory for LCD display (always fullpages)                    */                   /*bss_end is defined in the board-specific linker script */                   addr= (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);                   lcd_setmem(addr);                   gd->fb_base= addr;         }#endif /* CONFIG_LCD */ #if defined(CONFIG_CMD_NAND)         puts("NAND:  ");         nand_init();                /* go init the NAND */#endif #if defined(CONFIG_CMD_ONENAND)         onenand_init();#endif #ifdef CONFIG_HAS_DATAFLASH         AT91F_DataflashInit();         dataflash_print_info();#endif          /*initialize environment */         env_relocate(); #ifdef CONFIG_VFD         /*must do this after the framebuffer is allocated */         drv_vfd_init();#endif /* CONFIG_VFD */ #ifdef CONFIG_SERIAL_MULTI         serial_initialize();#endif          /*IP Address */         gd->bd->bi_ip_addr= getenv_IPaddr ("ipaddr");          stdio_init();      /* get the devices list going. */          jumptable_init(); #if defined(CONFIG_API)         /*Initialize API */         api_init();#endif          console_init_r();      /* fully init console as a device*/ #if defined(CONFIG_ARCH_MISC_INIT)         /*miscellaneous arch dependent initialisations */         arch_misc_init();#endif#if defined(CONFIG_MISC_INIT_R)         /*miscellaneous platform dependent initialisations */         misc_init_r();#endif          /*enable exceptions */         enable_interrupts();          /*Perform network card initialisation if necessary */#ifdef CONFIG_DRIVER_TI_EMAC         /*XXX: this needs to be moved to board init */extern void davinci_eth_set_mac_addr (constu_int8_t *addr);         if(getenv ("ethaddr")) {                   ucharenetaddr[6];                   eth_getenv_enetaddr("ethaddr",enetaddr);                   davinci_eth_set_mac_addr(enetaddr);         }#endif #if defined(CONFIG_DRIVER_SMC91111) || defined(CONFIG_DRIVER_LAN91C96)         /*XXX: this needs to be moved to board init */         if(getenv ("ethaddr")) {                   ucharenetaddr[6];                   eth_getenv_enetaddr("ethaddr",enetaddr);                   smc_set_mac_addr(enetaddr);         }#endif /* CONFIG_DRIVER_SMC91111 ||CONFIG_DRIVER_LAN91C96 */          /*Initialize from environment */         if((s = getenv ("loadaddr")) != NULL) {                   load_addr= simple_strtoul (s, NULL, 16);         }#if defined(CONFIG_CMD_NET)         if((s = getenv ("bootfile")) != NULL) {                   copy_filename(BootFile, s, sizeof (BootFile));         }#endif #ifdef BOARD_LATE_INIT         board_late_init();#endif #ifdef CONFIG_GENERIC_MMC         puts("MMC:   ");         mmc_initialize(gd->bd);#endif #ifdef CONFIG_BITBANGMII         bb_miiphy_init();#endif#if defined(CONFIG_CMD_NET)#if defined(CONFIG_NET_MULTI)         puts("Net:   ");#endif         eth_initialize(gd->bd);#if defined(CONFIG_RESET_PHY_R)         debug("Reset Ethernet PHY\n");         reset_phy();#endif#endif         /*main_loop() can return to retry autoboot, if so just run it again. */         for(;;) {                   main_loop();         }          /*NOTREACHED - no way out of command loop except booting */}

6、還有一個初始化函數,配置一些資訊。

nit_fnc_t *init_sequence[] = {#if defined(CONFIG_ARCH_CPU_INIT)         arch_cpu_init,          /* basic arch cpu dependent setup */#endif         board_init,                 /* basic board dependent setup*/#if defined(CONFIG_USE_IRQ)         interrupt_init,           /* set up exceptions */#endif         timer_init,                 /* initialize timer */#ifdef CONFIG_FSL_ESDHC         get_clocks,#endif         env_init,            /* initialize environment */         init_baudrate,          /* initialze baudrate settings */         serial_init,                  /* serial communications setup*/         console_init_f,          /* stage 1 init of console */         display_banner,                 /* say that we are here */#if defined(CONFIG_DISPLAY_CPUINFO)         print_cpuinfo,           /* display cpu info (and speed) */#endif#if defined(CONFIG_DISPLAY_BOARDINFO)         checkboard,              /* display board info */#endif#if defined(CONFIG_HARD_I2C) ||defined(CONFIG_SOFT_I2C)         init_func_i2c,#endif         dram_init,                  /* configure available RAMbanks */#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)         arm_pci_init,#endif         display_dram_config,         NULL,};

其中display_banner是串口上列印的第一條資訊的內容,自己有興趣可以進入這個函數,修改一下,會有意想不到的結果的。

最後整個 u-boot
的執行就進入main_loop()函數等待使用者輸入命令,解析並執行命令的死迴圈中。

關於uboot stage2裡面的一些重要資料結構以及一些值得注意的地方那就等下次吧,stage2的分析暫時到這裡。 
待續,uboot移植。。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.