Sumsang Uboot Analysis Very Good article

Source: Internet
Author: User
Tags documentation prepare
Sumsang Uboot Analysis Very good article, so I decided to reprint, Good article spread and save.
https://www.cnblogs.com/xiaojiang1025/p/6496704.html
from 0 transplant uboot (ii) _uboot start-up process Analysis

After the configuration of the previous article, We have executed make to compile a uboot.bin, but this is not enough, first of all, at this time the uboot does not conform to the Samsung chip format requirements for bootloader, at the same time, the uboot.bin is not combined with our Development Board configuration, but also can not be used. To carry out such a personalized configuration, the precondition is to uboot boot process and the compilation system has some knowledge, this article mainly discusses the former. In Samsung's Soc, the start-up process can be divided into three stages BL0, BL1, BL2, BL3, Samsung's own manual on the BL1 interpretation is not the same, one is to run in Iram program is attributed to BL1; One is the Iram in the Samsung encryption code Bl1.bin as BL1, the remainder of Iram as BL2, this article uses the latter, their main division of labor is as follows: The start address of the Bl0:arm is 0 address, Samsung's chip will generally map 0 address to Irom, BL0 refers to Irom in the curing of the startup code, mainly responsible for loading BL1 BL1: Samsung for bootloader encryption code Bl1.bin, to be placed in the peripheral uboot.bin head, and part of the Uboot.bin loaded into the Iram to run. BL2: From (NAND/SD/USB) copy of the Uboot.bin head maximum 14K to Iram in the code to remove the remainder of the Bl1.bin, responsible for setting the CPU to SVC mode, close the MMU, shut down the interrupt, close Icache, turn off the watchdog, Initialize the DRAM, initialize the clock, initialize the serial port, set up the stack, verify the BL2 and move it to the DRAM high address, relocate to DRAM to perform BL3 BL3: Refers to the full code of Uboot executed in memory after the code redirection, is responsible for initializing the peripherals, Update vector table, clear BSS, prepare kernel boot parameters, load and run OS kernel

This process can be understood with the following diagram

We often say that the uboot is a two stage bootloader, refers to the above BL2 and BL3. BL2 mainly do hardware directly related to the initialization, the use of assembly preparation; BL3 mainly for operating system preparation environment, mainly written in C, where the arm platform as an example to analyze its start-up process. The following are the main files involved in the startup process

Arch/arm/cpu/armv7/start. S
Board/samsung/myboard/lowlevel_init. S
Arch/arm/lib/crt0. S
Arch/arm/lib/board.c
ARCH/SAMSUNG/MYBOARD/MYBOARD.C
BL2

BL2 's main file and task flow is as follows

Arch/arm/cpu/armv7/start. S
1. Set the CPU to SVC mode
2. Close the MMU
3. Close the cache
4. Jump to Lowlevel_init. S Low_level_init
Board/samsung/origen/lowlevel_init. S
5. Initializing the Clock
6. Initializing memory
7. Initialize the serial port
8. Turn off the watchdog
9. Jump to Crt0. S _main
arch/arm/lib/crt0. S
10. Setting up the Stack
11. Initializing the C operating environment
12. Call Board_init_f ()
ARCH/ARM/LIB/BOARD.C
Board_init_f The global information GD structure body fills
arch/arm/lib/crt0. S
14. The Code relocation------------BL2 's final work, after execution into the DRAM execution BL2start. S

Globl _start
 _start: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

--40--> Exception Vector table settings

126 Reset:
127         BL      save_boot_params
131         Mrs     R0, CPSR         Bic     r0, R0, # 0x1f
133         Orr     r0, R0, #0xd3
134         msr     cpsr,r0

--126--> setting the CPU to SVC mode

the following three lines of code are very important and are intersections of the BL2 startup process

154         BL      cpu_init_cp15
155         bl      cpu_init_crit
158         BL      _main

--154--> jump execution cpu_init_cp15, i.e. initialize CP15 coprocessor
--155--> Jump Execution Cpu_init_crit,
--158--> Jump Execution _main

287 ENTRY (CPU_INIT_CP15)
291         mov     r0, #0                  @ set up for MCR
292         mcr     p15, 0, R0, C8, C7, 0   @ I  Nvalidate tlbs
293         mcr     p15, 0, R0, C7, C5, 0   @ invalidate icache
294         mcr     p15, 0, R0, C7, C5, 6   @ Invalidate BP array
295         mcr     p15, 0, R0, C7, C10, 4  @ DSB
296         mcr     p15, 0, R0, C7, C5, 4   @ ISB
297 
301         MRC     p15, 0, R0, C1, C0, 0
302         Bic     r0, R0, #0x00002000     @ Clear Bits (--v-)
303         Bic     r0, R0, #0x00000007     @ clear bits 2:0 (-CAM)
304         orr<  C38/>r0, R0, #0x00000002     @ set bit 1 (--a-) Align
305         Orr     r0, R0, #0x00000800     @ set bit one (Z---)  BTB
307         Bic     r0, R0, #0x00001000     @ clear Bit (I) i-cache
311         mcr     p15, 0, R0, C1, C0, 0
312         mov     pc, LR                  @ back to my caller
313 Endproc (CPU_INIT_CP15)

--291--> Close Cache
--301--> Close the MMU

324 ENTRY (Cpu_init_crit)
331         b       lowlevel_init           @ Go setup pll,mux,memory
332 endproc (cpu_init_ Crit)

--331--> jumps to Lowlevel_init, located in "Board/samsung/origen/lowlevel_init. S "for board-level related settings. Lowlevel_init. S

This is the initialization file located in the directory, mainly to complete the initialization of the specific development Board, including clocks, memory and serial port and so on.

         system_clock_init bl         mem_ctrl_asm_init
 1: *//For         UART *         /. Uart_asm_init         bl tzpc_init     , pop {pc}
system_clock_init:
329 Uart_asm_ Init:
357 tzpc_init:

--82--> initializes the system clock, which jumps to 114 rows
--85--> initialization of system memory
--89--> Initialize UART serial port, jump to 329 lines
--90--> initialize Trustzoneprotectorcontroller, which jumps to 357 rows

Finish Lowlevel_init. S, according to the above three lines of code, the execution process should go back to start. s executes 156 lines to jump to _main crt0. S

The first task is to set up the stack and prepare the environment for the C language to run:

_main:
102 #if defined (CONFIG_NAND_SPL)
103/         * deprecated, use instead config_spl_build */
104         Ldr     sp, = (CONFIG_SYS_INIT_SP_ADDR)
#elif defined (config_spl_build) && defined (config_spl_stack)
106         Ldr     sp, = (config_spl_stack)
107 #else
108         ldr     sp, = (CONFIG_SYS_INIT_SP_ADDR)
109 #endif         bic     sp, SP, #7/      * 8-byte Alignment for ABI compliance */
111         Sub     sp, #GD_SIZE/    * Allocate one GD above SP */.         bic     sp, SP, #7/      * 8-byte alignment for ABI Compliance */
113         mov     R8, SP/          * GD is above SP */*         mov     r0, #0         bl< C36/>board_init_f

_main
--104--> Initialize SP, prepare for C language
--110--> Save 128B GD structure to hold the global information,
--111-->GD's address is placed in R8,
--115--> jumps to Board_init_f (), which executes the first C code of the entire initialization process BOARD.C

The following function is the first C function executed during uboot initialization, and can be thought of as the entry function for this file. One of the most important is to prepare the global information GD structure, the kernel boot parameters are derived from the struct

209 typedef INT (init_fnc_t) (void); 243 init_fnc_t *init_sequence[] = {244 Arch_cpu_init,/* Basic Arch CPU Dependent Setup */245 m
Ark_bootstage, 246 #ifdef config_of_control 247 FDTDEC_CHECK_FDT, ...
277 void Board_init_f (ULONG Bootflag) 278 {...
291 Gd->mon_len = _bss_end_ofs;
292 #ifdef config_of_embed 293/* Get A pointer to the FDT */294 gd->fdt_blob = _binary_dt_dtb_start; 295 #elif defined Config_of_separate 296/* FDT is at end of image */297 Gd->fdt_blob = (void *) (_end_
OFS + _text_base); 298 #endif 299/* Allow the early environment to override the FDT address */Gd->fdt_blob = (void *
) Getenv_ulong ("Fdtcontroladdr", 301 (uintptr_t) gd->fdt_blob); 302 303 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {304 if (*init_fnc_pt            R) ()! = 0) {305             Hang (); 306} 307} ...

Board_init_f ()
--243--> a global array of function pointers, each of which is of type int (*ptr) (void).
--291-->mon_len through the link script can know that the Uboot code size is stored;
--294-->fdt_blob storage device number address;
--303--iterates through each member of the function pointer array init_sequence, which is to execute once for each initialization function in the array, which can be borrowed from crt0. S

After the function board_init_f () returns, continue to execute crt0. s in the section after 115 lines, the main work is to perform the code relocation, after the execution of these, we found the most interested in the following sentence

163         /* Call Board_init_r (gd_t *id, ULONG dest_addr) */
164         mov     r0, r8/                  * gd_t */
165         ldr< C10/>R1, [R8, #GD_RELOCADDR]/* DEST_ADDR */166/Call         Board_init_r */
167         Ldr     pc, =board_ Init_r/* This is       auto-relocated! */

--167--> jump to Board_init_r function execution, this time to jump out of this file statement will be executed, will not come back, began to execute BL3. BL3

The documents and tasks involved in this phase are as follows

Arch/arm/lib/crt0. S
Arch/arm/lib/board.c

1. Board_init_r () is the entry into the Custom Board catalogue
Common/main.c
2. Main_loop () to turn off interrupts, execute commands, and load the boot kernel board.c

This is also the last time to jump to this file, the execution function is as follows

 519 void Board_init_r (gd_t *id, ulong dest_addr) 520 {521 ulong Malloc_start; 522 #if!defined (config_sys_no
_flash) 523 ULONG Flash_size;      524 #endif 525 526 gd->flags |= Gd_flg_reloc;
/* Tell others:relocation-Done */527 bootstage_mark_name (Bootstage_id_start_uboot_r, "Board_init_r");
528 529 Monitor_flash_len = _end_ofs;
530 531/* Enable caches */532 enable_caches ();
533 534 Debug ("Monitor Flash Len:%08lx\n", Monitor_flash_len);   535 Board_init ();
/* Setup chipselects */...
650/* Set up exceptions */651 interrupt_init (); 
652/* Enable exceptions */653 enable_interrupts ();
        667 eth_initialize (GD->BD);
... 701/* Main_loop () can return to retry autoboot, if so just run it again. */702 for (;;) {703 Main_loop (); 704} 705 

Board_init_r ()
--532--> a lot of emergency work is done, you can open the cache.
--535--> Key!!! This is the entry function for the xxx.c of board-level custom files We are looking for ...
--651--> Interrupt Initialization
--653--> Enable interrupt
--667--> Network card initialization, the implementation of the function in Net/eth.c, will callback the board level xxx.c in the Board_eth_init ()
--703-->** executes Main_loop (), implemented in COMMON/MAIN.C, its main function is to loop through the input command and execute, one of the environment variable bootdelay (self-starting) setting determines whether to start the kernel, if the delay is greater than or equal to zero, And does not receive the key during the delay, the boot kernel main.c

This file is the file where the Main_loop () is located, whether it is the boot kernel, printing information or input commands are executed in this function, we are here to focus on how this function starts the kernel, the function of the call relationship is as follows:

Main_loop ()
├──getenv
│└──getenv_f
│├──env_get_char
│└──envmatch
└──run_command_list
└──builtin_run_command_list
└──builtin_run_command
├──process_macros
├──parse_line
└──cmd_process
├──find_cmd
├──cmd_call
│└──cmdtp->cmd//Find the command Do_bootm
│└──bootm_start
│└──boot_start_lmb
│└──arch_lmb_reserve (struct LMB *LMB)
│└──cleanup_before_linux
│└──disable_interrupts//Shutdown interrupt
└──cmd_usage
└──bootm_load_os

The above is the Uboot start Linux in general to do the final workflow, Uboot do so much, in fact, in order to boot the OS kernel, for Arm Linux, it on the pre-boot environment requirements in the kernel document "/documentation/ Kernel-parameters.txt " and " Documentation/arm/booting "are described, which explains why Uboot did the work above. The following 6 requirements have been made in the documentation for booting the Linux kernel in the arm platform: Setup and initialise the RAM.

The ram here refers to DRAM, because the Linux kernel needs to run in DRAM, and the DRAM has to be initialized, which is done in BL2. initialise one serial port.

Initialize a serial port, bootloader should initialize a serial port, so that the core serial driver can automatically detect the console for the serial port is which
Bootloader can use console= in TagList to specify a serial port, which is also done Detect the machine type in BL2 .

Probe board type, the Linux kernel needs to know the type of the board they run, this part of the work is also given to bootloader to complete, bootloader through some way to obtain the type of the board, according to the kernel source "arch/arm/tools/ Mach-types , the type number of the board is stored in the R1 Register
Setup the kernel tagged list.

Set up the tag list, which is the kernel parameters, in the kernel source code and Uboot source code used a struct tag to describe. The data structure tag and tag_header are defined in the "Include/asm/setup.h" header file of the Linux kernel source code: The valid Tagged list must start with Atag_core and end with Atag_none, empty The size field of the Atag_core is 0x00000002, and the size field of Atag_none is 0. List can be placed any number of tags, the name of the same tag is undefined, the final value may be the previous, or it may be after the bootloader at least the location of the system memory, the size of the memory and the location of the root file system to pass to the kernel Taggedlist location cannot conflict with kernel self-extracting area or INITRD BOOTP program, prevent rewriting, recommended address is RAM header 16KB

Bootloader must place DTB in the initialized memory of 64bit alignment, DTB in "Documentation/devicetree/booting-without-of.txt" , which defines the size of the device tree

struct Boot_param_header {
__be32 magic;                   Device Tree magic number, fixed to 0xd00dfeed
__be32 totalsize;               The size of the entire plant tree
__be32 off_dt_struct;           Save the offset of the structure block in the entire device tree
__be32 off_dt_strings;          The saved string block is offset __be32 off_mem_rsvmap in the device tree
;          Preserves the memory area, which retains the memory space that cannot be dynamically allocated by the kernel
__be32 version;                 Device tree version
__be32 last_comp_version;       Backward compatible version number
__be32 Boot_cpuid_phys;         __be32 dt_strings_size for the physical ID of the primary CPU used for booting in a multi-core processor
;         String block size
__be32 dt_struct_size;          Structure block size
};

In the kernel about the boot parameters of the Convention, it is believed that the address in the R2 may be the address of the device tree, or the address of the tagged list, so, after getting this address, the kernel's first job is to determine exactly what it is, The basis of judgment is to determine whether the first 32bit is stored on the device Tree magic number 0xd00dfeed or Atags_core. See the kernel "Arch/arm/kernel/head-common.h", here I have a question, since R2 may store DTB address, then how to find the kernel is tagged list ... . The actual development of the tagged list is generally placed in the address of the R2. The kernel recommends placing the DTB at 128MB at the start of Ram Load Initramfs.

Loading Ramfs,ramfs recommended exactly on the device tree calling the kernel image

Boot the kernel image, if the use of zimage,bootloader in Flash can directly load Zimage into memory and execute, the Linux kernel to the address of the non-zimage kernel image has stricter requirements ———— the mirror must be loaded into the Page_ OFFSET + text_offset Place . Page_offset defines the starting address of the kernel space in the virtual address space, which is 3GB in the 32bit system. Text_offset represents the size of a piece of space in the kernel space that is used to hold the kernel's page table (that is, the PGD for process 0), the bootload, and the kernel pass parameter, for the Arm,text_offset is 32kB, due to the first 896MB of the kernel space ( 3GB~3GB+896MB) is one by one mapped, so the kernel is loaded into the physical address 0x4000 0000 is actually loaded into the virtual address space 3GB, considering the above 32KB to save the page table, kernel parameters, etc., we need to extract the kernel to 0x40008000 run, That is, the virtual address (3GB+32KB), if you use Uimage, this parameter is written to the file header when the uimage is made. Our startup parameters in the Uboot are usually not specified to load to this address, because the kernel self-extracting will be moved to the 0x40008000 to start execution, if we specify this address, then the kernel will be removed from the first, the decompression and then move back to execute, Prevents the uncompressed part from being overwritten during the decompression process to cause errors.

Regardless of the boot mode, the kernel must be started to meet the following conditions: r0=0;r1= board type model; r2= kernel tagged list or device tree address all IRQ Fiq must be closed must be arm State, SVC mode MMU must be closed Icache can be turned off or no matter dcache must be turned off DMA device must be turned off

We have analyzed the boot framework for the entire uboot, and in the details, Uboot must complete the above work to meet the Linux startup requirements.

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.