The ARM Linux kernel starts with several key address "turn"

Source: Internet
Author: User

Transferred from: http://www.cnblogs.com/armlinux/archive/2011/11/06/2396787.html

1. Kernel Boot Address
1.1. Noun Interpretation
Ztextaddr

Unzip the start address of the code run. There is no physical address and virtual address, because the MMU is turned off at this time. This address is not necessarily the address of the RAM, can be support read-write addressing flash and other storage intermediaries.

Start address of decompressor. Here's no point in talking on virtual or physical addresses here, since the MMU would be is off at the time if you call T He decompressor code. You normally call the kernel in this address to start it booting. This doesn ' t has the to being located in RAM, it can is in flash or other read-only or Read-write addressable medium.

Zreladdr

The kernel initiates the address in RAM. The compressed kernel image is extracted to this address and then executed.

This is the address where the decompressed kernel would be written, and eventually executed. The following constraint must be valid:

__virt_to_phys (textaddr) = = Zreladdr

The initial part of the kernel are carefully coded to be position independent.

Textaddr

The kernel-initiated virtual address, which corresponds to the zreladdr. A generic kernel-initiated virtual address is the first bank address of RAM plus 0x8000.

TEXTADDR = Page_offset + textoffst

Virtual start address of kernel, normally Page_offset + 0x8000. This is where the kernel image ends up. With the latest kernels, it must is located at 32768 bytes to a 128MB region. Previous Kernels placed a restriction of 256MB here.

Textoffset

The kernel offset address. Set in the Arch/arm/makefile.

Phys_offset

The physical starting address of the first bank of RAM.

Physical start address of the first bank of RAM.

Page_offset

The virtual start address of the first bank of RAM.

Virtual start address of the first bank of RAM. During the kernel

Boot phase, virtual address page_offset is mapped to physical

Address Phys_offset, along with any and mappings you supply.

This should is the same value as task_size.

1.2. Kernel Boot Address determination
The kernel boot boot address is determined by bootp.lds. Bootp.lds:arch/arm/bootp

Output_arch (ARM)

ENTRY (_start)

SECTIONS

{

. = 0;

. Text: {

_stext =.;

* (. Start)

* (. Text)

Initrd_size = Initrd_end-initrd_start;

_etext =.;

}

}

By. = 0 You can determine the location of the start address in 0x0 where the decompression code runs. The value of the ZTEXTADDR determines which is worth selecting.

Makefile:arch/arm/boot/compressed

If the setting kernel starts from ROM, you can set the starting address of the decompression code in the configuration interface of make menuconfig, otherwise the starting address of the decompression code is 0x0. In fact, when booting from ROM by default, the starting address of the decompression code is also 0x0.

Feq ($ (config_zboot_rom), y)

ZTEXTADDR: = $ (Config_zboot_rom_text)

ZBSSADDR: = $ (CONFIG_ZBOOT_ROM_BSS)

Else

ZTEXTADDR: =0 zbssaddr: = ALIGN (4)

endif

Sedflags = s/text_start/$ (ztextaddr)/;s/bss_start/$ (ZBSSADDR)/

......

$ (obj)/vmlinux.lds: $ (obj)/vmlinux.lds.in arch/arm/mach-s3c2410/makefile. config

@sed "$ (sedflags)" < $< > [email protected]

@sed "$ (sedflags)" < $< > [email protected] rules set Text_start to Ztextaddr. Text_start is used in arch/arm/boot/compressed/vmlinux.lds.in to set the starting address of the decompression code.

Output_arch (ARM)

ENTRY (_start)

SECTIONS

{

. = Text_start;

_text =.;

. Text: {

_start =.;

* (. Start)

* (. Text)

* (. text.*)

......

}

}

The compilation of the kernel relies on vmlinux.lds,vmlinux.lds generated by VMLINUX.LDS.S. It can be seen from the following code that the kernel-initiated virtual address is set to Page_offset + Text_offset, and the kernel-initiated physical address zreladdr is set in Arch/arm/boot/makefile.

Output_arch (ARM)

ENTRY (stext)

SECTIONS

{

#ifdef Config_xip_kernel

. = Xip_virt_addr (CONFIG_XIP_PHYS_ADDR);

#else

. = Page_offset + Text_offset;

#endif

. init: {/* init code and Data */

_stext =.;

_sinittext =.;

* (. Init.text)

_einittext =.;

......

}

}

# Arch/arm/boot/makefile

# note:the Following conditions must always be true:

# zreladdr = = Virt_to_phys (Page_offset + text_offset)

# Params_phys must be within 4MB of ZRELADDR

# Initrd_phys must is in RAM

ZRELADDR: = $ (zreladdr-y)

#---> zrealaddr-y are specified with 0x30008000 in Arch/arm/boot/makefile.boot

Params_phys: = $ (params_phys-y)

Initrd_phys: = $ (initrd_phys-y)

Export ZRELADDR Initrd_phys Params_phys

The kernel image is compiled with the following command, which is specified by the parameter-A,-e, whose entry address is zreladdr, which is zreladdr: = $ (zreladdr-y).

quiet_cmd_uimage= uimage [email protected]

Cmd_uimage = $ (Config_shell) $ (mkimage)-A arm-o linux-t kernel \

-C none-a $ (ZRELADDR)-E $ (zreladdr) \

-N ' linux-$ (kernelrelease) '-D $< [email protected]

1.3. Summary
From the above analysis, it is known that after the Linux kernel is bootloader copied to ram, the decompression code runs from ZTEXTADDR (this code is a location-independent pic). The kernel is decompressed to zrealaddr, which is the physical address at which the kernel is started. Accordingly, the kernel-initiated virtual address is set to TEXTADDR, which satisfies the following conditions:

TEXTADDR = Page_offset + text_offset

The kernel-initiated physical address and virtual address satisfy the following conditions:

Zreladdr = = Virt_to_phys (page_offset + text_offset) = Virt_to_phys (TEXTADDR)

Assuming the development Board is smdk2410, there are:

Kernel-initiated virtual address

TEXTADDR = 0xc0008000

Kernel-Initiated Physical address

ZRELADDR = 0x30008000

If you start directly from Flash, you also need to set the ZTEXTADDR address.

2. Kernel Boot Process Analysis
The kernel boot process can be broadly divided into two phases: self-booting of the kernel image, and initialization of the Linux kernel sub-module.

Start

Decompress_kernel ()

Call_kernel

Stext:

Prepare_namespace

Do_basic_setup

Init

Rest_init

Setup_arch ...

Start_kernel

_enable_mmu

Execve ("/sbin/init"))

Kernel boot flowchart

2.1. Self-booting of kernel images
The main task at this stage is to extract the compressed kernel and enter into the kernel code.

After bootloader completes the system boot, the kernel image is called into the memory specified physical address ztextaddr. A typical kernel image consists of a bootstrap program and a compressed vmlinux. Therefore, the kernel needs to be decompressed before booting the kernel. The first code for the entry of the kernel image is the bootstrap program. It's in the Arch/arm/boot/compressed/head. S file.

The main function of the Head.s file is to decompress the compressed kernel and jump to the portal of the kernel vmlinux kernel. Decompress_kernel (): These functions are implemented by the ARCH/ARM/BOOT/COMPRESSED/MISC.C and Call_kernel functions. Before calling Decompress_kernel () to extract the kernel, you need to ensure that the extracted kernel code does not overwrite the original kernel image. And the entry address zrealaddr that sets the kernel code.

. text

ADR R0, LC0

Ldmia R0, {r1, R2, R3, R4, R5, R6, IP, SP}

. Type LC0, #object

LC0:. Word LC0 @ r1

. Word __bss_start @ r2

. Word _end @ R3

. Word zreladdr @ R4

. Word _start @ R5

. Word _got_start @ r6

. Word _got_end @ IP

. Word user_stack+4096 @ sp

The above code gets the entry address of the kernel code, which is stored in the R4.

/*

* Check to see if we'll overwrite ourselves.

* R4 = Final kernel address

* R5 = start of this image

* r2 = end of malloc space (and therefore this image)

* We basically want:

* R4 >= R2-OK

* R4 + image length <= R5-OK

*/

CMP R4, R2

BHS Wont_overwrite

Add R0, R4, #4096 *1024 @ 4MB Largest kernel size

CMP R0, R5

BLS Wont_overwrite

MOV R5, R2 @ decompress after malloc space

mov r0, R5

MOV R3, R7

BL Decompress_kernel

b Call_kernel

The code above determines that the extracted kernel code will overwrite the original kernel image, and then call the kernel decompression function decompress_kernel ().

Ulg

Decompress_kernel (Ulg Output_start, Ulg free_mem_ptr_p, Ulg free_mem_ptr_end_p,

int arch_id)

{

Output_data = (Uch *) Output_start; /* Specify kernel execution address, save in R4 */

Free_mem_ptr = free_mem_ptr_p;

Free_mem_ptr_end = free_mem_ptr_end_p;

__machine_arch_type = arch_id;

Arch_decomp_setup (); /* Initialization and setup before extracting, including serial baud rate settings, etc. */

MAKECRC (); /*CRC Check */

Putstr ("uncompressing Linux ...");

Gunzip (); /* Call the Decompression function */

Putstr ("Done, booting the kernel.\n");

return output_ptr;

}

The ARM Linux kernel starts with several key address "turn"

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.