uboot之board.c源码分析

系统 1522 0
      /lib_arm/
      
        board.c 主要完成了一些初始化的操作,最重要的是有start_armboot函数



_armboot_start地址为多少??




      
      
        /*
      
      
        



 *



 * U-Boot code: 00F00000 -> 00F3C774  BSS: -> 00FC3274



 * IRQ Stack: 00ebff7c



 * FIQ Stack: 00ebef7c



 
      
      
        */
      
      
        



 



#include 
      
      <common.h>
      
        



#include 
      
      <command.h>
      
        



#include 
      
      <malloc.h>
      
        



#include 
      
      <devices.h>
      
        



#include 
      
      <version.h>
      
        



#include 
      
      <net.h>
      
        



 



#ifdef CONFIG_DRIVER_SMC91111



#include 
      
      
        "
      
      
        ../drivers/smc91111.h
      
      
        "
      
      
        #endif
      
      
        



#ifdef CONFIG_DRIVER_LAN91C96  应该是关于网卡的定义



#include 
      
      
        "
      
      
        ../drivers/lan91c96.h
      
      
        "
      
      
        #endif
      
      
        



 



DECLARE_GLOBAL_DATA_PTR 
      
      
        //
      
      
        声明全局数据指针
      
      
        #if
      
       (CONFIG_COMMANDS & CFG_CMD_NAND)




      
        void
      
       nand_init (
      
        void
      
      
        ); 声明这个方法




      
      
        #endif
      
      
        ulong
      
      
         monitor_flash_len;



 



#ifdef CONFIG_HAS_DATAFLASH




      
      
        extern
      
      
        int
      
        AT91F_DataflashInit(
      
        void
      
      
        );




      
      
        extern
      
      
        void
      
       dataflash_print_info(
      
        void
      
      
        );




      
      
        #endif
      
      
        



 



#ifndef CONFIG_IDENT_STRING 如果没有定义,CONFIG_IDENT_STRING就定义为空




      
      
        #define
      
       CONFIG_IDENT_STRING ""




      
        #endif
      
      
        const
      
      
        char
      
       version_string[] =
      
        版本字符串



     U_BOOT_VERSION
      
      
        "
      
      
         (
      
      
        "
      
       __DATE__ 
      
        "
      
      
         - 
      
      
        "
      
       __TIME__ 
      
        "
      
      
        )
      
      
        "
      
      
        CONFIG_IDENT_STRING;



 



#ifdef CONFIG_DRIVER_CS8900  如果是CS8900网卡,则声明下面的函数。好像是获取网址的意思




      
      
        extern
      
      
        void
      
       cs8900_get_enetaddr (uchar *
      
         addr);




      
      
        #endif
      
      
        



 



#ifdef CONFIG_DRIVER_RTL8019




      
      
        extern
      
      
        void
      
       rtl8019_get_enetaddr (uchar *
      
         addr);




      
      
        #endif
      
      
        /*
      
      
        



 * Begin and End of memory area for malloc(), and current "brk" malloc用于用户程序进行分配内存



 
      
      
        */
      
      
        static
      
      
        ulong
      
       mem_malloc_start = 
      
        0
      
      
        ;




      
      
        static
      
      
        ulong
      
       mem_malloc_end = 
      
        0
      
      
        ;




      
      
        static
      
      
        ulong
      
       mem_malloc_brk = 
      
        0
      
      
        ;



 




      
      
        static
      
      
        void
      
       mem_malloc_init (
      
        ulong
      
      
         dest_addr) 内存分配初始函数。



{



     mem_malloc_start 
      
      =
      
         dest_addr;



     mem_malloc_end 
      
      = dest_addr +
      
         CFG_MALLOC_LEN;



     mem_malloc_brk 
      
      =
      
         mem_malloc_start;



 



     memset ((
      
      
        void
      
       *) mem_malloc_start, 
      
        0
      
      
        ,



              mem_malloc_end 
      
      -
      
         mem_malloc_start);



真正实现内存分配的函数。分配了一个CFG_MALLOC_LEN大小的内存空间



}



 




      
      
        void
      
       *
      
        sbrk (ptrdiff_t increment)     所分配内存区的brk指针调整。



{



     
      
      
        ulong
      
       old =
      
         mem_malloc_brk;



     
      
      
        ulong
      
      
        new
      
       = old +
      
         increment;



 



     
      
      
        if
      
       ((
      
        new
      
       < mem_malloc_start) || (
      
        new
      
       >
      
         mem_malloc_end)) {



         
      
      
        return
      
      
         (NULL);



     }



     mem_malloc_brk 
      
      = 
      
        new
      
      
        ;



 



     
      
      
        return
      
       ((
      
        void
      
       *
      
        ) old);



}



 




      
      
        /*
      
      
        ***********************************************************************



 * Init Utilities                             *



 ************************************************************************



 * Some of this code should be moved into the core functions,



 * or dropped completely,



 * but let's get it working (again) first...



 
      
      
        */
      
      
        



下面就是一系列的初始化操作。




      
      
        static
      
      
        int
      
       init_baudrate (
      
        void
      
      
        )           初始化波特率



{



     
      
      
        char
      
       tmp[
      
        64
      
      ]; 
      
        /*
      
      
         long enough for environment variables 
      
      
        */
      
      
        int
      
       i = getenv_r (
      
        "
      
      
        baudrate
      
      
        "
      
      , tmp, 
      
        sizeof
      
      
         (tmp));



     gd
      
      ->bd->bi_baudrate = gd->baudrate = (i > 
      
        0
      
      
        )



              
      
      ? (
      
        int
      
      ) simple_strtoul (tmp, NULL, 
      
        10
      
      
        )



              : CONFIG_BAUDRATE;



 



     
      
      
        return
      
       (
      
        0
      
      
        );



}



 




      
      
        static
      
      
        int
      
       display_banner (
      
        void
      
      
        ) 一些显示函数。显示IRQ_STACK_START等的地址



_armboot_start, _bss_start, _bss_end 这些值



{



     printf (
      
      
        "
      
      
        \n\n%s\n\n
      
      
        "
      
      
        , version_string);



     debug (
      
      
        "
      
      
        U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n
      
      
        "
      
      
        ,



            _armboot_start, _bss_start, _bss_end);



#ifdef CONFIG_MODEM_SUPPORT



     debug (
      
      
        "
      
      
        Modem Support enabled\n
      
      
        "
      
      
        );




      
      
        #endif
      
      
        



#ifdef CONFIG_USE_IRQ



     debug (
      
      
        "
      
      
        IRQ Stack: %08lx\n
      
      
        "
      
      
        , IRQ_STACK_START);



     debug (
      
      
        "
      
      
        FIQ Stack: %08lx\n
      
      
        "
      
      
        , FIQ_STACK_START);




      
      
        #endif
      
      
        return
      
       (
      
        0
      
      
        );



}



 




      
      
        /*
      
      
        



 * WARNING: this code looks "cleaner" than the PowerPC version, but



 * has the disadvantage that you either get nothing, or everything.



 * On PowerPC, you might see "DRAM: " before the system hangs - which



 * gives a simple yet clear indication which part of the



 * initialization if failing.



 
      
      
        */
      
      
        static
      
      
        int
      
       display_dram_config (
      
        void
      
      
        )  显示内存的配置,打印出DRAM的大小



{



     
      
      
        int
      
      
         i;



 



#ifdef DEBUG



     puts (
      
      
        "
      
      
        RAM Configuration:\n
      
      
        "
      
      
        );



 



     
      
      
        for
      
      (i=
      
        0
      
      ; i<CONFIG_NR_DRAM_BANKS; i++
      
        ) {



         printf (
      
      
        "
      
      
        Bank #%d: %08lx 
      
      
        "
      
      , i, gd->bd->
      
        bi_dram[i].start);



         print_size (gd
      
      ->bd->bi_dram[i].size, 
      
        "
      
      
        \n
      
      
        "
      
      
        );



     }




      
      
        #else
      
      
        ulong
      
       size = 
      
        0
      
      
        ;



 



     
      
      
        for
      
       (i=
      
        0
      
      ; i<CONFIG_NR_DRAM_BANKS; i++
      
        ) {



         size 
      
      += gd->bd->
      
        bi_dram[i].size;



     }



     puts(
      
      
        "
      
      
        DRAM:  
      
      
        "
      
      
        );



     print_size(size, 
      
      
        "
      
      
        \n
      
      
        "
      
      
        );




      
      
        #endif
      
      
        return
      
       (
      
        0
      
      
        );



}



 



#ifndef CFG_NO_FLASH




      
      
        static
      
      
        void
      
       display_flash_config (
      
        ulong
      
      
         size)



{



     puts (
      
      
        "
      
      
        Flash: 
      
      
        "
      
      
        );



     print_size (size, 
      
      
        "
      
      
        \n
      
      
        "
      
      
        );



}




      
      
        #endif
      
       /* CFG_NO_FLASH */



 



 




      
        /*
      
      
        初始化一个串行口作为控制台,同时进行一些硬件测试



 * Breathe some life into the board...



 *



 * Initialize a serial port as console, and carry out some hardware



 * tests.



 *



 * The first part of initialization is running from Flash memory;



 * its main purpose is to initialize the RAM so that we



 * can relocate the monitor code to RAM.



 
      
      
        */
      
      
        



不存在一个common 即通用的初始化序列来为所有的开发板及结构进行初始化。因为不同的体系结构差别还是比较大的。




      
      
        /*
      
      
        



 * All attempts to come up with a "common" initialization sequence



 * that works for all boards and architectures failed: some of the



 * requirements are just _too_ different. To get rid of the resulting



 * mess of board dependent #ifdef'ed code we now make the whole



 * initialization sequence configurable to the user.



 *



 * The requirements for any new initalization function is simple: it



 * receives a pointer to the "global data" structure as it's only



 * argument, and returns an integer return code, where 0 means



 * "continue" and != 0 means "fatal error, hang the system".



 
      
      
        */
      
      
        通过接受一个指向全局数据的指针作为唯一的参数。



typedef 
      
      
        int
      
       (init_fnc_t) (
      
        void
      
      
        );



 




      
      
        int
      
       print_cpuinfo (
      
        void
      
      ); 
      
        /*
      
      
         test-only 
      
      
        */
      
      
        



 



init_fnc_t 
      
      *init_sequence[] =
      
         {定义一个初始化的整型指针数组



     cpu_init,     
      
      
        /*
      
      
         basic cpu dependent setup 
      
      
        */
      
      /cpu/arm920t/
      
        cpu.c



 这个函数在cpu.c函数中定义了



     board_init,        
      
      
        /*
      
      
         basic board dependent setup 
      
      
        */
      
      /board/smdk2410/
      
        smdk2410.c



     interrupt_init,        
      
      
        /*
      
      
         set up exceptions 
      
      
        */
      
      
        



     env_init,     
      
      
        /*
      
      
         initialize environment 
      
      
        */
      
      tools/env/
      
        FW_env.c



     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)       显示cpu的信息
      
        



     print_cpuinfo,         
      
      
        /*
      
      
         display cpu info (and speed) 
      
      
        */
      
      
        #endif
      
      
        #if
      
       defined(CONFIG_DISPLAY_BOARDINFO)     显示板的信息
      
        



     checkboard,        
      
      
        /*
      
      
         display board info 
      
      
        */
      
      
        #endif
      
      
        



     dram_init,         
      
      
        /*
      
      
         configure available RAM banks 
      
      
        */
      
      
        



     display_dram_config,



     NULL,



};



 




      
      
        void
      
       start_armboot (
      
        void
      
      
        )



{



     init_fnc_t 
      
      **
      
        init_fnc_ptr;定义一个双重整型指针。



     
      
      
        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));



     _armboot_start为0x33f80000,CFG_MALLOC_LEN是堆大小加环境数据区大小,在smdk2410.h中有定义




      
      
        #define
      
       CFG_MALLOC_LEN              (CFG_ENV_SIZE + 128*1024)  CFG_ENV_SIZE为64K,所以共192K



 



     
      
        /*
      
      
         compiler optimization barrier needed for GCC >= 3.4 
      
      
        */
      
      
        



     __asm__ __volatile__(
      
      
        ""
      
      : : :
      
        "
      
      
        memory
      
      
        "
      
      
        );



 



     memset ((
      
      
        void
      
      *)gd, 
      
        0
      
      , 
      
        sizeof
      
      
         (gd_t));获得一个gd指针,给全局数据变量gd分配内存



     gd
      
      ->bd = (bd_t*)((
      
        char
      
      *)gd - 
      
        sizeof
      
      
        (bd_t));



     memset (gd
      
      ->bd, 
      
        0
      
      , 
      
        sizeof
      
      
         (bd_t));给板子数据变量分配内存空间



 



     monitor_flash_len 
      
      = _bss_start -
      
         _armboot_start;取整个代码区Uboot的长度



顺序执行init_sequence数组中的初始化函数



     
      
      
        for
      
       (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++
      
        init_fnc_ptr) {



         
      
      
        if
      
       ((*init_fnc_ptr)() != 
      
        0
      
      
        ) {



              hang ();



         }



     }



 



#ifndef CFG_NO_FLASH



     
      
      
        /*
      
      
         configure available FLASH banks 
      
      
        */
      
      
        从其实现上来看,好像只是配置nor flash



     size 
      
      =
      
         flash_init ();



     display_flash_config (size);显示flash的信息




      
      
        #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 
      
      
        */
      
      
        



     初始化CFG_MALLOC_LEN大小空间



     mem_malloc_init (_armboot_start 
      
      -
      
         CFG_MALLOC_LEN);



 




      
      
        #if
      
       (CONFIG_COMMANDS & CFG_CMD_NAND)
      
        



初始化nandflash,这是在nandflash启动的s3c2410移植Uboot的关键,根据flash时序编写函数即可。首先要在include
      
      /configs/
      
        smdk2410.h中打开CFG_CMD_NAND命令



     puts (
      
      
        "
      
      
        NAND:  
      
      
        "
      
      
        );



     nand_init();       
      
      
        /*
      
      
         go init the NAND 
      
      
        */
      
      ,这个函数在前面被声明过,现在就可以直接使用了/board/smdk2410/
      
        smdk2410.c中没有定义这个函数,需要添加




      
      
        #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();framebuffer初始化




      
      
        #endif
      
       /* CONFIG_VFD */



 



     
      
        /*
      
      
         IP Address 
      
      
        */
      
      
        



     gd
      
      ->bd->bi_ip_addr = getenv_IPaddr (
      
        "
      
      
        ipaddr
      
      
        "
      
      
        );



 



     
      
      
        /*
      
      
         MAC Address 
      
      
        */
      
      
        



     {



         
      
      
        int
      
      
         i;



         
      
      
        ulong
      
      
         reg;



         
      
      
        char
      
       *s, *
      
        e;



         
      
      
        char
      
       tmp[
      
        64
      
      
        ];



 



         i 
      
      = getenv_r (
      
        "
      
      
        ethaddr
      
      
        "
      
      , tmp, 
      
        sizeof
      
      
         (tmp));



         s 
      
      = (i > 
      
        0
      
      ) ?
      
         tmp : NULL;



 



         
      
      
        for
      
       (reg = 
      
        0
      
      ; reg < 
      
        6
      
      ; ++
      
        reg) {



              gd
      
      ->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 
      
        16
      
      ) : 
      
        0
      
      
        ;



              
      
      
        if
      
      
         (s)



                   s 
      
      = (*e) ? e + 
      
        1
      
      
         : e;



         }获取网卡地址



 



#ifdef CONFIG_HAS_ETH1



         i 
      
      = getenv_r (
      
        "
      
      
        eth1addr
      
      
        "
      
      , tmp, 
      
        sizeof
      
      
         (tmp));



         s 
      
      = (i > 
      
        0
      
      ) ?
      
         tmp : NULL;



 



         
      
      
        for
      
       (reg = 
      
        0
      
      ; reg < 
      
        6
      
      ; ++
      
        reg) {



              gd
      
      ->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 
      
        16
      
      ) : 
      
        0
      
      
        ;



              
      
      
        if
      
      
         (s)



                   s 
      
      = (*e) ? e + 
      
        1
      
      
         : e;



         }




      
      
        #endif
      
      
        



     }



 



     devices_init ();   
      
      
        /*
      
      
         get the devices list going. 
      
      
        */
      
      
        调用相应驱动函数对硬件设备进行初始化



 



#ifdef CONFIG_CMC_PU2



     load_sernum_ethaddr ();




      
      
        #endif
      
       /* CONFIG_CMC_PU2 */
      
        



 



     jumptable_init ();



 



     console_init_r (); 
      
      
        /*
      
      
         fully init console as a device 
      
      
        */
      
      
        #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_CS8900



     cs8900_get_enetaddr (gd
      
      ->bd->
      
        bi_enetaddr);




      
      
        #endif
      
      
        #if
      
       defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)



     
      
        if
      
       (getenv (
      
        "
      
      
        ethaddr
      
      
        "
      
      
        )) {



         smc_set_mac_addr(gd
      
      ->bd->
      
        bi_enetaddr);



     }




      
      
        #endif
      
       /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */



 



     
      
        /*
      
      
         Initialize from environment 
      
      
        */
      
      
        if
      
       ((s = getenv (
      
        "
      
      
        loadaddr
      
      
        "
      
      )) !=
      
         NULL) {



         load_addr 
      
      = simple_strtoul (s, NULL, 
      
        16
      
      
        );



     }




      
      
        #if
      
       (CONFIG_COMMANDS & CFG_CMD_NET)



     
      
        if
      
       ((s = getenv (
      
        "
      
      
        bootfile
      
      
        "
      
      )) !=
      
         NULL) {



         copy_filename (BootFile, s, 
      
      
        sizeof
      
      
         (BootFile));



     }




      
      
        #endif
      
         /* CFG_CMD_NET */
      
        



 



#ifdef BOARD_LATE_INIT



     board_late_init ();




      
      
        #endif
      
      
        #if
      
       (CONFIG_COMMANDS & CFG_CMD_NET)




      
        #if
      
       defined(CONFIG_NET_MULTI)
      
        



     puts (
      
      
        "
      
      
        Net:   
      
      
        "
      
      
        );




      
      
        #endif
      
      
        



     eth_initialize(gd
      
      ->
      
        bd);




      
      
        #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 
      
      
        */
      
      
        



}



 




      
      
        void
      
       hang (
      
        void
      
      
        )



{



     puts (
      
      
        "
      
      
        ### ERROR ### Please RESET the board ###\n
      
      
        "
      
      
        );



     
      
      
        for
      
      
         (;;);



}



 .......



后面是modem的配置 不用管
      
    

 

uboot之board.c源码分析


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论