Uboot Entrance
Arch/arm/lib/crt0. S
#include <config.h> #include <asm-offsets.h> #include <linux/linkage.h>/* * This file handles the Target-independent stages of the u-boot * start-up where a C runtime environment is needed. Its entry point * is _main and is branched to from the target ' s start. S file. * * _main execution sequence is: * * 1. Set up initial environment for calling Board_init_f (). * This environment-provides a stack and a place-to-store * The GD (' Global data ') structure, both located in so Me readily * available RAM (SRAM, Locked cache ...). In the context, VARIABLE * Global data, initialized or not (BSS), is unavailable; Only * CONSTANT initialized data is available. * * 2. Call Board_init_f (). This function prepares the hardware for * execution from System RAM (DRAM, DDR ...) As System RAM may is available yet, board_init_f () must use the current GD to * store any data which must is Passed on to later stages. These * data include the relocation DEstination, the future stack, and * The future of GD location. * * (The following applies only to NON-SPL builds) * * 3. Set up intermediate environment where the stack and GD is the * ones allocated by Board_init_f () on system RAM, but BS S and * Initialized Non-const data is still not available. * * 4. Call Relocate_code (). This function relocates u-boot from it * Current location to the relocation destination computed by * board_init_ F (). * * 5. Set up final environment for calling Board_init_r (). This * environment have BSS (initialized to 0), initialized non-const * data (initialized to their intended value), a nd stack in System * RAM. GD has retained values set by Board_init_f (). Some CPUs * has Some work of the left-to-do at this point regarding memory, so * call C_runtime_cpu_setup. * * 6. Branch to Board_init_r (). *//* * entry point of Crt0 sequence */entry (_main)/* Set up initial C runtime environment and call Board_init_f (0). */#if defined (config_spL_build) && defined (config_spl_stack) ldrsp, = (config_spl_stack) #elseldrsp, = (config_sys_init_sp_addr) # ENDIFBICSP, SP, #7/* 8-byte alignment for ABI compliance */movr2, spsubsp, SP, #GD_SIZE/* Allocate one GD above SP */BICSP , SP, #7/* 8-byte alignment for ABI compliance */MOVR9, sp/* GD are above SP */MOVR1, Spmovr0, #0clr_gd: CMPR1, r2/* while N OT at end of GD */strlor0, [r1]/* clear 32-bit gd word */addlor1, r1, #4/* Move to next */bloclr_gd#if defined (config_sys_ Malloc_f_len) subsp, sp, #CONFIG_SYS_MALLOC_F_LENstrsp, [R9, #GD_MALLOC_BASE] #endif/* mov r0, #0 not needed due to above co De */blboard_init_f#if! Defined (config_spl_build)/* * Set up Intermediate environment (new SP and GD) and call * Relocate_code (Addr_moni). Trick Here's that we'll return * ' here ' but relocated. */LDRSP, [R9, #GD_START_ADDR_SP]/* sp = gd->start_addr_sp */bicsp, SP, #7/* 8-byte alignment for ABI compliance */LDRR9 , [R9, #GD_BD]/* R9 = gd->bd */subr9, R9, #GD_SIZE/* New GD is below BD */ADRLR,Hereldrr0, [R9, #GD_RELOC_OFF]/* r0 = Gd->reloc_off */ADDLR, LR, r0ldrr0, [R9, #GD_RELOCADDR]/* r0 = gd->relocaddr * /brelocate_codehere:/* * Now relocate vectors */blrelocate_vectors/* Set up final (full) environment */blc_runtime_cpu_se tup/* we still call old routine here * * #endif # if!defined (config_spl_build) | | Defined (config_spl_framework) # ifdef config_spl_build/* use a DRAM stack for the rest of SPL, if requested */blspl_relocat E_stack_gdcmpr0, #0movnesp, r0# endifldrr0, =__bss_start/* this is auto-relocated! */#ifdef CONFIG_USE_ARCH_MEMSETLDRR3, =__bss_end/* this is auto-relocated! */MOVR1, #0x00000000/* Prepare zero to clear BSS */SUBSR2, r3, r0/* r2 = memset len */blmemset#elseldrr1, =__bss_end/* Thi S is auto-relocated! */MOVR2, #0x00000000/* Prepare zero to clear BSS */clbss_l:cmpr0, r1/* and not at end of BSS */strlor2, [r0]/* Clear 32- Bit BSS word */addlor0, r0, #4/* move to Next */bloclbss_l#endif#if! Defined (config_spl_build) BL coloured_led_initbl Red_led_on#endif/* Call Board_init_r (gd_t *id, ulong dest_addr) */mov r0, R9/* gd_t */ldrr1, [R9, #GD_RELOCADDR]/* Dest_addr *//* Call Board_init_r */ldrpc, =<span style= "color: #FF0000;" >board_init_r</span>/* this is auto-relocated! *//* we should not return here. */#endif
BOARD/FREESCALE/MX6SABRESD under the MX6SABRESD.C
void Board_init_f (ULONG dummy) {/* Setup AIPS and disable watchdog */arch_cpu_init (); Ccgr_init (); Gpr_init ();/* Iomux and S Etup of I²c */board_early_init_f ();/* Setup GP timer */timer_init ();/* UART clocks enabled and GD Valid-init serial cons Ole */preloader_console_init ();/* DDR initialization */spl_dram_init ();/* Clear the BSS. */memset (__bss_start, 0, __bss_end-__bss_start);/* Load/boot image from boot device */<span style= "color: #FF0000;" >board_init_r (NULL, 0); </span>}
The function board_init_r (NULL, 0) finally calls the ARCH/ARM/LIB/BOARD.C
void Board_init_r (gd_t *id, ulong dest_addr) {ulong Malloc_start; #if!defined (config_sys_no_flash) ULONG flash_size;# Endifgd->flags |= gd_flg_reloc;/* Tell others:relocation done */bootstage_mark_name (Bootstage_id_start_uboot_r, " Board_init_r "); Monitor_flash_len = (ULONG) &__rel_dyn_end-(ULONG) _start;/* Enable caches */enable_caches ();d Ebug ("Monitor Flash Len:%08lx\n", Monitor_flash_len); Board_init ();/* Setup chipselects *//* * todo:printing of the clock inf Oramtion of the board is now * implemented as part of the Bdinfo command. Currently for * DaVinci SOC's is added. Remove this check once all the board * implement. */#ifdef Config_clocksset_cpu_clk_info (); /* Setup Clock information */#endifserial_initialize ();d ebug ("Now running in Ram-u-boot at:%08lx\n", dest_addr); #ifdef Config_logbufferlogbuff_init_ptrs (); #endif #ifdef Config_postpost_output_backlog (); #endif/* The Malloc area is Immediately below the monitor copy in DRAM */malloc_start = Dest_addr-total_malloc_len;mem_malloc_init (Malloc_start, Total_malloc_len); #ifdef Config_arch_early_init_rarch_early_init_r (); Endifpower_init_board (); #if!defined (Config_sys_no_flash) puts ("FLASH:"); flash_size = Flash_init (); if (flash_size > 0) {# ifdef config_sys_flash_checksumprint_size (Flash_size, "");/* * Compute and print FLASH CRC if Flashchecksum is Set to ' y ' * * note:maybe we should add some watchdog_reset ()? XXX */if (Getenv_yesno ("flashchecksum") = = 1) {printf ("CRC:%08x", CRC32 (0, (const unsigned char *) config_sys_flash_base , flash_size));} PUTC (' \ n '); # else/*! Config_sys_flash_checksum */print_size (flash_size, "\ n"); # endif/* config_sys_flash_checksum */} else {puts (failed); Hang ();} #endif # if defined (Config_cmd_nand) puts ("NAND:") nand_init ();/* Go init the NAND */#endif # if defined (config_cmd_ Onenand) Onenand_init (); #endif #ifdef config_generic_mmcputs ("MMC:"); Mmc_initialize (GD->BD); #endif #ifdef CONFIG _cmd_scsiputs ("SCSI:"); Scsi_init (); #endif #ifdef config_has_dataflashat91f_Dataflashinit ();d ataflash_print_info (); #endif/* Initialize Environment */if (should_load_env ()) env_relocate (); Elseset_default_env (NULL); #if defined (CONFIG_CMD_PCI) | | Defined (CONFIG_PCI) arm_pci_init (); #endif <span style= "color: #FF0000;" >stdio_init ();/* Get the devices list going. */</span>jumptable_init (); #if defined (CONFIG_API)/* Initialize API */api_init (); #endifconsole_init_r ();/* Fully init console as a device */#ifdef config_display_boardinfo_late# ifdef config_of_control/* Put This here so it APPEA RS on the LCD, now it's ready */display_fdt_model (Gd->fdt_blob); # Elsecheckboard (); # endif#endif#if defined (config_ar Ch_misc_init)/* Miscellaneous arch Dependent initialisations */arch_misc_init (); #endif # if defined (config_misc_init_r )/* Miscellaneous platform Dependent initialisations */misc_init_r (); #endif/* Set up exceptions */interrupt_init ();/* en Able exceptions */enable_interrupts ();/* Initialize from environment */load_addr = Getenv_ulong ("loadaddr", +, Load_ Addr; #ifdef Config_board_late_initboard_late_init (); #endif #ifdef Config_fsl_fastbootfastboot_setup (); #endif #ifdef Config_bitbangmiibb_miiphy_init (); #endif # if defined (config_cmd_net) puts ("NET:"); Eth_initialize (GD->BD); #if Defined (config_reset_phy_r) debug ("RESET Ethernet phy\n"); Reset_phy (); #endif #endif#ifdef Config_postpost_run (NULL, Post_ram | Post_bootmode_get (0)); #endif # if defined (Config_pram) | | Defined (config_logbuffer)/* * Export available size of memory for Linux, * Taking to account the protected RAM at top of Memory */{ulong pram = 0;uchar memsz[32]; #ifdef Config_prampram = Getenv_ulong ("Pram", ten, Config_pram); #endif #ifdef CONF Ig_logbuffer#ifndef config_alt_lb_addr/* Also Take the Logbuffer to account (pram are in KB) */pram + = (Logbuff_len + LOG Buff_overhead)/1024x768; #endif #endifsprintf ((char *) MEMSZ, "%ldk", (gd->ram_size/1024)-pram); Setenv ("Mem", (char *) m EMSZ);} #endif #ifdef config_fsl_fastbootcheck_fastboot (); #endif/* Main_loop () can return to retry Autoboot, if So just run it again. */for (;;) {Main_loop ();} /* Notreached-no-out-of-command loop except booting */}
Here we focus on the Stdio_init () function, which is implemented in the function in COMMON/STDIO.C
int Stdio_init (void) {stdio_init_tables (); <span style= "color: #FF0000;" >stdio_add_devices (); </span>return 0;}
int stdio_add_devices (void) {#ifdef config_sys_i2ci2c_init_all (); #else # if defined (CONFIG_HARD_I2C) i2c_init (config_ Sys_i2c_speed, Config_sys_i2c_slave), #endif #endif#ifdef config_lcddrv_lcd_init (), #endif # if defined (config_video) | | Defined (config_cfb_console) <span style= "color: #FF0000;" >drv_video_init ();</span> #endif #ifdef config_keyboarddrv_keyboard_init (); #endif #ifdef CONFIG_ Logbufferdrv_logbuff_init (); #endifdrv_system_init (); Serial_stdio_init (); #ifdef config_usb_ttydrv_usbtty_init (); #endif #ifdef config_netconsoledrv_nc_init (); #endif #ifdef config_jtag_consoledrv_jtag_console_init (); #endif #ifdef Config_cbmem_consolecbmemc_init (); #endifreturn 0;}
int Drv_video_init (void) {int skip_dev_init;struct stdio_dev console_dev;/* Check If video initialization should be Skippe D */<span style= "color: #FF0000;" >if (Board_video_skip ()) </span>return 0;/* Init video chip-returns with framebuffer cleared */<span style= "c Olor: #FF0000; " >skip_dev_init = (Video_init () = =-1); </span>if (Board_cfb_skip ()) return 0; #if!defined (Config_vga_as_single _device) Debug ("Kbd:keyboard init ... \ n"); Skip_dev_init |= (VIDEO_KBD_INIT_FCT = =-1); #endifif (Skip_dev_init) return 0 ;/* Init VGA device */memset (&console_dev, 0, sizeof (Console_dev)); strcpy (Console_dev.name, "VGA"); console_ Dev.ext = dev_ext_video;/* VIDEO Extensions */console_dev.flags = Dev_flags_output | DEV_FLAGS_SYSTEM;CONSOLE_DEV.PUTC = video_putc;/* ' putc ' function */console_dev.puts = video_puts;/* ' puts ' function */# If!defined (config_vga_as_single_device)/* Also init console DEVICE */console_dev.flags |= dev_flags_input;console_ DEV.TSTC = video_tstc_fct;/* ' TSTC ' functiOn */console_dev.getc = video_getc_fct;/* ' getc ' function */#endif/* Config_vga_as_single_device */if (Stdio_register (& Amp;console_dev)! = 0) Return 0;/* return success */return 1;}
Board_video_skip Gets the screen parameters to initialize ARCH/ARM/IMX-COMMON/VIDEO.C
int Board_video_skip (void) {int i;int ret;char const *panel = getenv ("Panel"), if (!panel) {for (i = 0; i < Display_count ; i++) {struct display_info_t const *DEV = displays+i;if (dev->detect && dev->detect (dev)) {panel = Dev->mo de.name;printf ("auto-detected panel%s\n", panel); break;}} if (!panel) {panel = displays[0].mode.name;printf ("No panel Detected:default to%s\n", panel); i = 2;}} else {for (i = 0; i < Display_count; i++) {if (!strcmp (panel, displays[i].mode.name)) break;}} if (I < display_count) {ret = <span style= "color: #FF0000;" >ipuv3_fb_init</span> (&displays[i].mode, 0, displays[i].pixfmt); if (!ret) {if (displays[i].enable) Displays[i].enable (displays + i);p rintf ("Display:%s (%ux%u) \ n", Displays[i].mode.name, Displays[i].mode.xres, Displays[i].mode.yres);} elseprintf ("LCD%s cannot be configured:%d\n", Displays[i].mode.name, ret);} else {printf ("Unsupported panel%s\n", panel); return-einval;} return 0;
Finally call Video_init to initialize the screen and display the logo
void Video_inti (void)
{
------
Video_hw_init//Screen initialization (according to the parameters obtained above)
Video_logo ();//Brush logo (located in Tools/logos/xxx.bmp, the BMP bitmap is compiled into an array, eventually be brushed out)
------
}
In the process of brushing the logo will call Flush_cache refresh the buffer, otherwise the image will become discrete.
if (Cfb_do_flush_cache)
Flush_cache (Video_fb_adrs, video_size);
Video_fb_adrs Show Base Address
Video_size the size of the display
There are many debug functions in Uboot, and the debug function can be opened to see the call procedure of a function in Uboot.
The Dedug function (include/common.h) is defined as
#ifdef debug#define _debug1#else#define _debug0#endif#ifndef pr_fmt#define pr_fmt (FMT) fmt#endif/* * Output a DEBUG text W Hen condition "cond" is met. The "cond" should is * computed by a preprocessor in the best case, allowing for the best * optimization. */#define DEBUG_COND (Cond, FMT, args ...) Do {if (cond) printf (PR_FMT (FMT), # #args) and} while (0) #define DEBUG (FMT, args ...) Debug_cond (_DEBUG, FMT, # #args)
Just add # define debug in front to open the function.
In addition, when looking for a function call relationship, if there is more than one definition, and you are unsure of the specific location, simply go to that directory and Ls-al *.O to confirm the function that is actually called. Because the function is compiled, it will
Generate an. o file.
Uboot Debug Summary (Freescale Platform for example)