Uboot startup process analysis

U-Boot U-Boot, short for Universal Boot Loader, is an open-source project governed by the GPL license. Its primary function is to initialize and boot a system. U-Boot evolved from earlier projects like FADSROM, 8xxROM, and PPCBOOT. The source code structure and build process of U-Boot are very similar to that of the Linux kernel. In fact, many parts of the U-Boot source code are derived from corresponding Linux kernel code, especially device drivers. This can be seen in the comments within the code. U-Boot supports not only embedded Linux systems but also other operating systems such as NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, and Android. Currently, it supports a wide range of operating systems including OpenBSD, NetBSD, FreeBSD, 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS, and Android. This reflects the "Universal" aspect of U-Boot. Another key feature is its support for multiple processor architectures, such as PowerPC, MIPS, x86, ARM, NIOS, and XScale. These two characteristics define the development goals of the U-Boot project: supporting as many embedded processors and operating systems as possible. At present, U-Boot has the most comprehensive support for the PowerPC family and the most complete support for Linux. Other processor families and OSs were gradually added after PPCBOOT was renamed to U-Boot in November 2002. The smooth transition from PPCBOOT to U-Boot was largely due to the professional efforts of Wolfgang Denk from DENX Software Engineering in Germany. Today, the U-Boot project continues under his leadership, with many developers contributing to expand and enhance support for various embedded processors and operating systems.

Uboot startup process analysis

Uboot Startup Process Analysis From the code, we can see that the program entry point is at `_start`. The `_start` symbol is located in `u-boot-2016.05\arch\arm\lib\vectors.S`. ``` ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { *(.__image_copy_start) *(.vectors) CPUDIR/start.o (.text*) *(.text*) } ... } ``` After jumping from `_start`, the code jumps to `reset` for execution: ``` .globl _start ... _start: #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG .word CONFIG_SYS_DV_NOR_BOOT_CFG #endif b reset Ldr pc, _undefined_instruction Ldr pc, _software_interrupt Ldr pc, _prefetch_abort Ldr pc, _data_abort Ldr pc, _not_used Ldr pc, _irq Ldr pc, _fiq ... ``` **1. Reset Execution from `u-boot-2016.05\arch\arm\cpu\arm920t\start.S`** The main execution flow is: `reset -> cpu_init_crit -> lowlevel_init -> _main`. ``` Reset: #ifndef CONFIG_SKIP_LOWLEVEL_INIT Bl cpu_init_crit #endif Bl _main ... ``` **2. Jump from `bl _main` to `u-boot-2016.05\arch\arm\lib\crt0.S` via `_main`** The main execution flow is: `board_init_f -> relocate_code -> board_init_r`. ``` ENTRY(_main) ... Bl board_init_f_alloc_reserve ... Bl board_init_f #if !Defined(CONFIG_SPL_BUILD) b relocate_code #endif ... ENDPROC(_main) ``` There are three key points in this section: 1. In `u-boot-2016.05\common\board_f.c`, `board_init_f` runs a series of initialization functions using `initcall_run_list(init_sequence_f)` to complete the first half of board-level initialization. The global data structure `gd` is declared in `u-boot-2016.05\arch\arm\include\asm\global_data.h`. 2. In `u-boot-2016.05\arch\arm\lib\relocate.S`, `relocate_code` handles the relocation of U-Boot code. If the code seems complex, you can rewrite it yourself. 3. There are two paths for relocating U-Boot: one sets `gd->flags` to 0 and calls `relocate_code` via `jump_to_copy`, while the other skips `CONFIG_SPL_BUILD` and directly calls `relocate_code`. **3. After the previous step, enter `u-boot-2016.05\common\board_r.c:board_init_r` through `ldr pc, =board_init_r`**, then call `initcall_run_list(init_sequence_r)` to execute a series of initialization functions for the second half of board-level initialization, and finally enter `run_main_loop`. ``` void board_init_r(gd_t *new_gd, ulong dest_addr) { ... if (initcall_run_list(init_sequence_r)) Hang(); /* NOTREACHED - run_main_loop() does not return */ Hang(); } ``` `init_sequence_r` is an array of function pointers, which includes important functions like `initr_announce` and `run_main_loop`. **4. Enter `u-boot-2016.05\common\main.c: main_loop`** Before entering `main_loop`, initialization is completed, and the system is ready to process commands. ``` static int run_main_loop(void) { ... for (;;) main_loop(); return 0; } ``` In the `main_loop` function, there are two key processes: 1. In `bootdelay_process`, the `bootcmd` parameter is retrieved via `s = getenv("bootcmd")`. 2. Then, `autoboot_command` is called with the `bootcmd` parameter, which triggers `run_command_list`. **5. After entering `u-boot-2016.05\common\cli.c:run_command_list`, the `board_run_command` function is called to execute the command.** ``` int run_command_list(const char *cmd, int len, int flag) { ... rcode = board_run_command(buff); ... } ``` The `board_run_command` function finds the `bootm` command in the `bootcmd` parameter and executes the `do_bootm` function. ``` U_BOOT_CMD( bootm, CONFIG_SYS_MAXARGS, 1, do_bootm, "boot application image from memory", bootm_help_text ); ``` This defines the command and its handler function pointer `do_bootm`. The `bootm_headers_t` structure variable `images` is used to store the kernel image address, which is `30000000` in this example.

For Pixel Glass

For Pixel Glass,Pixel Glass,Google Pixel 4 Xl Glass,Google Pixel 6 Pro Front Glass

Dongguan Jili Electronic Technology Co., Ltd. , https://www.jlglassoca.com