Decide to analyze u-boot-1.1.4 source code from scratch (2)

Source: Internet
Author: User
Jump from the Assembly startup code and go to the start_armboot function void start_armboot (void) in \ u-boot-1.1.4 \ lib_arm \ board. c)
{
Declare_global_data_ptr; ulong size;
Init_fnc_t ** init_fnc_ptr;
Char * s;
# 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-example _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); monitor_flash_len = _ bss_start-_ armboot_start; For (init_fnc_ptr = init_sequence; * init_fnc_ptr; + + callback ){
If (* init_fnc_ptr )()! = 0 ){
Hang ();
}
}/* Configure available Flash banks */
Size = flash_init ();
Display_flash_config (size); # 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-cmd_malloc_len); # If (config_commands & cfg_assist_nand)
Puts ("NAND :");
Nand_init ();/* Go init the NAND */
# 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 * // * IP Address */
GD-> BD-> bi_ip_addr = getenv_ipaddr ("ipaddr");/* MAC address */
{
Int I;
Ulong reg;
Char * s, * E;
Uchar 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;
}
} Devices_init ();/* Get the devices list going. */# ifdef config_cmc_pu2
Load_sernum_ethaddr ();
# Endif/* config_cmc_pu2 */jumptable_init (); lele_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 & cmd_cmd_net)
If (S = getenv ("bootfile "))! = NULL ){
Copy_filename (bootfile, S, sizeof (bootfile ));
}
# Endif/* cmd_cmd_net */# ifdef board_late_init
Board_late_init ();
# Endif
# If (config_commands & cmd_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 handle T booting */
} This function first declared a macro declare_global_data_ptr, macro definition in the u-boot-1.1.4 \ include \ ASM-Arm \ global_data.h file # define declare_global_data_ptr register volatile gd_t * gd asm ("R8 ") the gd_t struct is used to define a pointer variable GD. The keyword register is used frequently. Therefore, the variable is stored in the CPU register R8 to increase the speed. the gd_t type is defined in the global_data.h file as follows: typedef struct global_data {
Bd_t * BD;
Unsigned long flags;
Unsigned long baudrate;
Unsigned long have_console;/* serial_init () was called */
Unsigned long reloc_off;/* relocation offset */
Unsigned long env_addr;/* address of Environment struct */
Unsigned long env_valid;/* checksum of Environment valid? */
Unsigned long fb_base;/* base address of Frame Buffer */
# Ifdef config_vfd
Unsigned char vfd_type;/* display type */
# Endif
# If 0
Unsigned long cpu_clk;/* CPU clock in Hz! */
Unsigned long bus_clk;
Unsigned long ram_size;/* Ram size */
Unsigned long reset_status;/* reset Status Register at boot */
# Endif
Void ** JT;/* Jump table */
} Gd_t; first, a BD-T pointer variable is defined in the first position. The BD-T type also defines typedef struct bd_info {In global_data.h {
Int bi_baudrate;/* serial console baudrate */
Unsigned long bi_ip_addr;/* IP Address */
Unsigned char bi_enetaddr [6];/* Ethernet adress */
Struct environment_s * bi_env;
Ulong bi_arch_number;/* unique ID for this Board */
Ulong bi_boot_params;/* where this Board expects Params */
Struct/* ram configuration */
{
Ulong start;
Ulong size;
} Bi_dram [config_nr_dram_banks];
} Bd_t; I still don't know what to do with these variables. I will go back later and then define the pointer init_fnc_t ** init_fnc_ptr; init_fnc_t in the same \ u-boot-1.1.4 \ lib_arm \ board. in C, it is defined as typedef int (init_fnc_t) (void). Why does it define (init_fnc_t) (void) as Int. _ ASM _ volatile _ ("": "Memory"); the following section is copied online: /* ---------------------------------------------------------------------------- */"_ ASM _" indicates that the following code is embedded assembly, and "ASM" is an alias of "_ ASM. "_ Volatile _" indicates that the compiler should not optimize the code, and the subsequent commands will remain unchanged. "volatile" is its alias. The brackets contain Assembly commands. Memory descriptor informs GCC:

1) do not re-sort the assembly instructions embedded in this section with the preceding commands. That is, before the embedded assembly code is executed, all the preceding commands are executed.
2) Do not cache variables in registers, because this Code may use memory variables which may change in unpredictable ways, therefore, GCC inserts necessary code to first write the variable values cached in the register back to the memory. If you access these variables later, you need to re-access the memory.

If the Assembly command modifies the memory, but GCC itself does not notice it, because there is no description in the output part, you need to add "Memory" in the description section to tell GCC that the memory has been modified, after GCC learns this information, it will insert the necessary commands before this command to write the variable values in the cache to the register back to the memory, if you want to use these variables again later, read them again.

This can also be achieved by using "volatile", but it is better to use "Memory" to add this keyword before each variable.

/* Struct */GD = (gd_t *) (_ armboot_start-example _malloc_len-sizeof (gd_t); the GD pointer variable defined in the previous gd_t struct is displayed, here, the GD pointer is initialized to the point. memset (void *) Gd, 0, sizeof (gd_t); clears the struct pointed by the GD pointer
GD-> BD = (bd_t *) (char *) Gd-sizeof (bd_t); initialize the BD pointer to the point
Memset (Gd-> BD, 0, sizeof (bd_t); clears the structure monitor_flash_len pointed by the BD pointer. This variable may be the length to be protected by flash (if Flash needs to be protected) the following loop executes the init_sequence array-defined function: For (init_fnc_ptr = init_sequence; * init_fnc_ptr; ++ init_fnc_ptr ){
If (* init_fnc_ptr )()! = 0 ){
Hang ();
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.