初始化0號進程

來源:互聯網
上載者:User

arch/x86/kernel/head_32.S的336行,進入分頁後的核心程式碼片段,執行lss stack_start,%esp指令,立即為進程0建立核心態堆棧。stack_start定義在657行:

657 ENTRY(stack_start)

658        .long init_thread_union+THREAD_SIZE

659        .long __BOOT_DS

 

我們看到核心態堆棧由init_thread_union表示,其在include/linux/sched.h中被定義成一個全域變數:

extern union thread_union init_thread_union;

union thread_union {

       struct thread_info thread_info;

       unsigned long stack[THREAD_SIZE/sizeof(long)];

};

 

#define THREAD_SIZE        (PAGE_SIZE << THREAD_ORDER)

 

由於PAGE_SIZE是4096,THREAD_ORDER在32位x86體系中是1,所以THREAD_SIZE的值為8k。所以這個thread_union的大小也為8k。關於核心棧的詳細內容請參考部落格“進程相關的資料結構” .

 

那麼,對於一個進程,最重要的是什麼呢?兩個東西,一個是thread_info,另一個就是著名的task_struct。這個0號進程的thread_info,我們已經看到了,是在init_thread_union中。那麼這個task_struct又在哪兒呢?看到arch/x86/kernel/init_task.c:

23 union thread_union init_thread_union __init_task_data =

  24        { INIT_THREAD_INFO(init_task) };

 

紮眼一看,很奇怪,怎麼多了個__init_task_data?別緊張,其實,它只是一個宏,不是什麼變了,來自include/linux/init_task.h的186行:

#define __init_task_data __attribute__((__section__(".data.init_task")))

 

那麼,上面的內容就展開成了:

union thread_union init_thread_union __attribute__((__section__(".data.init_task"))) =

{ INIT_THREAD_INFO(init_task) };

 

這是一條指派陳述式,對聯合體init_thread_union賦初始值。暈了吧,c語言的功底是多麼重要啊,通過核心的學習,你也學會了如何對聯合體賦初值並且把資料放進指定的資料區段.data.init_task了吧。

 

繼續,具體到如何賦值呢?先講講init_task這個全域變數,定義在arch/x86/kernel/init_task.c的第31行:

struct task_struct init_task = INIT_TASK(init_task);

 

這不,0號進程的task_struct出現了,就是init_task。在對init_thread_union賦初值的時候,同時也通過調用INIT_TASK宏對init_task賦初值:

 

110#define INIT_TASK(tsk)  /

 111{                                                                       /

 112        .state          = 0,                                            /

 113        .stack          = &init_thread_info,                            /

 114        .usage          = ATOMIC_INIT(2),                               /

 115        .flags          = PF_KTHREAD,                                   /

 116        .lock_depth     = -1,                                           /

 117        .prio           = MAX_PRIO-20,                                  /

 118        .static_prio    = MAX_PRIO-20,                                  /

 119        .normal_prio    = MAX_PRIO-20,                                  /

 120        .policy         = SCHED_NORMAL,                                 /

 121        .cpus_allowed   = CPU_MASK_ALL,                                 /

 122        .mm             = NULL,                                         /

 123        .active_mm      = &init_mm,                                     /

 124        .se             = {                                             /

 125                .group_node     = LIST_HEAD_INIT(tsk.se.group_node),    /

 126        },                                                              /

 127        .rt             = {                                             /

 128                .run_list       = LIST_HEAD_INIT(tsk.rt.run_list),      /

 129                .time_slice     = HZ,                                   /

 130                .nr_cpus_allowed = NR_CPUS,                             /

 131        },                                                              /

 132        .tasks          = LIST_HEAD_INIT(tsk.tasks),                    /

 133        .pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO), /

 134        .ptraced        = LIST_HEAD_INIT(tsk.ptraced),                  /

 135        .ptrace_entry   = LIST_HEAD_INIT(tsk.ptrace_entry),             /

 136        .real_parent    = &tsk,                                         /

 137        .parent         = &tsk,                                         /

 138        .children       = LIST_HEAD_INIT(tsk.children),                 /

 139        .sibling        = LIST_HEAD_INIT(tsk.sibling),                  /

 140        .group_leader   = &tsk,                                         /

 141        .real_cred      = &init_cred,                                   /

 142        .cred           = &init_cred,                                   /

 143        .cred_guard_mutex =                                             /

 144                 __MUTEX_INITIALIZER(tsk.cred_guard_mutex),             /

 145        .comm           = "swapper",                                    /

 146        .thread         = INIT_THREAD,                                  /

 147        .fs             = &init_fs,                                     /

 148        .files          = &init_files,                                  /

 149        .signal         = &init_signals,                                /

 150        .sighand        = &init_sighand,                                /

 151        .nsproxy        = &init_nsproxy,                                /

 152        .pending        = {                                             /

 153                .list = LIST_HEAD_INIT(tsk.pending.list),               /

 154                .signal = {{0}}},                                       /

 155        .blocked        = {{0}},                                        /

 156        .alloc_lock     = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock),         /

 157        .journal_info   = NULL,                                         /

 158        .cpu_timers     = INIT_CPU_TIMERS(tsk.cpu_timers),              /

 159        .fs_excl        = ATOMIC_INIT(0),                               /

 160        .pi_lock        = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock),        /

 161        .timer_slack_ns = 50000, /* 50 usec default slack */            /

 162        .pids = {                                                       /

 163                [PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),            /

 164                [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),           /

 165                [PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),            /

 166        },                                                              /

 167        .dirties = INIT_PROP_LOCAL_SINGLE(dirties),                     /

 168        INIT_IDS                                                        /

 169        INIT_PERF_EVENTS(tsk)                                           /

 170        INIT_TRACE_IRQFLAGS                                          /

 171        INIT_LOCKDEP                                                 /

 172        INIT_FTRACE_GRAPH                                          /

 173        INIT_TRACE_RECURSION                                       /

 174        INIT_TASK_RCU_PREEMPT(tsk)                                 /

 175}

 

至於task_struct的詳細介紹,請查看部落格“進程相關的資料結構”,這裡只挑幾個重要的來說說。0號進程的stack就是剛才init_thread_info的地址;parent是他自己;thread是INIT_THREAD。還有一些是常量,如init_fs。等我們用到了再回過來看它。

 

現在,0號進程task_struct有了,下面就該來講講INIT_THREAD_INFO宏了,在arch/x86/include/asm/thread_info.h:

 

  46#define INIT_THREAD_INFO(tsk)                   /

  47{                                               /

  48        .task           = &tsk,                 /

  49        .exec_domain    = &default_exec_domain, /

  50        .flags          = 0,                    /

  51        .cpu            = 0,                    /

  52        .preempt_count  = INIT_PREEMPT_COUNT,   /

  53        .addr_limit     = KERNEL_DS,            /

  54        .restart_block = {                      /

  55                .fn = do_no_restart_syscall,    /

  56        },                                      /

  57}

 

執行完這個宏以後,init_thread_union就被初始化成以上內容了,至此,0號進程的task_struct和thread_info就初始化完畢了。注意,這個初始化不是在head_32.S中初始化的。大家也看到了,上面的內容都是在編譯的時候作為一個資料全域資料被初始化的,並且把他們放在.data.init_task資料區段中。head_32.S中只是將esp指標指向這個已經被初始化了的init_thread_union以上8k作為棧頂,並向下移動(回憶一下c程式的特點,並參考“進程相關的資料結構”中那個圖)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.