<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > uclinux啟動(dòng)過程詳細(xì)分析

          uclinux啟動(dòng)過程詳細(xì)分析

          作者: 時(shí)間:2018-08-31 來源:網(wǎng)絡(luò) 收藏

          本文引用地址:http://www.ex-cimer.com/article/201808/388126.htm

          void __init start_kernel(void)

          {

          char * command_line;

          unsigned long mempages;

          extern char saved_command_line[];

          /*

          * Interrupts are still disabled. Do necessary setups, then

          * enable them

          */

          lock_kernel();

          printk(linux_banner);

          setup_arch(command_line);

          printk(“Kernel command line: %s/n”, saved_command_line);

          parse_options(command_line);

          trap_init();

          init_IRQ();

          sched_init();

          softirq_init();

          time_init();

          /*

          * HACK ALERT! This is early. We‘re enabling the console before

          * we’ve done PCI setups etc, and console_init() must be aware of

          * this. But we do want output early, in case something goes wrong.

          */

          console_init();

          #ifdef CONFIG_MODULES

          init_modules();

          #endif

          if (prof_shift) {

          unsigned int size;

          /* only text is profiled */

          prof_len = (unsigned long) _etext - (unsigned long) _stext;

          prof_len 》》= prof_shift;

          size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;

          prof_buffer = (unsigned int *) alloc_bootmem(size);

          }

          kmem_cache_init();

          sti();

          calibrate_delay();

          #ifdef CONFIG_BLK_DEV_INITRD

          if (initrd_start !initrd_below_start_ok initrd_start 《 min_low_pfn 《《 PAGE_SHIFT)

          {

          printk(KERN_CRIT “initrd overwritten (0x%08lx 《 0x%08lx) - ”

          “disabling it./n”,initrd_start,min_low_pfn 《《 PAGE_SHIFT);

          initrd_start = 0;

          }

          #endif

          mem_init();

          kmem_cache_sizes_init();

          pgtable_cache_init();

          mempages = num_physpages;

          fork_init(mempages);

          proc_caches_init();

          vfs_caches_init(mempages);

          buffer_init(mempages);

          page_cache_init(mempages);

          #if defined(CONFIG_ARCH_S390)

          ccwcache_init();

          #endif

          signals_init();

          #ifdef CONFIG_PROC_FS

          proc_root_init();

          #endif

          #if defined(CONFIG_SYSVIPC)

          ipc_init();

          #endif

          check_bugs();

          printk(“POSIX conformance testing by UNIFIX/n”);

          /*

          * We count on the initial thread going ok

          Like idlers init is an unlocked kernel thread,which will

          * make syscalls (and thus be locked)。

          */

          smp_init();

          rest_init();

          }

          內(nèi)核啟動(dòng)之后需要執(zhí)行的第一個(gè)函數(shù)是start_kernel()(在linux/init/main.c文件中)。

          start_kernel()

          完成下面一系列初始化的工作。

          ◆printk(1inux_banner),顯示Linux內(nèi)核的版本信息。

          ◆ setup_arch(command_line),做與體系結(jié)構(gòu)相關(guān)的初始化工作。

          ◆ parse_options(command_line),解釋系統(tǒng)參數(shù)。

          ◆ trap_init(),設(shè)置系統(tǒng)異常的入口點(diǎn)。

          ◆ init_IRQ(),初始化系統(tǒng)中斷服務(wù)。

          ◆ sched_init(),系統(tǒng)調(diào)度器的初始化。

          ◆ time_init(),時(shí)鐘、定時(shí)器初始化。

          ◆ softirq_init(),系統(tǒng)軟中斷的初始化。

          ◆console_init(),控制臺(tái)初始化。

          ◆kmem_cache_init(),內(nèi)核cache的初始化。

          ◆calibrate_delay(),校準(zhǔn)時(shí)鐘。

          ◆mem_init(),內(nèi)存初始化。

          ◆kmem_cache_sizes_init(),創(chuàng)建及設(shè)置通用cache。

          ◆fork_init(mempages),建立uidcache,并且根據(jù)系統(tǒng)內(nèi)存大小來確定最大進(jìn)程數(shù)目。

          ◆buffer_init(mempages),塊設(shè)備緩沖區(qū)的初始化。初始化一系列的cache。

          ◆check_bugs(),檢查體系結(jié)構(gòu)漏洞。

          ◆kernel_thread(init NULL,CLONE_FS | CLONE_FILES | CLONE_SIGNAL),創(chuàng)建第一個(gè)核心進(jìn)程,啟動(dòng)init進(jìn)程。

          _idle(),運(yùn)行idle進(jìn)程

          接下去做的工作由init()函數(shù)來完成。init()首先要鎖定內(nèi)核,然后調(diào)用do_basic_setup( )來完成外部設(shè)備以及驅(qū)動(dòng)程序的初始化。外設(shè)的初始化要根據(jù)內(nèi)核的配置來決定,一般需要做下面的初始化工作:

          ◆PCI總線初始化。

          ◆網(wǎng)絡(luò)初始化。

          ◆一系列其他設(shè)備的初始化。

          ◆start_context_thread()創(chuàng)建事件管理核心進(jìn)程keventd。

          ◆通過do_initcalls()函數(shù)來啟動(dòng)任何使用__initcall標(biāo)識(shí)的函數(shù)。

          ◆文件系統(tǒng)初始化。

          ◆加載文件系統(tǒng)。

          在do_basic_setup()調(diào)用完成之后,init()會(huì)釋放初始化函數(shù)所用的內(nèi)存,并且打開/dev/console設(shè)備重新定向控制臺(tái),讓系統(tǒng)調(diào)用execve來執(zhí)行程序init。

          到這里為止,Linux 內(nèi)核的初始化工作已經(jīng)完成。然后開始用戶態(tài)進(jìn)程的初始化。

          =============================================================

          中內(nèi)存模塊的啟動(dòng)初始化

          arch/armnommu/kernel/entry_armv.S是一個(gè)匯編文件,他包含了一個(gè)kernel_entry的定義,這是整個(gè)內(nèi)核的進(jìn)入點(diǎn)。在完成某些平臺(tái)相關(guān)的初始化工作之后,執(zhí)行流程跳轉(zhuǎn)到start_kerne()處。從這里開始考察的內(nèi)存模塊啟動(dòng)初始化是如何實(shí)現(xiàn)的。

          start_kernel()中與內(nèi)存模塊相關(guān)的函數(shù)調(diào)用流程如下:

          setup_arch() paging_init() free_area_init() mem_init()

          下面分別分析這些函數(shù)各自的功能以及對(duì)他們的改造。

          (1) setup_arch()

          setup_arch()首先根據(jù)目前內(nèi)核所配置的平臺(tái)向某些特定地址寫入特殊字符序列,以完成對(duì)特定硬件的初始化,比如工作狀態(tài)發(fā)光二極管、錯(cuò)誤和報(bào)警發(fā)光二極管。



          關(guān)鍵詞: uClinux cpu 控制器

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();