There is a place to see that the start-up process is ARCH/ARM/BOOT/COMPRESSED/HEAD.S-----> Call arch/arm/boot/compressed/misc.c decompress_kernel ()
function to decompress the kernel. ---->arch/arm/kernel/head-common. S initialization---->init/main.c asmlinkage void __init start_kernel (void)
Note that there is a function in the Arch/arm/kernel/smp.c file that starts the multicore processor void __init smp_prepare_boot_cpu (void), Asmlinkage void __init by INIT/MAIN.C Start_kernel (void) call
Some people say that there are two of the boot code of ARM Linux, one is compressed, one is not compressed, the compression will eventually call no compression, no compression of the entrance in Arch/arm/kernel/head. S file. It looks like this, the second startup process is in the Boot/compressed folder, which confirms that the compression starts the process.
Take 32-bit arm as an example, analyzed on the 3.9.7 kernel version.
1. Compression START process
/arch/arm/boot/compressed/head. S
1) first defines a series of macros, such as Writeb, LOADSP, KPUTC, Kphex, Debug_reloc_start, debug_reloc_end;
2) Use R0, R7, R8 respectively to save the values of R0, R1, R2 (respectively, 0, Machinetype, atag pointers), R9 is the value of CPSR;
3) R2 save CPSR, determine whether the last 2bit is 0, that is, whether the user mode, not the case is set to the SVC mode, and the R9 in the cpsr saved to SPSR;
4) Put the final kernel file address in the R4, one way is through the pc&0xf8000000 + text_offset; one way is Zreladdr;text_offset =??
ZRELADDR is defined in makefile, but the context is unclear.
5) Jump to cache_on
6) ADR R0, LC0//Assign the address of the LC0 tag to the contents of the R0,LC0 label as shown in
Ldmia R0, {r1, R2, R3, R6, R10, R11, R12}//Save 7 Word Data beginning with r0 address to R1, R2, R3, R6, R10, R11, R12
Set the stack, which is the value of LC0 start Word 8th
/*
* We might is running at a different address. We need
* To fix up various pointers.
*/
Sub R0, R0, R1 @ Calculate the delta offset
Add R6, R6, R0 @ _edata
Add R10, R10, r0 @ inflated kernel size location
Calculates the address of the kernel size store and saves it in R10
LC0:. Word LC0 @ r1
. Word __bss_start @ r2
. Word _end @ R3
. Word _edata @ r6
. Word input_data_end-4 @ R10 (inflated size location)
. Word _got_start @ R11
. Word _got_end @ IP
. Word. L_user_stack_end @ SP
. Size LC0,. -LC0
7) The address from the beginning of the R10 reads 4 bytes, and the 32bit is stored in the R9, which is the value of the kernel size (uncompressed);
8) Allocate space above the stack, stack Max 64KB (0x10000), assign SP + 0x10000 value to R10;
9) The size of the initialized DTB is 0, and is saved in R5;
10) If there is a device trees (DTB) appended to zimage, some processing, temporarily first not analysis
To date, the contents of each register are as follows:
/*
* R0 = Delta
* R2 = BSS start
* R3 = BSS End
* R4 = Final kernel address
* R5 = appended DTB size (still unknown)
* R6 = _edata
* R7 = Architecture ID
* r8 = Atags/device tree pointer
* R9 = size of decompressed image
* R10 = end of this image, including bss/stack/malloc space if non XIP
* R11 = GOT start
* R12 = GOT End
* SP = stack pointer
*
* If there is device trees (DTB) appended to Zimage, advance R10 so, the
* DTB data would get relocated along with the kernel if necessary.
*/
11) Determine if the address will be overwritten,
R10 = R10 + 16KB;
R4 > R10 will not overwrite, otherwise R10 = R4 + R9,r10 < R9 will not overwrite otherwise it will overwrite
Handling when overwriting is not analyzed here first
Orrs R1, R0, R5//orr logic and R5 for 0, when R0 and Delta are also 0, jump to not_relocated
BEQ not_relocated//Otherwise you need to jump to the address, jump part we don't look at the moment
13) Clear 0 BSS section, address starting from R2 to R3
14) Extracting C code environment preparation and decompression
Decompress_kernel (
unsigned long Output_start,//(value in R4, transferred to R0)
unsigned long free_mem_ptr_p,//(value of SP, transferred to R1)
unsigned long free_mem_ptr_end_p,//(SP value +64KB, transferred to R2)
int arch_id//(value in R7, transferred to R3)
);
Prepare 4 parameters, save in R0~r3, and then call the Decompress_kernel function
15) Swipe the cache, close the cache, respectively, call Cache_clean_flush, Cache_off
16) Restore R7, R8 architecture number, atags pointer to R1, R2
Jump to the __enter_kernel tab, where R0 recovery to 0,R4 in the decompression kernel address is transferred to the PC, jump to the R4, complete from the compression core process to the non-compressed core process conversion.
2, non-compression START process
The code entry is in Arch\arm\kernel\head.s, and then jumps to the Start_kernel in MAIN.C.
Ensure SVC mode and interrupt shutdown
|
Get CPUID
|
Judging Atag, seems to only judge the Atag_core
|
__create_page_tables, creating a page table
|
Save the __mmap_switched address in R13
|
Jump to __enable_mmu,
At the end of the __turn_mmu_on jump to R13, that is, jump to __mmap_switched
|
At the end of __mmap_switched b Start_kernel
This GCC assembly looks good pain, some in as documents are not found, and do not know what meaning, so it is only a general.
This compilation is described in detail in the http://linux.chinaunix.net/bbs/thread-1021226-1-1.html.