Key addresses when the ARM Linux kernel is started

Source: Internet
Author: User

1. kernel startup address
1.1. Glossary
Ztextaddr

Extract the start address of the Code. There is no physical address or virtual address, because MMU is disabled at this time. The RAM address may be a storage medium such as flash that supports read/write addressing.

Start address of decompressor. here's no point in talking about virtual or physical addresses here, since the MMU will be off at the time when you call the decompressor code. you normally call the kernel at this address
Start it booting. This doesn't have to be located in Ram, it can be in flash or other read-only or read-write addressable medium.

Zreladdr

The address of the kernel startup in Ram. The compressed kernel image is extracted to this address and then executed.

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

_ Pai_to_phys (textaddr) = zreladdr

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

Textaddr

The virtual address of kernel startup, which corresponds to zreladdr. Generally, the virtual address started by the kernel is 0x8000 added to the First Bank address of RAM.

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 be located at 32768 bytes into a 128 MB region. previous kernels placed a restriction
Of 256 MB here.

Textoffset

Kernel offset address. Set in arch/ARM/makefile.

Phys_offset

The physical start 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 will be mapped to physical

Address phys_offset, along with any other mappings you supply.

This shoshould be the same value as task_size.

1.2. Check the kernel startup address
The boot address of the kernel 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 = .;

}

}

From top. = 0, you can determine that the start address of the decompressed code is 0x0. The value of ztextaddr determines this value.

Makefile: ARCH/ARM/boot/compressed

If you set the kernel to start from Rom, you can set the start address of the decompressed code on the make menuconfig configuration interface. Otherwise, the start address of the decompressed code is 0x0. In fact, the start address of the decompressed code is 0x0 by default when starting from Rom.

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)" <$ <>$ @

@ Sed "$ (sedflags)" <$ <> $ @ the rule sets text_start to ztextaddr. Text_start is used in arch/ARM/boot/compressed/vmlinux. LDS. In to set the start address of the decompressed code.

Output_arch (ARM)

Entry (_ start)

Sections

{

. = Text_start;

_ Text = .;

. Text :{

_ Start = .;

* (. Start)

* (. Text)

* (. Text .*)

......

}

}

Kernel compilation relies on vmlinux. LDS. vmlinux. LDS is generated by vmlinux. LDS. S. The following code shows that the virtual address of kernel startup is set to page_offset + text_offset, and the physical address of kernel startup 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 = pai_to_phys (page_offset + text_offset)

# Params_phys must be within 4 MB of zreladdr

# Initrd_phys must be in Ram

Zreladdr: = $ (zreladdr-y)

# ---> Zrealaddr-y is 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

Run the following command to compile the kernel image. The entry address of-a and-E is set to zreladdr, which is specified in zreladdr :=$ (zreladdr-Y.

Quiet_pai_uimage = uimage $ @

Export _uimage = $ (config_shell) $ (mkimage)-A arm-O Linux-T kernel \

-C none-A $ (zreladdr)-E $ (zreladdr )\

-N'linux-$ (kernelrelease) '-d $ <$ @

1.3. Summary
From the above analysis, we can know that after the Linux kernel is copied to ram by bootloader, the decompressed code starts to run from ztextaddr (this code is a location-independent pic ). The kernel is decompressed to zrealaddr, that is, the physical address of the kernel startup. Correspondingly, the virtual address of kernel startup is set to textaddr, which meets the following conditions:

Textaddr = page_offset + text_offset

The physical and virtual addresses of kernel startup meet the following conditions:

Zreladdr = pai_to_phys (page_offset + text_offset) = pai_to_phys (textaddr)

Assume that the Development Board is smdk2410:

Virtual Address of kernel startup

Textaddr = 0xc0008000

Physical address of kernel startup

Zreladdr = 0x30008000

If it is started directly from flash, you also need to set the ztextaddr address.

2. kernel Startup Process Analysis
The kernel startup process is divided into two phases: Kernel Image Self-boot and kernel sub-module initialization.

Start

Decompress_kernel ()

Call_kernel

Stext:

Prepare_namespace

Do_basic_setup

Init

Rest_init

Setup_arch ......

Start_kernel

_ Enable_mmu

Execve ("/sbin/init "))

Kernel startup Flowchart

2.1. kernel Image Self-boot
The main task at this stage is to decompress the compressed kernel and enter the kernel code entry.

After bootloader completes system boot, the kernel image is transferred to the physical address ztextaddr specified by the memory. A typical kernel image consists of a self-boot program and a compressed vmlinux. Therefore, you need to decompress the kernel before starting the kernel. The first code at the kernel image entry is the self-guided program. It is 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 kernel vmlinux kernel entry. Decompress_kernel (): ARCH/ARM/boot/compressed/Misc. C and call_kernel functions implement the above functions. Before calling decompress_kernel () to decompress the kernel, make sure that the decompressed kernel code does not overwrite the original kernel image. And set the kernel code entry address zrealaddr.

. 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 saved in R4.

/*

* Check to see if we will 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 @ 4 MB 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 checks whether the extracted kernel code will overwrite the original kernel image, and then calls 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 the kernel execution address and save it 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 ();/* initialize and set before decompression, including serial port baud rate settings */

Makecrc ();/* CRC check */

Putstr ("Uncompressing Linux ...");

Gunzip ();/* call the extract function */

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

Return output_ptr;

}

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.