ZZ from:http://blog.csdn.net/ly601579033/article/details/48318239
=============================================================
The general flowchart is as follows:
After power-on, the Reset,arm core starts executing the Boot ROM, with the following actions: (code is cured in ROM)
1. Initialize the built-in SRAM stack
2, initialize the NAND/EMMC (mobile phone built-in storage)
3. Import the pre-loader stored in NAND into the SRAM
4. Jump to SRAM to execute Pre-loader
Perform Pre-loader operations in built-in SRAM: (Operation to Bootloader/preloader) < code under Preloader directory >
1. Configure C Run Environment (register, stack, BSS, etc.) BSS static memory segment (uninitialized), data segment (initialize), heap segment, stack segment
2, initialization of external DRAM timer, clock, UART, EMI (DRAM anti-static interference)
3. Jump to dram execution lk (little kernel) <LK code is transferred to DRAM >
The specific source code is as follows:
Execute an LD link script first--Display part (LINK_DESCRIPTOR.LD file on Bootable/bootloader/preloader platform)
Output_arch (ARM)
ENTRY (_start)//Enter _start execution
Rombase = 0x00201000;
Rambase = 0x00102180;
MEMORY {
Ram:origin= rambase, LENGTH = 0xba80
Rom:origin= rombase, LENGTH = 0x1f000
}
_start in Init.s, define C Runtime environment in LD (C Run Environment (register, stack, BSS, etc.) is initialized here
. globl _start
_start:
b Resethandler
... ... ...
Resethandler://reset operation, and disable IRQ
LDR r6,=bldr_args_addr
STR R4, [R6]
MOV R0, #0
... ... ... ...
LDR r0, =bldr_args_addr//Jump operation, BLDR_ARGS_ADDR address previously defined
B Main
Enter the Main.c file to perform the main operation
void Main (U32 *arg) {
Mtk_uart_init (Uart_src_clk_frq, cfg_log_baudrate);
Bldr_pre_process (); Timer, clock, UART settings for external Rwam
Bldr_handshake (&handler); UART, USB handshake test (guaranteed to communicate)
Bldr_load_images; Import Uboot image (the mirror address is defined within this function addr)
Bldr_post_process ();
Bldr_jump (Jump_addr,jump_arg, sizeof (boot_arg_t)); Jump to dram execution
}
When we jump to the dram to do LK, what parameters are passed.
Bldr_jump (jump_addr, Jump_arg, sizeof (boot_arg_t));
1. jump_addr jump to LK execution address
2. The address of the parameter is passed to LK
3, the size of the passed parameter
The data of a boot_arg_t structure is passed, and the structure data is defined under the Platform_set_boot_args () function of the PLATFORM.C.
Jump to LK Execution < code under the LK directory >
For the initialization of the peripheral in LK , load the kernel and start the Android system initialization, as follows:
1. Get the parameters passed by Pre-loader
2. Enable MMU Unit
3. Enabling Peripherals
4, set boot mode (here can enter fastboot mode)
5. Import Kernel
6. Transfer to Kernel for loading
Jump to LK, in LK\ARCH\ARM\CRT0.S
. globl _start
_start:
b Reset
... ... ...
Reset
LDR R6, =boot_argument_location//Transfer of register data to R6
STR r4, [R6]
After this file is executed, it jumps to Kmain execution (via BL kmain)
Kmain in the LK/KERNEL/MAIN.C.
void Kmain (void) {
Initialize the thread queue, create a BOOTSTRAP2 thread, and join the queue, where you can see that there are 6 states of the thread
Thread_init_early ();
Six states are defined as follows:
Enum Thread_state {
thread_suspended= 0,//Abort
Thread_ready,//preparation
Thread_running,//Run
Thread_blocked,//block
Thread_sleeping,//Hibernate
Thread_death,//death
};
MMU initialization, correlation register initialization
Arch_early_init ();
Interrupt initialization, timer initialization preparation, GPIO initialization, UART initialization, WDT (watchdog) initialization, SRAM repair, I²C firmware initialization, LED initialization (backlight), pmic initialization (Power)
Platform_early_init ();
Null operation, no meaning here
Target_early_init ();
dprintf (INFO, "Welcome to lk\n\n");
constructor, loop execution defines the func in the. Ctros
dprintf (Spew, "calling constructors\n");
Call_constructors ();
Thekernel Heap Initialization
dprintf (Spew, "initializing heap\n");
Heap_init ();
Initialize the threading system
dprintf (Spew, "initializing threads\n");
Thread_init ();
Soft Interrupt System
dprintf (Spew, "initializing dpc\n");
Dpc_init ();
Timer initialization
dprintf (Spew, "initializing timers\n");
Timer_init ();
#ifdef Mtk_lk_irrx_support
Mtk_ir_init (0);
#endif
#if (! Enable_nandwrite)
Resume Thread BOOTSTRAP2
dprintf (Spew, "creating bootstrap Completion thread\n");
Thread_resume (Thread_create ("Bootstrap2", &bootstrap2, Null,default_priority,default_stack_size));
Enableinterrupts
Exit_critical_section ();
Turn the current thread into an idle thread
Thread_become_idle ();
#endif
}
The current thread becomes idle and the new thread bootstrap2 is turned on. The thread priority is default_priority, and the definition of the column outgoing priority is:
/* Thread Priority */
#define Num_priorities 32
#define LOWEST_PRIORITY 0//Lowest priority 0
#define HIGHEST_PRIORITY (NUM_PRIORITIES-1)//Highest priority 31
#define Dpc_priority highest_priority//Highest priority 31
#define Idle_priority lowest_priority//Idle minimum priority 0
#define LOW_PRIORITY (NUM_PRIORITIES/4)//Low Priority 8
#define DEFAULT_PRIORITY (NUM_PRIORITIES/2)//Default priority 16
#define High_priority ((NUM_PRIORITIES/4) * 3)//High priority 24
Enter BOOTSTRAP2 thread:
static int bootstrap2 (void *arg) {
Platform initialization (NAND initialization, environment variable env get and print, LCM Display related (Display logo), select Enter Mode < here to determine can enter boot burn write mode >)
dprintf (Spew, "initializing platform\n");
Platform_init ();
Null function
dprintf (Spew, "initializing target\n");
Target_init ();
Execute __apps_start to __apps_end app
dprintf (Spew, "calling Apps_init () \ n");
Apps_init ();
return 0;
}
Apps jump to bootable\bootloader\lk\app\mt_boot\mt_boot.c execution mt_boot_init
Look at the code:
App_start (Mt_boot)
. init = Mt_boot_init,//Perform this operation
App_end
The boot_linux_from_storage operation is performed after entering Mt_boot_init, and then the
Boot_linux (void *) cfg_bootimg_load_addr, (unsigned*) cfg_bootargs_addr,
(char*) Commanline, Board_machtype (), (void *) cfg_ramdisk_load_addr, G_RIMG_SZ);
Cfg_bootimg_load_addr ———— The physical address of bootimg in DRAM
Cfg_bootargs_addr ———— The position of passing parameters to the DRAM
Commanline parameters passed by the ———— Commanline
Board_machtype () ———— Board information
CFG_RAMDISK_LOAD_ADDR ———— RAMDISK Address
Attention:
1, the data passed to the kernel must be transmitted in the ATAG structure (easy to receive)
2. Close the cache and MMU
The last execution ———— entry (0, machtype, tags); jump to kernel execution cfg_bootimg_load_addr address
LK passes parameters to kernel: (The process of data being encapsulated)
Atag's structural package must start with the core and end With end
/* core*/
*ptr++ = 2;
*ptr++ =0x54410001;
PTR =target_atag_boot (PTR);
PTR =target_atag_mem (PTR);
PTR =target_atag_meta (PTR);
PTR =target_atag_commmandline (PTR, cmdline);
PTR =target_atag_initrd (PTR, (unsigned long) RAMDisk, ramdisk_size);
PTR =TARGET_ATAG_VIDEOLFB (PTR);
/* END */
*ptr++ = 0;
*ptr++ = 0;
Analysis Source::
Unsigned*target_atag_boot (unsigned *ptr) {
*ptr++ =tag_size (tag_boot); Tag_size size
*ptr++ =atag_boot; Tag name
*ptr++ =g_boot_mode; The data passed
return ptr;
}
unsigned *target_atag_mem (unsigned *ptr)