Linux Kernel startup address

Source: Internet
Author: User
KernelThe link compilation process relies on the vmlinux. LDS file ArmFor example, the vmlinux. LDS file is located in the kernel/ARCH/ARM/vmlinux. LDS, The vmlinux-armv.lds is generated in the kernel/ARCH/ARM/makefile

Ifeq ($ (config_cpu_32), Y)
Processor = armv
Textaddr = 0xc0008000
Ldscript = ARCH/ARM/vmlinux-armv.lds.in
Endif

ARCH/ARM/vmlinux. LDS: $ (ldscript) dummy
@ SED's/textaddr/$ (textaddr)/; S/dataaddr/$ (dataaddr)/'$ (ldscript) >$ @

View ARCH/ARM/vmlinux. LDS

Output_arch (ARM)
Entry (stext)
Sections
{
. = 0xc0008000;
. Init: {/* init code and Data */
_ Stext = .;
_ Init_begin = .;
* (. Text. init)
_ Proc_info_begin = .;
* (.Proc.info)
_ Proc_info_end = .;
_ Arch_info_begin = .;
* (.Arch.info)
_ Arch_info_end = .;
_ Tagtable_begin = .;
* (. Taglist)
_ Tagtable_end = .;
* (. Data. init)
. = Align (16 );
_ Setup_start = .;
* (. Setup. init)
_ Setup_end = .;
_ Initcall_start = .;
* (. Initcall. init)
_ Initcall_end = .;
. = Align (4096 );
_ Init_end = .;
}

/Discard/: {/* exit code and Data */
* (. Text. Exit)
* (. Data. Exit)
* (. Exitcall. Exit)
}

. Text: {/* Real Text Segment */
_ Text =.;/* Text and read-only data */
* (. Text)
* (. Fixup)
* (. GNU. Warning)
* (. Rodata)
* (. Rodata .*)
* (. Glue_7)
* (. Glue_7t)
* (. Got)/* Global Offset Table */

_ Etext =.;/* end of text section */
}

. Kstrtab: {* (. kstrtab )}

. = Align (16 );
_ Ex_table: {/* exception table */
_ Start ___ ex_table = .;
* (_ Ex_table)
_ Stop ___ ex_table = .;
}

_ Ksymtab: {/* kernel symbol table */
_ Start ___ ksymtab = .;
* (_ Ksymtab)
_ Stop ___ ksymtab = .;
}

. = Align (8192 );

. Data :{
/*
* First, The init task Union, aligned
* To an 8192 byte boundary.
*/
* (. Init. Task)

/*
* Then the cacheline aligned data
*/
. = Align (32 );
* (. Data. cacheline_aligned)

/*
* And the usual data section
*/
* (. Data)
Constructors

_ Edata = .;
}

. BSS :{
_ Bss_start =.;/* BSS */
* (. BSS)
* (Common)
_ End = .;
}
/* Stabs debugging sections .*/
. Stab 0: {* (. Stab )}
. Stabstr 0: {* (. stabstr )}
. Stab. excl 0: {* (. Stab. excl )}
. Stab. exclstr 0: {* (. Stab. exclstr )}
. Stab. index 0: {* (. Stab. Index )}
. Stab. indexstr 0: {* (. Stab. indexstr )}
. Comment 0: {* (. Comment )}
}

ARCH/ARM/makefile:

Vmlinux: ARCH/ARM/vmlinux. LDS

ARCH/ARM/vmlinux. LDS: $ (ldscript) dummy
@ SED's/textaddr/$ (textaddr)/; S/dataaddr/$ (dataaddr)/'$ (ldscript) >$ @

Makeboot = $ (make)-c arch/$ (ARCH)/boot

Bzimage zimage zinstall image bootpimage install: vmlinux
@ $ (Makeboot) $ @

However, in kernel/ARCH/ARM/boot/makefile

Ifeq ($ (config_arch_s3c2410), Y)
Ztextaddr = 0x30008000
Zreladdr = 0x30008000
Endif

Zimage: $ (configure) compressed/vmlinux
$ (Objcopy)-O Binary-R. Note-R. comment-s compressed/vmlinux $ @

Compressed/vmlinux: $ (topdir)/vmlinux Dep
@ $ (Make)-C compressed vmlinux

In makefile under the compressed directory

Zldflags =-p-X-T vmlinux. LDS

Sedflags = s/text_start/$ (ztextaddr)/; S/load_addr/$ (zreladdr)/; S/bss_start/$ (zbssaddr )/

ALL: vmlinux

Vmlinux: $ (head) $ (objs) piggy. O vmlinux. LDS
$ (LD) $ (zldflags) $ (head) $ (objs) piggy. o $ (libgcc)-O vmlinux

Vmlinux. LDS: vmlinux. LDS. In makefile $ (topdir)/ARCH/$ (ARCH)/boot/makefile $ (topdir)/. config
@ Sed "$ (sedflags)" <vmlinux. LDS. In >$ @

Vmlinux-armv.lds.in file content: output_arch (ARM)
Entry (_ start)
Sections
{
. = Load_addr;
_ Load_addr = .;

. = Text_start;
_ Text = .;

. Text :{
_ Start = .;
* (. Start)
* (. Text)
* (. Fixup)
* (. GNU. Warning)
* (. Rodata)
* (. Rodata .*)
* (. Glue_7)
* (. Glue_7t)
Input_data = .;
Piggy. o
Input_data_end = .;
. = Align (4 );
}

_ Etext = .;

_ Got_start = .;
. Got: {* (. Got )}
_ Got_end = .;
. Got. PLT: {* (. Got. PLT )}
. Data: {* (. Data )}
_ Edata = .;

. = Bss_start;
_ Bss_start = .;
. BSS: {* (. BSS )}
_ End = .;

. Stack (noload): {* (. Stack )}

. Stab 0: {* (. Stab )}
. Stabstr 0: {* (. stabstr )}
. Stab. excl 0: {* (. Stab. excl )}
. Stab. exclstr 0: {* (. Stab. exclstr )}
. Stab. index 0: {* (. Stab. Index )}
. Stab. indexstr 0: {* (. Stab. indexstr )}
. Comment 0: {* (. Comment )}
}

The content of vmlinux. LDS is

Output_arch (ARM)
Entry (_ start)
Sections
{
. = 0x30008000;
_ Load_addr = .;

. = 0;
_ Text = .;

. Text :{
_ Start = .;
* (. Start)
* (. Text)
* (. Fixup)
* (. GNU. Warning)
* (. Rodata)
* (. Rodata .*)
* (. Glue_7)
* (. Glue_7t)
Input_data = .;
Piggy. o
Input_data_end = .;
. = Align (4 );
}

_ Etext = .;

_ Got_start = .;
. Got: {* (. Got )}
_ Got_end = .;
. Got. PLT: {* (. Got. PLT )}
. Data: {* (. Data )}
_ Edata = .;

. = Align (4 );
_ Bss_start = .;
. BSS: {* (. BSS )}
_ End = .;

. Stack (noload): {* (. Stack )}

. Stab 0: {* (. Stab )}
. Stabstr 0: {* (. stabstr )}
. Stab. excl 0: {* (. Stab. excl )}
. Stab. exclstr 0: {* (. Stab. exclstr )}
. Stab. index 0: {* (. Stab. Index )}
. Stab. indexstr 0: {* (. Stab. indexstr )}
. Comment 0: {* (. Comment )}
}

Generally, after vmlinux is generated, the kernel is compressed into zimage, and the compressed directory is kernel/ARCH/ARM/boot.
The compressed zimage file is downloaded to flash, and zimage is composed of the compressed vmlinux and decompression program, as shown in: | ----------------- |/| ----------------- |
|/|
|/| Decompress code |
| Vmlinux |/| ----------------- | zimage
|/|
|
|
|
|/| --------------- |
|/
|/
|/
| --------------- |/

The zimage link script is also called vmlinux. LDS and is located in kernel/ARCH/ARM/boot/compressed.
Is generated by the vmlinux. LDS. In file in the same directory.

Defined in the kernel/ARCH/ARM/boot/MAKEFILE file:

Ifeq ($ (config_arch_s3c2410), Y)
Ztextaddr = 0x30008000
Zreladdr = 0x30008000
Endif

Ztextaddr is the ram offset of the decompressed code.AddressZreladdr is the offset address of the kernel Ram startup. here we can see that the address of the specified ztextaddr is 30008000,
The above is my analysis of the kernel startup address, which summarizes the kernel startup Address Settings:

Set

Ifeq ($ (config_arch_s3c2410), Y)
Ztextaddr = 0x30008000
Zreladdr = 0x30008000
Endif
# We now have a pic decompressor implementation. decompressors running
# From RAM shoshould not define ztextaddr. decompressors running directly
# From Rom or flash must define ztextaddr (preferably via the config)
#

Check the datasheet of 2410 and find that the base address of the memory ing is 0x3000 0000. How does the 0x30008000 come from?

The Kernel File kernel/document/ARM/booting contains:

Calling the kernel image

Existing boot loaders: Mandatory
New boot loaders: Mandatory

There are two options for calling the kernel zimage. if the zimage is stored in flash, and is linked correctly to be run from flash, then it is legal for the boot loader to call the zimage in Flash directly.

The zimage may also be placed in system RAM (at any location) and called there. note that the kernel uses 16 K of RAM below the image to store page tables. the recommended placement is 32kib into RAM.

It seems that 32 K (0x8000) space is used under the image to store the kernel page table,
0x30008000 is the startup address of the 2410 kernel in Ram.

Kernel decompression process analysis kernel compression and decompression code are in the directory kernel/ARCH/ARM/boot/compressed,

After compilation, the files vmlinux, head. O, MISC. O, head-s3c2410.o, piggy. O will be generated,

Head. O is the header file of the kernel and is responsible for initial settings;

Misc. O will be mainly responsible for Kernel decompression, after head. O;

Head-s3c2410.o files are mainly targeted at initialization and will be merged with head. O at the link;

Piggy. O is an intermediate file. It is actually a compressed kernel (kernel/vmlinux), but it is not linked to the initialization file or decompress the file;

Vmlinux is not (zimage is compressed kernel) Compressed kernel, is composed of piggy. O, head. O, MISC. O, head-s3c2410.o.

Completed in bootloader SystemAnd LinuxAfter the kernel is transferred to the memory, call bootlinux (),
This function will jump to the start position of the kernel.

If the kernel is not compressed, you can start it.
If the kernel is compressed, decompress it. There is an decompressed program in the compressed kernel header.
The source code of the first file in the compressed kernel entry is in arch/ARM/boot/compressed/head. S.

It will call the decompress_kernel () function, which is in the arch/ARM/boot/compressed/Misc. c file,
Decompress_kernel () also calls proc_decomp_setup (), arch_decomp_setup () to set,
Call gunzip () after "Uncompressing Linux..." is printed (). Place the kernel at a specified location. The following is an analysis of the head. s file:
(1) For debugging output settings of Various arm CPUs, the macro is defined for unified operations.
(2) set the start and end addresses of the kernel and save the architecture ID.
(3) If the CPU above arm2 is a common userModeTo the superuser mode, and then disconnected.
(4) analyze the Delta offset of the lc0 structure to determine whether the kernel address needs to be reloaded (R0 deposit offset to determine whether R0 is zero ).

Whether the kernel address needs to be reloaded here. I thought it was mainly used to analyze ARCH/ARM/boot/makefile, arch/ARM/boot/compressed/makefile
And arch/ARM/boot/compressed/vmlinux. LDS. In files, mainly look at the location of the main segment of the vmlinux. LDS. In File Link,

Load_addr (_ load_addr) = 0x30008000, while text_start (_ text, _ start) is set to 0, bss_start (_ bss_start) = align (4 ).

This result depends on the kernel decompression mode, that is, whether the kernel is in memory (RAM) or flash before decompression,

Because here, our bootloader moves the compressed kernel (zimage) to the ram 0x30008000 position, and our compressed kernel is ordered from the 0x30008000 address in the memory (RAM, therefore, the offset obtained by R0 is the load address (0x30008000 ).
The next task is to convert the relative address of the kernel image to the physical address of the memory, that is, the address of the heavy-load kernel.
(5) You need to reload the kernel address and add the R0 offset to the BSS region and got table.
(6) Clear the r2-r3 of the BSS stack space.

(7) create a cache required for the C program to run and allocate 64 K stack space.

(8) R2 indicates the cache end address, R4 indicates the last execution address of the kernel, and R5 indicates the start address of the kernel object. Check whether the address conflict exists.

Set R5 to R2 so that the kernel address after decompress is after the 64 K stack.

(9) Call the decompress_kernel () function of the file Misc. C, decompress the kernel at the end of the cache (after the R2 address ). The register values are changed as follows:

R0 indicates the size of the extracted kernel.
R4 is the address when the kernel is executed
R5 is the start address of the kernel after decompression.
R6 is the CPU type value (processor ID)
R7 is the system type value (Architecture ID)

(10) after copying the reloc_start code to the kernel (R5 + R0), first clear the cache and then execute reloc_start.
(11) reloc_start reload the kernel starting with R5 at the R4 address.
(12) Clear the cache content, disable the cache, assign the architecture ID in R7 to R1, and run the kernel code starting with R4.

The following describes the decompression process, which is implemented by the decompress_kernel function. Function:
The decompressed code is located in kernel/lib/inflate. C, and inflate. C is separated from the gzip source program. Contains some direct references to global data.
It must be embedded directly into the code during use. When gzip files are compressed, they always search for duplicate strings in the first 32 KB for encoding,
During decompression, a buffer with at least 32 KB is required. It is defined as window [wsize]. Inflate. c Use get_byte () to read the input file,
It is defined as a macro to improve efficiency. The input buffer pointer must be defined as inptr, which is included in inflate. C. Inflate. c call flush_window ()
To output the encoded byte string in the window buffer. OutputThe length is represented by the outcnt variable. In flush_window (),
CRC must be calculated for the output byte string and the CRC variable must be refreshed. Call makecrc () to initialize the CRC calculation table before calling gunzip () to start decompression.
Finally, if gunzip () returns 0, the decompression is successful.

We will see this output at the beginning of kernel startup:
Uncompressing Linux... Done, booting the kernel.

This is also output by the decompress_kernel function, which calls the puts () Output string,
Puts is implemented in kernel/include/ASM-arm/arch-s3c2410/uncompress. h.

After decompression, return to head. s and start the kernel:

Call_kernel: BL cache_clean_flush
BL cache_off
MoV r0, #0
MoV R1, R7 @ restore architecture number
MoV PC, R4 @ call Kernel

Next we will start the real kernel.

Linux2.6 start and PASS Command Line Analysis

The kernel can pass a string command line at startup to control the kernel startup process, for example:
"Console = ttys2, 115200mem = 64m @ 0xa0000000"
The console is specified as the serial port 2, the baud rate is 115200, the memory size is 64 MB, and the physical base address is 0xa0000000.
In addition, we can define some global variables in the kernel and use these global variables to control kernel configurations, such USB DriverDefined in
Static int nousb;/* disable USB when built into kernel image */
If this variable is 1, the entire USB driver is not initialized. If you want to set it to 1, you can add nousb = 1 to the string command line.
Before you operate the variable, you need to let the system know the variable:
_ Module_param_call ("", nousb, param_set_bool, param_get_bool, & nousb, 0444 );
The macro _ module_param_call is defined in kernel/include/Linux/moduleparam. h.
The prototype is as follows:
# DEFINE _ module_param_call (prefix, name, set, get, ARG, Perm )/
Static char _ param_str _ # name [] = prefix # name ;/
Static struct kernel_param const _ Param _ # name/
_ Attribute_used __/
_ Attribute _ (unused ,__ section _ ("_ Param"), aligned (sizeof (void *))))/
= {_ Param_str _ # name, Perm, set, get, Arg}
 
It defines a variable of the kernel_param type, which is put into the _ Param,
The kernel_param struct is defined as follows:
Struct kernel_param {
Const char * Name;
Unsigned int perm;
Param_set_fn set;
Param_get_fn get;
Void * ARG;
};
_ Param: the Declaration of this section is somewhat PlatformIs in arch/.../../vmlinux. LDS. s, and most platforms are placed in
In kernel/include/ASM-generic/vmlinux. LDS. H, the definition is as follows:
_ Param: At (ADDR (_ PARAM)-load_offset ){/
Vmlinux_symbol (_ start ___ PARAM) = .;/
* (_ PARAM )/
Vmlinux_symbol (_ Stop ___ PARAM) = .;/
}
When the kernel is started, the string command will be parsed. In kernel/init/Main. C, the kernel startup function start_kernel
Declare the external array: extern struct kernel_param _ start ___ Param [], _ Stop ___ Param [];
Then call the parse_args function to parse the array:
Parse_args ("booting kernel", command_line, _ start ___ Param,
_ Stop ___ param-_ start ___ Param,
& Unknown_bootoption );

Command_line is the string command line to be parsed, and unknown_bootoption is the function pointer, which is used to obtain the = value on the right of the specified parameter.
Parse_args finds the kernel_param variable with the same name as nousb in the array and calls its set function to pay for it.

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.