Linux核心代碼學習筆記(2.6.21.7 ARM) — 核心啟動函數start_kernel

來源:互聯網
上載者:User

其實對核心的代碼已經分析很久了,早就想自己寫些什麼,從今天開始,從新繼續我的部落格!

這幾年都在與Linux打交道了,而且我覺得我也真正的愛上了Linux,所以就寫些Linux的東西吧!

Linux的東西很多,就核心而言,已經無法一個人去瞭解所有的機制和細節了。但好在源碼是可以隨時取到的,只要你熟悉和瞭解核心的一些基本特性,還是可以很容易上手的!

下面,我就把我自己的一些學習經曆寫出來和大家分享一下!

首選,核心代碼裡有大小寫重名的檔案,所以,從網上下載了核心源碼包以後,不能直接在Windows下解壓,否則會有些檔案被大小寫重複的檔案名稱複蓋掉!主要是網路相關的。我暫時先不想瞭解網路相關的內容,所以,就先在Windows下,使用SourceInsight來看代碼!如果要看到全部的代碼,還是要在Linux系統下解壓代碼!

另外,我對X86體繫結構的代碼也暫時不感興趣,先從ARM入手,不過不同的體繫結構,關係並不太大,明白一些機制以後,大部份是一樣的!

先從第一個函數入手:

E:\Projects\kernel\linux-2.6.21.1.src\init\main.c (501/825)

asmlinkage void __init start_kernel(void);

這個函數是核心由引導程式引導以後,由自解壓程式解壓以後執行的第一個函數,可以認為是整個核心的入口函數,以後我分析的代碼全部從這個函數開始!

這個函數做的事情相對比較簡單,就是線性初始化一些核心的基礎機制,如中斷,記憶體管理,進程管理,訊號,檔案系統,KO等!最後就啟動一個init線程,init線程再讀取檔案系統裡的init程式,做為系統的第一個進程而存在!

 

其實,start_kernel函數是0是做為0號進程存在的,它在最後就是空轉CPU:

代碼

/*
 * The idle thread.  We try to conserve power, while trying to keep
 * overall latency low.  The architecture specific idle is passed
 * a value to indicate the level of "idleness" of the system.
 */
void cpu_idle(void)
{
    local_fiq_enable();

    /* endless idle loop with no priority at all */
    while (1) {
        void (*idle)(void) = pm_idle;

#ifdef CONFIG_HOTPLUG_CPU
        if (cpu_is_offline(smp_processor_id())) {
            leds_event(led_idle_start);
            cpu_die();
        }
#endif

        if (!idle)
            idle = default_idle;
        leds_event(led_idle_start);
        while (!need_resched())
            idle();
        leds_event(led_idle_end);
        preempt_enable_no_resched();
        schedule();
        preempt_disable();
    }
}

 

而在它之前,啟動的init線程,則是運行檔案系統裡的init程式:

代碼

/* This is a non __init function. Force it to be noinline otherwise gcc
 * makes it inline to init() and it becomes part of init.text section
 */
static int noinline init_post(void)
{
    free_initmem();
    unlock_kernel();
    mark_rodata_ro();
    system_state = SYSTEM_RUNNING;
    numa_default_policy();

    if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
        printk(KERN_WARNING "Warning: unable to open an initial console.\n");

    (void) sys_dup(0);
    (void) sys_dup(0);

    if (ramdisk_execute_command) {
        run_init_process(ramdisk_execute_command);
        printk(KERN_WARNING "Failed to execute %s\n",
                ramdisk_execute_command);
    }

    /*
     * We try each of these until one succeeds.
     *
     * The Bourne shell can be used instead of init if we are
     * trying to recover a really broken machine.
     */
    if (execute_command) {  /* 如果有啟動參數做為執行命令,就執行 */
        run_init_process(execute_command);
        printk(KERN_WARNING "Failed to execute %s.  Attempting "
                    "defaults...\n", execute_command);
    }   /* 依次查詢檔案系統裡的init程式,這裡的run_init_process函數不能返回,否則啟動失敗 */
    run_init_process("/sbin/init");
    run_init_process("/etc/init");
    run_init_process("/bin/init");
    run_init_process("/bin/sh");

    panic("No init found.  Try passing init= option to kernel.");
}

 

 因為核心為很多體繫結構的CPU實現具體的函數,所以一個函數可能在很多目錄裡的同名檔案所實現。在查詢是具體的哪個函數時,要對應的具體的體繫結構。如果對應的具體體繫結構裡沒有相關函數,就可在使用通用的函數或者通用的體繫結構裡的函數!

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.