ARM Linux kernel Startup Process

Source: Internet
Author: User

ARM Linux kernel Startup Process

Let's take a look at the process of generating vmlinux from the compilation link, which is composed of a lot of. o file links. The first one is
Kernel/ARCH/ARM/kernel/head-armv.o, and we also see
LDS link file kernel/ARCH/ARM/vmlinux. LDS, analyze it first
Entry (stext) // The entry point is stext should be in the head-armv.s
Sections
{
. = 0xc0008000; // base address, which is the starting virtual address of the kernel
. 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 = .;
}
About virtual addresses and physical addresses: After MMU is used, the system uses virtual addresses to point
The actual physical address. Here, the actual physical address of 0xc0008000 is 0x30008000,
For more information about MMU, see ARM architecture and programming.
To the head-armv.s find the entry to the program
. Section ". Text. init", # alloc, # execinstr
. Type stext, # Function
Entry (stext)
MoV R12, R0
MoV r0, # f_bit | I _bit | mode_svc @ Make sure SVC Mode
MSR cpsr_c, R0 @ and all irqs disabled
BL _ lookup_processor_type
TEQ R10, #0 @ invalid processor?
Moveq r0, # 'P' @ Yes, error 'P'
Beq _ Error
BL _ lookup_ubunture_type
TEQ R7, #0 @ invalid architecture?
Moveq r0, # 'A' @ Yes, error 'A'
Beq _ Error
BL _ create_page_tables
Adr lr, _ RET @ return address
Add PC, R10, #12 @ initialise Processor
Let's see where the previous sentence jumped.
The value of R10 is assigned to the _ lookup_processor_type subfunction.
_ Lookup_processor_type:
The base address of ADR R5, 2f // R5 2 is 0x30008000
Ldmia R5, {R7, R9, R10} // R7 =__ proc_info_end R9 =__ proc_info_begin
Sub R5, R5, R10 // The base address of R10 2 is 0xc0008000
Add R7, R7, R5 @ to our address space
Add R10, R9, R5 // R10 is changed to the base address of 0x30008000 _ proc_info_begin
2:. Long _ proc_info_end
. Long _ proc_info_begin
. Long 2B
In this way, the address of _ proc_info_begin is stored in R10, because MMU has not been enabled yet.
So we still need to change the base address to 0x30008000. Then we will find _ proc_info_begin.
Note that this label is in the vmlinux. LDS above, and the link is the .proc.info segment,
This segment was found at the end of the kernel/ARCH/ARM/MM/proc-arm920.s
. Section ".proc.info", # alloc, # execinstr

. Type _ arm920_proc_info, # object
_ Arm920_proc_info:
. Long 0x41009200
. Long 0xff00fff0
. Long 0x00000c1e @ mmuflags
B _ arm920_setup
OK, so that we can know where to jump to add PC, R10, #12, because this address has just put a jump statement
Note that the B Statement uses relative addresses, so you do not need to change the address. It jumps to _ arm920_setup, and
The previous statement is adr lr, _ ret, And the return address of _ arm920_setup is _ ret.
_ Arm920_setup and return to the _ RET label of the head-armv.s to continue execution.
_ RET: ldr lr, _ switch_data
MCR P15, 0, R0, C1, C0 // note that here, MMU is enabled
MoV r0, R0
MoV r0, R0
MoV r0, R0
MoV PC, LR // jump to _ mmap_switched. The virtual address is used.
// This command ldr lr. The _ switch_data-loaded _ mmap_switched address is a virtual address.
_ Switch_data:. Long _ mmap_switched
From _ mmap_switched to C code
B symbol_name (start_kernel) // in kernel/init/Main. c
This program is not very complex. I can still understand it carefully, and I cannot comment it out one by one.
Here is a flowchart


It is not hard to understand in C language.
Lock_kernel ();
Printk (linux_banner );
Setup_arch (& command_line );
Printk ("kernel command line: % s/n", saved_command_line );
Parse_options (command_line );
Trap_init ();
Init_irq ();
Sched_init ();
Softirq_init ();
Time_init ();
It's just a lot of initialization work. It's good to chase every function.

The last function called by start_kernel.
Static void rest_init (void)
{
Kernel_thread (init, null, clone_fs | clone_files | clone_signal );
Unlock_kernel ();
Current-> need_resched = 1;
Cpu_idle ();
}
An INIT process is created using kernel_thread and the init function in Main. C is executed.
Lock_kernel ();
Do_basic_setup ();
The do_initcils function is called in do_basic_setup.
Various drivers are completed in do_initcils (void ).
Static void _ init do_initcils (void)
{
Initcall_t * call;

Call = & __ initcall_start;
Do {
(* Call )();
Call ++;
} While (call <& __ initcall_end );

Flush_scheduled_tasks ();
}
_ Initcall_start is also assigned in vmlinux. LDS, so you need to find the. initcall. ini segment.
In kernel/include/Linux/init. H, you can find
# DEFINE _ init_call _ attribute _ (unused ,__ section _ (". initcall. init ")))
Typedef int (* initcall_t) (void );
# DEFINE _ initcall (FN )/
Static initcall_t _ initcall _ # FN _ init_call = FN
After careful research, we found that the address of the initialization function is put in the. initcall. init segment.
In this way, you can continuously call the driver's initialization function.
If no module is defined, # define module_init (x) _ initcall (X );
So it's easy to compile the driver into the kernel.
End of init
If (execute_command)
Execve (execute_command, argv_init, envp_init );
Execute_command is related to the command line parameter passed by ppcboot, that is, init =/linuxrc.
In this case, you need to execute the linuxrc script under the root directory, which will execute busybox
Busybox executes the/etc/init. d/RCS script again, and the script executes the/usr/etc/rc. Local script again.
Finished

Related Article

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.