Linux kernel boot code analysis __linux

Source: Internet
Author: User

Based on MIPS architecture, this paper analyzes the linux-3.3.8

I. Kernel entrance

First, find the portal of kernel through a link script.

1. The kernel is compressed

/arch/mips/boot/compressed/makefile $ (obj)/head.o $ (obj)/decompress.o $ (obj)/dbg.o $ (obj)/piggy.o link to Vmlinuz, Link script for Ld.script vmlinuz: $ (SRC)/ld.script $ (vmlinuzobjs-y) $ (obj)/calc_vmlinuz_load_addr $ (call Cmd,zld) $ (call cmd , strip)
The vmlinux.bin.z is used as the Objcopy tool, packaged as data for PIGGY.O targets + = piggy.o objcopyflags_piggy.o: =--add-section=.image=$ (obj)/ VMLINUX.BIN.Z \--set-section-flags=.image=contents,alloc,load,readonly,data $ (obj)/piggy.o: $ (obj )/dummy.o $ (obj)/vmlinux.bin.z FORCE $ (call if_changed,objcopy)
Compress vmlinux.bin using compression tool to Vmlinux.bin.z tool_$ (config_kernel_gzip) = GZIP tool_$ (config_kernel_bzip2) = bzip2 tool_$ (CONFI G_kernel_lzma) = Lzma tool_$ (config_kernel_lzo) = Lzo
Targets + + vmlinux.bin.z $ (obj)/vmlinux.bin.z: $ (obj)/vmlinux.bin FORCE $ (call if_changed,$ (tool_y))

Visible in compression is the entrance for/arch/mips/boot/compressed/head.s

2. The kernel is uncompressed

The definition makefile Specifies the vmlinux link script:

Vmlinux-lds: = arch/$ (Srcarch)/kernel/vmlinux.lds, compiled VMLINUX.LDS.S by Vmlinux.lds:OUTPUT_ARCH (MIPS) ENTRY (kernel_ Entry) Phdrs {text Pt_load flags (7);/* RWX * * Pt_note flags (4);/* r__/} jiffies = jiffies_64; SECTIONS {. = 0x80001000/* read-only/_text =./* Text and read-only data/. Text: {. = ALIGN (8); * (. text.hot) * (. Text) * (. Ref.text) * (. Devinit.text) * (. Devexit.text) * (. Cpuinit.text) * (. Cpuexit.text) * (. text.unlikely). = ALIGN (8); __sched_text_start =.;   * (. sched.text) __sched_text_end =.; . = ALIGN (8); __lock_text_start =.;   * (. spinlock.text) __lock_text_end =.; . = ALIGN (8); __kprobes_text_start =.;   * (. kprobes.text) __kprobes_text_end =.; * (. text.*) * (. Fixup) * (. gnu.warning)}: Text = 0 _etext =.; /* End of text section * *

Visible Entrance for Kernel_entry

This only describes the uncompressed situation, because the compression is uncompressed after the jump to the kernel execution process is the same.

(ARCH/MIPS/KERNEL/HEAD.S) NESTED (Kernel_entry, SP) # Kernel entry point
Kernel_entry_setup # CPU Specific setup
Setup_c0_status_pri
/* We might not get launched in the address the kernel are linked to, so We jump there.         * * Ptr_la t0, 0f Jr t0 0:ptr_la t0, __bss_start # Clear. BSS//Will kernel BSS Chingqing zero long_s Zero, (t0) Ptr_la T1, __bss_stop-longsize 1:ptr_addiu t0, longsize long_s Zero, (t 0) bne t0, T1, 1b
long_s a0, fw_arg0 # Firmware arguments long_s A1, Fw_arg1 long_s A2, Fw_arg2 LONG _s A3, Fw_arg3
    mtc0        zero, CP0_CONTEXT     # Clear Context Register     ptr_la        $28, Init_thread_union        //union thread_union init_thread_union,  $28 Register pointing  init_ Thread_union     /* Set The SP after a empty pt_regs.  */    ptr_li         SP, _thread_size-32-pt_size     ptr_addu     SP, $28         //SP registers pointing to the stack space in  init_thread_union      back_to_back_c0_hazard  //sync C0 to prevent c0 adventures, see below for explanations     set_saved_sp     SP, t0, T1    //Save the value of the SP register to the KERNELSP variable, and save the process kernel state stack pointer in the KERNELSP variable     ptr_ SUBU    SP, 4 * szreg        # init stack pointer
J Start_kernel/Start C code, INIT/MAIN.C end (Kernel_entry)


The definition of Kernel_entry_setup is located at:

(arch/mips/include/asm/mach-brcmstb/kernel-entry-init.h). Macro Kernel_entry_setup # Save arguments for CFE Callba    CK SW A0, Cfe_handle//Saves the contents of the A0 registers to Cfe_handle, in order to kernel the functions in CFE to obtain kernel boot functions and other hardware configuration parameters, which are stored in the CFE environment variable SW A2, Cfe_entry//Save the contents of the A2 registers to cfe_entry SW A3 cfe_seal//Save the contents of the A3 registers to Cfe_seal JAL Nable_xks01. ENDM. Macro Smp_slave_setup. endm

(ARCH/MIPS/KERNEL/BMIPS_VEC.S)/*********************************************************************** * XKS01 Support * Certain CPUs support extending kseg0 to 1024MB. /LEAF (BMIPS_ENABLE_XKS01)
#if defined (config_xks01) mfc0 t0, $22, 3 li T1, 0x1ff0 Li T2, (1 << 12) | (1 << 9) or t0 T1 xor t0, T1 or t0, T2 mtc0 t0, $22, 3 BARRIER #endif/* Defined (CO NFIG_XKS01) * * *
JR RA
End (BMIPS_ENABLE_XKS01)


The definition of Setup_c0_status_pri is located at:

(ARCH/MIPS/KERNEL/HEAD.S). Macro Setup_c0_status_pri #ifdef config_64bit setup_c0_status st0_kx 0 #else Set Up_c0_status 0 0//will c0 status register clear 0 #endif. endm


Arch/mips/include/asm/hazards.h: _EHB assembly instruction, for synchronous c0, to prevent C0 Adventures Asmmacro (Back_to_back_c0_hazard, _EHB)

Current represents the process, let's look at its definition: #define Get_current () (Current_thread_info ()->task) #define Present get_current ()
Register struct Thread_info *__current_thread_info __asm__ ("$28"); #define CURRENT_THREAD_INFO () __current_thread_info
__current_thread_info is a register variable, $28 represents the GP register

So here Ptr_la $28, Init_thread_union is actually set to process No. 0,

Ptr_li sp, _thread_size-32-pt_size

Ptr_addu sp, $28

sp= $28 + _thread_size-32-pt_size=$28 +8192-32-sizeof (struct pt_regs)

Union thread_union {
#ifndef config_x86
struct Thread_info thread_info;
#endif
unsigned long stack[thread_size/sizeof (long)];

};

struct Thread_info {
struct Task_struct *task; /* Main task structure/*
struct Exec_domain *exec_domain; * Execution Domain * *
unsigned long flags; /* Low Level flags */
unsigned long tp_value; /* Thread pointer * *
__U32 CPU; /* Current CPU */
int preempt_count; /* 0 => preemptable, <0 => BUG * *


mm_segment_t Addr_limit; /* Thread Address spaces:
0-0XBFFFFFFF for User-thead
0-0XFFFFFFFF for Kernel-thread
*/
struct Restart_block restart_block;
struct Pt_regs *regs;

};

$28---------→+----------------+ low Address

| *task |

| ...              |

|   *regs | ----------------------------------+

grow↑|                                                      xxxxxxxxx | |

|  |                                                      xxxxxxxxx | |

SP---------> |                                                       xxxxxxxxx | |

|                                                        Byte (MB) | |

|    sizeof (Pt_regs) | ←------------------------------+

This allows the SP to switch to the kernel stack on the No. 0 process, and after setting the stack, you can perform the C-defined function.

two. Enter Start_kernel

asmlinkage void __init start_kernel (void)
{
Boot_init_stack_canary ();
Local_irq_disable ();

Tick_init ();

Setup_arch (&command_line);

Build_all_zonelists (NULL);
Page_alloc_init ();
Trap_init ();
Mm_init ();
Sched_init ();
INIT_IRQ ();
Prio_tree_init ();
Init_timers ();
Hrtimers_init ();
Softirq_init ();
Timekeeping_init ();
Time_init ();
Local_irq_enable ();
...
/* Do the rest non-__init ' Ed, we ' re now alive * *
Rest_init ();

}

static noinline void __init_refok rest_init (void)
{
int pid;
/*
* We need to spawn Init, it obtains PID 1, however
* The INIT task would end up wanting to create kthreads, which, if
* We schedule it before we create Kthreadd, would OOPS.
*/
Kernel_thread (Kernel_init, NULL, CLONE_FS |   Clone_sighand); Create the Init process, that is, the number 1th process

Rcu_read_lock ();
Kthreadd_task = Find_task_by_pid_ns (PID, &init_pid_ns);
Rcu_read_unlock ();
Complete (&kthreadd_done);

/*
* The boot idle thread must execute schedule ()
* At least once to get things moving:
*/
Init_idle_bootup_task (current);
Preempt_enable_no_resched ();
Schedule ();


/* Call to Cpu_idle with preempt disabled * *
Preempt_disable ();
Cpu_idle (); Process # No. 0

}

static int __init kernel_init (void * unused)
{

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.