linux init_task 的初始化

linux init_task 的初始化

日期

内核版本

架构

作者

2017-03-17

Linux-3.4.0

arm

jlovej

 

前言:

Init_task 是系统的0号进程,又称swapper进程,又称idle任务。它是所有进程、线程的祖宗,包括1号进程init,2号内核线程kthreadd。

Init_task的栈针sp:

进入start_kernel,可以说就已经运行在init_task的上下文了,因为此时栈针sp已经指向init_task的栈了。

Init_task的栈:

linux/arch/arm/kernel/init_task.c中:

structtask_struct init_task = INIT_TASK(init_task);

unionthread_union init_thread_union __init_task_data =

                { INIT_THREAD_INFO(init_task) };

init_thread_union即为init_task的栈,也是一个8K对齐的thread_info结构体。init_thread_union为静态变量,被编译到内核的data段。

系统栈针sp的初始化:

linux/arch/arm/kernel/head.S中:

ENTRY(stext)

                ldr           r13, =__mmap_switched                   @address to jump to after

                                                                                                @mmu has been enabled

                adr          lr, BSYM(1f)                                           @return (PIC) address

                mov        r8, r4                                                      @set TTBR1 to swapper_pg_dir

 ARM(     add         pc, r10, #PROCINFO_INITFUNC          )

1:            b              __enable_mmu

系统使能mmu时,跳转到__turn_mmu_on,enablemmu后跳转到r13,即__mmap_switched,最后跳转到start_kernel。

linux/arch/arm/kernel/head-common.S中

__mmap_switched:

                adr          r3, __mmap_switched_data

 

                ldmia      r3!, {r4, r5, r6, r7}

                cmp        r4, r5                                                      @Copy data segment if needed

1:            cmpne    r5, r6

                ldrne      fp, [r4], #4

                strne       fp, [r5], #4

                bne         1b

 

                mov        fp, #0                                                      @Clear BSS (and zero fp)

1:            cmp        r6,r7

                strcc       fp, [r6],#4

                bcc          1b

 

 ARM(     ldmia      r3, {r4, r5, r6, r7, sp})

                str           r9, [r4]                                   @Save processor ID

                str           r1, [r5]                                   @Save machine type

                str           r2, [r6]                                   @Save atags pointer

                bic           r4, r0, #CR_A                                        @Clear 'A' bit

                stmia       r7, {r0, r4}                                             @Save control register values

                b              start_kernel

ENDPROC(__mmap_switched)

 

                .align       2

                .type       __mmap_switched_data, %object

__mmap_switched_data:

                .long       __data_loc                                            @r4

                .long       _sdata                                                    @r5

                .long       __bss_start                                           @r6

                .long       _end                                                       @r7

                .long       processor_id                                        @r4

                .long       __machine_arch_type                       @r5

                .long       __atags_pointer                                   @r6

                .long       cr_alignment                                        @r7

                .long       init_thread_union + THREAD_START_SP @ sp

                .size        __mmap_switched_data, . - __mmap_switched_data

其中,ARM(     ldmia     r3, {r4, r5, r6,r7, sp})赋值sp

sp = init_thread_union +THREAD_START_SP,即init_task的栈顶。

所以,之后start_kernel中的任务都是基于此sp。当然,中断有中断的栈。

Init_task的后续初始化:

                http://blog.csdn.net/gatieme/article/details/51484562

进程userspace栈的由来:

一个普通进程,其userspace栈大小可以通过cat/proc/$pid/limits |grep stack 看到。栈大小是由task_struct->signal->rlim[RLIMIT_STACK]决定的,在该进程被创建时,rlim是复制从父进程的rlim:

do_fork àcopy_processà copy_signal:

memcpy(sig->rlim, current->signal->rlim, sizeofsig->rlim);

父进程又是复制爷爷的,爷爷又是复制祖宗的,最终还是拷贝的init_task的rlim。

而init_task的rlim在这定义的:

#define INIT_RLIMITS                                                                                                    \

{                                                                                                                                              \

                [RLIMIT_CPU]                   = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_FSIZE]                 = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_DATA]                 = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_STACK]               = {       _STK_LIM,   _STK_LIM_MAX },      \

                [RLIMIT_CORE]                 = {              0,  RLIM_INFINITY },    \

                [RLIMIT_RSS]                     = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_NPROC]                             = {              0,              0 },     \

                [RLIMIT_NOFILE]                             = {   INR_OPEN_CUR,   INR_OPEN_MAX },            \

                [RLIMIT_MEMLOCK]      = {   MLOCK_LIMIT,    MLOCK_LIMIT },   \

                [RLIMIT_AS]                       = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_LOCKS]                               = {  RLIM_INFINITY,  RLIM_INFINITY },    \

                [RLIMIT_SIGPENDING]  = {                           0,                   0 },   \

                [RLIMIT_MSGQUEUE]   = {  MQ_BYTES_MAX,   MQ_BYTES_MAX },         \

                [RLIMIT_NICE]                  = { 0, 0 },                                                               \

                [RLIMIT_RTPRIO]                             = { 0, 0 },                                                               \

                [RLIMIT_RTTIME]                             = {  RLIM_INFINITY,  RLIM_INFINITY },    \

}

在我的系统上,#define_STK_LIM        (8*1024*1024),用户态栈大小默认是8M。

 

 

 


你可能感兴趣的:(kernel初始化,init_task,栈针)