Original address: Linux kernel source Code Analysis--Kernel boot (4) Image kernel boot (setup_arch function) (Linux-3.0 ARMv7) Tekkamanninja
Transferred from: http://blog.chinaunix.net/uid-25909619-id-4938393.html
In the analysis of the Start_kernel function, there are schema-related initialization function Setup_arch. This function varies according to the architecture and the detailed analysis of the ARM architecture is as follows:
- void __init Setup_arch (char **cmdline_p)
- {
- struct MACHINE_DESC *mdesc;
Click (here) to collapse or open
- This is the device description structure, for any board has defined such a structure, my previous article has introduced:
- "Uncompressing Linux ... done, booting the kernel" 1, Machine Type mismatch
- Unwind_init ();
Click (here) to collapse or open
- Initializes the BackTrace unwind system (stack fallback) based on arm Eabi, which is used primarily for address translation (ARCH/ARM/KERNEL/UNWIND.C)
- Setup_processor ();
Click (here) to collapse or open
- The processor type is detected again and the underlying variable associated with the processor is initialized. The processor information (including the cache) that the kernel starts with is printed by this function, for example:
- Cpu:armv7 Processor [413fc082] revision 2 (ARMV7), cr=10c53c7f
- Cpu:vipt nonaliasing data cache, vipt aliasing instruction Cache
- Mdesc = SETUP_MACHINE_FDT (__atags_pointer);
- if (!MDESC)
- Mdesc = Setup_machine_tags (Machine_arch_type);
Click (here) to collapse or open
- Match a struct MACHINE_DESC structure here with the device ID passed by bootloader.
- (This struct is the structure defined in ARCH/ARM/MACH-*/MACH-*.C: machine_start~machine_end)
- If there is no match on the dead loop.
- If a match is made, the machine name is printed and the tagged_list passed by bootloader is processed, and all tag information is saved to the corresponding global variable or struct.
- The machine information at the kernel startup is printed here, for example:
Click (here) to collapse or open
- Machine:ti8168evm
- Finally, the struct pointer is returned.
- Machine_desc = Mdesc;
- Machine_Name = mdesc->name;
Click (here) to collapse or open
- Initializes some global variables by matching struct MACHINE_DESC struct data
- if (mdesc->soft_reboot)
- Reboot_setup ("s");
Click (here) to collapse or open
- To set the restart type through the soft_reboot data in the struct MACHINE_DESC:
- "S" if present: Softreset; "H" if it does not exist: Hardreset
- 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;
Click (here) to collapse or open
- Here, you initialize some of the data in the MM_STRUCT structure init_mm by connecting the Linux code location data obtained in the script.
- PS: Each task has a MM_STRUCT structure to manage memory space, INIT_MM is the kernel itself mm_struct
- /* Fill Cmd_line for later use, protect boot_command_line data */
- strlcpy (Cmd_line, Boot_command_line, command_line_size);
- *cmdline_p = Cmd_line;
Click (here) to collapse or open
- Copy the Boot_command_line into the cmd_line. The key here is to know how the CmdLine is delivered when the system starts.
- Parse_early_param ();
Click (here) to collapse or open
- Handle the startup parameters defined as early in the struct Obs_kernel_param (mainly the parameters of the memory configuration section)
- which analyzes the [email protected] parameter initialization of the struct meminfo meminfo;
- Also initializes the Vmalloc=size parameter if it has a vmalloc_min
- Reference: Linux kernel high-low end Memory setup code tracking (ARM architecture)
- It is important to note that the parameters in the kernel cmdline are divided into early and non-early according to their required order.
- Include/linux/init.h:
Click (here) to collapse or open
- struct Obs_kernel_param {
- const char *STR; The name of the corresponding parameter in the CmdLine.
- Int (*setup_func) (char *); For this parameter, the dedicated handler function
- int early; //is a parameter that needs to be processed earlier
- };
- Two different parameters are defined in the kernel with different macros:
- Early: #define EARLY_PARAM (str, fn) \
- __setup_param (str, FN, FN, 1)
- Non-early: #define __SETUP (str, fn) \
- __setup_param (str, FN, FN, 0)
- Using the parameters defined by these two macros is related to the schema, and some structures or boards can define their own specific parameters and processing functions. For the more important "men" parameter is the early parameter.
- Sanity_check_meminfo ();
Click (here) to collapse or open
- Here you set the HIGHMEM variable in each bank in the struct Meminfo meminfo,
- Determine if memory in each bank belongs to high-end memory through Vmalloc_min
- Arm_memblock_init (&meminfo, Mdesc);
Click (here) to collapse or open
- This is where data from the Meminfo is sorted by address data from small to large, and global memblock data is initialized.
- Paging_init (MDESC);
Click (here) to collapse or open
- Sets the reference page table for the kernel.
- This page table is used not only for physical memory mapping, but also for managing the Vmalloc zone.
- One of the most important functions in this function is the initialization of the BOOTMEM allocator!
- Request_standard_resources (MDESC);
Click (here) to collapse or open
- initializes the memory-related global struct-body variables by obtaining data from the device description struct (struct MACHINE_DESC) and the address data generated at compile time.
- Unflatten_device_tree ();
Click (here) to collapse or open
- Get memory-related information by using the "non-flat device tree" information in the startup parameters (if any)
- #ifdef CONFIG_SMP
- if (IS_SMP ())
- Smp_init_cpus ();
- #endif
Click (here) to collapse or open
- For SMP processors, initialize the possible CPU mappings-this describes the possible CPU
- Reserve_crashkernel ();
Click (here) to collapse or open
- Reserved kernel for kernel crashes
- This feature preserves the export of kernel information when the main kernel crashes by "crashkernel=" in the kernel command line parameter.
- Cpu_init ();
Click (here) to collapse or open
- Initialize a CPU and set up a PER-CPU stack
- Tcm_init ();
Click (here) to collapse or open
- Initializes the TCM (tightly coupled memory) inside arm.
- Reference: "Understanding of ARM's compact memory TCM"
- ARM's official website also has the introduction document
- #ifdef Config_multi_irq_handler
- HANDLE_ARCH_IRQ = mdesc->handle_irq;
- #endif
Click (here) to collapse or open
- The call device describes the MDESC->HANDLE_IRQ function in the struct, and the purpose is unknown.
- #ifdef CONFIG_VT
- #if defined (config_vga_console)
- CONSWITCHP = &vga_con;
- #elif defined (config_dummy_console)
- CONSWITCHP = &dummy_con;
- #endif
- #endif
- Early_trap_init ();
Click (here) to collapse or open
- Early initialization of an interrupt vector table
- if (mdesc->init_early)
- Mdesc->init_early ();
Click (here) to collapse or open
- It is called here if the device description struct defines the init_early function (which should be the meaning of an early initialization).
- }
This function mainly checks to see if the processor type matches, and obtains the processor information to set the processor's associated underlying parameters.
- static void __init setup_processor (void)
- {
- struct Proc_info_list *list;
- /*
- * Locate the processor in the list of supported processors
- * Connector for us to create this list, from * arch/arm/mm/proc-*. the entrance in S
- */
- List = Lookup_processor_type (read_cpuid_id ());
- if (!list) {
- PRINTK ("CPU configuration botched (ID%08x), unable"
- "To Continue.\n", read_cpuid_id ());
- while (1);
- }
Click (here) to collapse or open
- Check the processor type again here, although this is already done in the assembly code.
- Cpu_name = list->cpu_name;
- #ifdef MULTI_CPU
- Processor = *list->proc;
- #endif
- #ifdef MULTI_TLB
- Cpu_tlb = *list->tlb;
- #endif
- #ifdef Multi_user
- Cpu_user = *list->user;
- #endif
- #ifdef Multi_cache
- Cpu_cache = *list->cache;
- #endif
Click (here) to collapse or open
- Initialize CPU-related global variables by data obtained from struct proc_info_list
- PRINTK ("CPU:%s [%08x] revision%d (armv%s), cr=%08lx\n",
- Cpu_name, read_cpuid_id (), read_cpuid_id () & 15,
- Proc_arch[cpu_architecture ()], cr_alignment);
Click (here) to collapse or open
- Processor information for the print kernel when it starts
- sprintf (Init_utsname ()->machine, "%s%c", List->arch_name, ENDIANNESS);
- sprintf (Elf_platform, "%s%c", List->elf_name, ENDIANNESS);
- Elf_hwcap = list->elf_hwcap;
- #ifndef Config_arm_thumb
- Elf_hwcap &= ~hwcap_thumb;
- #endif
- Feat_v6_fixup ();
Click (here) to collapse or open
- Masking some features for specific arm core software
- Cacheid_init ();
Click (here) to collapse or open
- Initializing the cache in the arm core
- Cpu_proc_init ();
Click (here) to collapse or open
- Macro:
- #define Cpu_proc_init __glue (cpu_name,_proc_init)
- Intended to invoke processor-specific initialization functions.
- }
Linux Kernel Source Analysis--Kernel boot (4) Image kernel boot (setup_arch function) (Linux-3.0 ARMv7) "Go"