Changed from: http://www.cnblogs.com/lknlfy/archive/2012/05/06/2486479.html
The boot process of the kernel?
3) The boot process of the kernel?
Arch/arm/kernel/head. S-> Boot assembly for kernel
R0 = 0. R1 = Machine nr, r2 = atags pointer. Machine code startup reference address, machine from U-boot, in which u-boot
For example, the following in "U-boot-digilent-dev-master/arch/arm/include/asm/mach-types.h"
Head. S medium
b secondary_start_kernel-> Jump to C-language entry function
Machine code list file for Linux kernel: arch/arm/tools/mach-types
Init/main.c-> Start_kernel//C Language Program entry
Operating System Management ideas: memory management, task management, device management, file management
Setup_arch (&command_line); System initialization, ARCH/ARM/KERNEL/SETUP.C Setup_command_line (command_line); //
Arch/arm/kernel/setup.c–> Setup_arch () in
Mdesc = Setup_machine (Machine_arch_type); Configure the current machine type, Machine_arch_type is the type of machine code, here is the assignment mach_xilinx_ep107
Mach_xilinx_ep107 in this macro in/arch/arm/tools/mach-types
Where is the initialization code for SMDK2410? --Traverse to find the initialization file for the corresponding machine code under the Arch/arm folder--\LINUX-DIGILENT-DEV-MASTER\ARCH\ARM\MACH-ZYNQ\ARM\COMMON.C
A list of device initialization functions corresponding to this machine code:
Dt_machine_start (xilinx_ep107,"Xilinx Zynq Platform")/ * 64KB to size, 8-way associativity, parity disabled * / . L2c_aux_val =0x00000000,. L2c_aux_mask =0xFFFFFFFF,. SMP= Smp_ops (Zynq_smp_ops),. Map_io = Zynq_map_io,. Init_IRQ = Zynq_irq_init,. Init_machine = Zynq_init_machine,. Init_late = Zynq_init_late,. Init_time = Zynq_timer_init,. DT_compat = Zynq_dt_match,. Reserve= Zynq_memory_init,. Restart= Zynq_system_reset,machine_end
zynq_init_machine---> 当前的zybo的机器初始化主函数。如需上点后初始化该板子的其它外设,能够在本函数内加入相应的初始化功能。
Have played or transplanted arm-linux should know in the/arch/arm folder there are a lot of detailed processor-related folders. Of course, for ZYNQ, the corresponding folder is MACH-ZYNQ. Found in the inside of the detailed board related documents \LINUX-DIGILENT-DEV-MASTER\ARCH\ARM\MACH-ZYNQ\ARMCOMMON.C, yes. That's it. Whether you want to migrate to a new kernel or if you want to learn more about an arm, the study of this file is indispensable.
The majority of this file is initialized to the structure of the platform device. At the end of this file there is a very important macro:
Dt_machine_start (xilinx_ep107,"Xilinx Zynq Platform")/ * 64KB to size, 8-way associativity, parity disabled * / . L2c_aux_val =0x00000000,. L2c_aux_mask =0xFFFFFFFF,. SMP= Smp_ops (Zynq_smp_ops),. Map_io = Zynq_map_io,. Init_IRQ = Zynq_irq_init,. Init_machine = Zynq_init_machine,. Init_late = Zynq_init_late,. Init_time = Zynq_timer_init,. DT_compat = Zynq_dt_match,. Reserve= Zynq_memory_init,. Restart= Zynq_system_reset,machine_end
The definition of Dt_:qmachine_start is in arch/arm/include/asm/mach/arch.h, for example the following:
#define Dt_machine_start (_name, _namestr) \ static const struct machine_desc __mach_desc_ # #_name \ __used __attribute__ ( (__section__ ( ". Arch.info.init" ))) = {. nr = ~0 ,. Name = _namestr,#endif
Oh, in fact, it defines a struct MACHINE_DESC type struct variable, which also defines some other members, followed by a focus on. Init_machine This member, which is a function pointer with a value of Zynq_init_machine, This function is also defined in COMMON.C. What is the content? Oh, because here just give the general flow, the detailed content first not analysis. What is most concerned about today is where the struct variable is called, so that it can invoke its members and member functions. First look at the Setup_arch () function inside/ARCH/ARM/KERNEL/SETUP.C:
void__init Setup_arch (Char**cmdline_p) {const struct MACHINE_DESC*Mdesc; Setup_processor (); Mdesc=SETUP_MACHINE_FDT (__atags_pointer);if(!MDESC) Mdesc=Setup_machine_tags (__atags_pointer, __machine_arch_type); Machine_desc=Mdesc; Machine_Name=Mdesc -Nameif(Mdesc -Reboot_mode!=Reboot_hard) Reboot_mode=Mdesc -Reboot_mode; Init_mm.Start_code=(unsigned long) _text; Init_mm.End_code=(unsigned long) _etext; Init_mm.End_data=(unsigned long) _edata; Init_mm.Brk=(unsigned long) _end;/ * Populate Cmd_line too for later use, preserving boot_command_line * /strlcpy (Cmd_line, Boot_command_line, command_line_size);*Cmdline_p=Cmd_line; Parse_early_param (); Early_paging_init (Mdesc, Lookup_processor_type (read_cpuid_id ())); Setup_dma_zone (MDESC); Sanity_check_meminfo (); Arm_memblock_init (MDESC); Paging_init (MDESC); Request_standard_resources (MDESC);if(Mdesc -Restart) Arm_pm_restart=Mdesc -Restart Unflatten_device_tree (); Arm_dt_init_cpu_maps (); Psci_init ();......................
This function is called in the Start_kernel () function of/INIT/MAIN.C. See line 10th, where the Setup_machine () function is to find the variable of the struct MACHINE_DESC type we want, that is, to define that variable in COMMON.C.
What is the value of the parameter machine_arch_type of the function? Keep looking:
This is the machine definition in U-boot.
# define machine_arch_type MACH_TYPE_XILINX_EP107
That is to say, the value of Machine_arch_type is 2520.
In the Setup_machine () function, the main call to the Lookup_machine_type () function to find the appropriate type should be for efficiency reasons. This function is implemented by assembly, and no detailed code is given here.
Here, we know that Setup_arch () was called in the Start_kernel () function of/INIT/MAIN.C, and a detailed struct MACHINE_DESC type variable was found in Setup_arch (). But where is the member or member function called through this variable? Keep looking.
Or in setup.c, you see a function like this:
static int __init customize_machine (void) {/* * * Customizes platform devices,orAdds new ones * on DT based machines, we fall Back toPopulating the* Machine from theDevice Tree,ifNo callback isprovided, * otherwise we would always need an init_machine callback. */if(Machine_desc->init_machine) machine_desc->init_machine ();#ifdef config_of ElseOf_platform_populate (NULL, of_default_bus_match_table, NULL, NULL);#endifreturn 0;}
Finally, we see that the member function Init_machine is called here.
But it was not explicitly called, but it was placed in the Arch_initcall macro. Go and see how it's defined in./include/linux/init.h:
Look at the __define_initcall macro again: in./arch/um/include/shared/init.h
Well. It is linked to the. Initcall section, now look briefly./include/asm-generic/vmlinux.lds.h: the definition of Initcall in this link script:
able to see Customize_machine () was put in the. Initcall3.init. Say so many definitions, where exactly is it called? Well, it was called in a function called Do_initcalls () in/init/main.c, to see:
See line 1th. Very familiar with it. All functions from __early_initcall_end to __initcall_end end are called sequentially in the For loop. Customize_machine () is also called in the meantime.
Well, it's almost the same end here, and finally, the sequence of these function calls is summed up:
Start_kernel ()->setup_arch ()->do_initcalls ()->customize_machine ()->zynq_init_machine ()
[Zedboard Linux system porting]-start from Machine_start