Linux kernel boot process

Start conditions:

CPU located in SVC mode, and IRQ and FIQ are disabled; the MMU Memory Management closed at this time is a physical address; off data cache, instruction cache No; general register R0 = 0, R1 = CPU type, R2 = kernel parameter physical address list.

Linux kernel, there are two images:

One kind of non-compressed kernel, called Image, and the other is a compressed version of it, called zImage. Depending on the kernel image, Linux kernel start at the beginning are different. Image zImage is the compressed form, so its size is smaller than the Image. But in order to be able to use zImage, it can only be executed after the beginning of plus decompression code, zImage decompression, so it's slower execution speed than Image. However, considering the capacity of the memory space for embedded systems in general is relatively small, the use zImage can take up less storage space, so the expense of a slight performance hit is worth it. It is generally the way embedded systems are used in compressed kernel.

 

Linux kernel image in the bootloader later copied to RAM, the Linux kernel can be started by the following Code Example: call_linux (0, machine_type, kernel_params_base ). Wherein, machine_tpye bootloader is detected the processor type, kernel_params_base a start address in the parameter RAM. [1 Jump to compression of the Linux kernel or uncompressed Linux kernel at]

For the  ARM processor family is, zImage program is the entrance arch / arm / boot / compressed / head.S. Which in turn do the following: Open the MMU and Cache, call decompress_kernel () extract the kernel , and finally by calling call_kernel () into the non-compressed kernel Image to start.

 

Linux kernel uncompressed entry in the file /arch/arm/kernel/head.S in stext segment . The segment base address is the address of the jump compressed core decompression. If the kernel is loaded uncompressed Image , then the bootloader will copy the kernel from Flash to RAM will jump directly to that address , thereby starting the Linux kernel. Linux systems of different architectures inlet files are different , and because the specific document architecture are, therefore generally written in assembly language [3]. ARM-based Linux system for processing, the file is head.S. The program calls by looking for the type of processor core and processor type the appropriate initialization function, and then create a page table (temporary kernel page tables), and finally jump to start_kernel () function to start the kernel initialization.

Jump to the start_kernel () function needs to be done before: determining the type of processor cores, the processor determines the type, the kernel creates a temporary page table (for core loading, typically 4MB or 8MB), this stage can be both real mode and protected mode can the memory access, platform-specific function calls cpu__flush, open mmu, switched data.

For example: type detection processor core is completed in assembly of __lookup_processor_type Functions. It can be achieved by the following code to its calling: bl __lookup_processor_type. When __lookup_processor_type call the end of the return to the original program, it will return results stored in registers. Wherein r8 saved flag in the page table, r9 processor ID number stored, r10 holds struproc_info_list structure associated with the processor address. Detection processor type is created in the compilation subroutine __lookup_architecture_type. And __lookup_processor_type similar to it by the code: to achieve it calls "bl __lookup_processor_type". When this function returns, the return structure will save r5, r6 and r7 three registers. R5 which holds the starting address of the RAM-based, r6 save the I / O base address, r7 saves I / O page table offset. When the end detection processor core and processor type, the subroutine calls __create_page_tables to create page table, it has to do is to map the physical address space of 4M RAM base address of the start of the virtual address 0xC0000000 began. For I S3C2410 development board, the RAM connected to the physical address 0x30000000, when the call ends __create_page_tables 0x30000000 ~ 0x30400000 to a physical address mapped to the virtual address 0xC0000000 ~ 0xC0400000.

 

After the end of all initialization, using the following code to jump to the start_kernel C program entry function () at , after the start of the kernel initialization:

start_kernel is after all a function of the entrance into the Linux platform system kernel initialization, it is mainly related to the completion of the remaining hardware platform initialization, after undergoing a series of related kernel initialization, calls the first user process -init process and wait for the user implementation process, so that the entire Linux kernel will boot up. The specific work functions are:

a, create exceptions to the scale and initialize the interrupt handler;

b, initialize the system kernel process scheduler and clock interrupt handling mechanism;

c, the initialization serial console (serial-console);

d, ARM-Linux usually during initialization to initialize a serial console as the kernel, so the kernel during the boot process can understand the system boot process through the serial output information to the developer or user.

e, create and initialize the system cache, provides a variety of mechanisms for cache memory calls, including; dynamic memory allocation, virtual file system (VirtualFile System) and page caching.

F, initialize memory management, and the memory size detected by the kernel memory occupied by the case;

Interprocess g, initialization of the system communication mechanisms (the IPC);

When all of the above initialization, start_kernel () function calls rest_init () function to initialize the final, including the creation of a system process to end the process -init start the kernel. Init process first series of hardware initialization parameters are then passed over the command line to mount the root file system. Finally, the init process executes one user transfer from the "init =" boot parameter to perform user-specified command, or execute the following process:

1 execve("/sbin/init",argv_init,envp_init);   

2 execve("/etc/init",argv_init,envp_init);   

3 execve("/bin/init",argv_init,envp_init);   

4 execve("/bin/sh",argv_init,envp_init)。  

When all initialization, cpu_idle () function is called to make the system is idle (idle) state and waits for the user program execution. At this point, the entire Linux kernel boot up.

 

reference:

https://www.cnblogs.com/wxb20/p/6266313.html

https://www.cnblogs.com/pengdonglin137/p/3632698.html#_labelTop

Guess you like

Origin blog.csdn.net/weixin_38812277/article/details/92002760