久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

linux內(nèi)核啟動(dòng)過程學(xué)習(xí)總結(jié)

 趙帥蹲守圖書館 2014-02-25

通用寄存器的作用
r0
:在函數(shù)開始時(shí)使用
r1
:存放堆棧指針,,相當(dāng)于ia32架構(gòu)中的esp寄存器
r2
:存放當(dāng)前進(jìn)程的描述符的地址
r3
:存放第一個(gè)參數(shù)和返回地址
r4-r10
:存放函數(shù)的參數(shù)
r11
:用在指針的調(diào)用和當(dāng)前一些語言的環(huán)境指針
r12
:用于存放異常處理
r13
:保留做為系統(tǒng)線程ID
r14-r31
:作為本地變量,,具有非易失性

Linux啟動(dòng)過程描述

第一步:使用Boot Loader(一般是U-boot)加載Linux內(nèi)核映像到內(nèi)存,并負(fù)責(zé)目標(biāo)系統(tǒng)的基本初始化過程,,并搜集這個(gè)系統(tǒng)的基本信息,,比如內(nèi)存大小、處理器主頻,、外設(shè)的使用情況等一系列信息。然后把這些信息傳遞給linux內(nèi)核,。然后Boot loaderlinux內(nèi)核復(fù)制到從0x0000 0000 開始的物理內(nèi)存處(虛擬地址一般為0xc000 0000處)開始執(zhí)行,。

備注:這一部分內(nèi)容,,本文不做重點(diǎn)介紹。請參考《uboot啟動(dòng)過程學(xué)習(xí)總結(jié).doc

 

*

 

*******************************************************************************

記錄2linux kernel 鏈接文件,、入口函數(shù)和相關(guān)宏定義等

Bootstraploader過程:從文件\arch\powerpc\boot\zImage.lds中可以看出,,bootstraploader的入口為_zimage_start。在代碼arch\powerpc\boot\crt0.S

D:\virtual_machine\share_folder\linux-2.6.23\arch\powerpc\boot\zImage.lds中定義的入口地址為4MB,,見下面

SECTIONS

{

  . = (4*1024*1024);

  _start = .;

  .text      :

進(jìn)入linux內(nèi)核:vmlinux.lds看到,,內(nèi)核入口為_stext,通過段.text.head 將代碼定位到0xc0000000處,。

在代碼arch/powerpc/kernel/head_32.S_stext之后緊接著是_start,,他們之間沒有代碼,他們表示相同的地址,。

vmlinux.lds中將.text.head規(guī)劃為.text的第一個(gè)字段(保證了地址定位到0xc0000000),。

*******************************************************************************

 

 

 

 

第二步:Linux系統(tǒng)的初始化

1、  bootstraploader 過程

注意:需要知道從uboot跳到此處時(shí),,r3寄存器的內(nèi)容,,以及其他register的內(nèi)容

如果運(yùn)行地址和鏈接地址不同,則修正got表中各個(gè)函數(shù)的指針

清零BSS

調(diào)用platform_init(),,保存bd__res,,初始化ppc_mdppc module)中的各個(gè)函數(shù)。

調(diào)用arch\powerpc\boot\main.c中的start()

start()中:

1.1將命令行拷貝到cmdline

1.2調(diào)用open函數(shù)打開串口

1.3解壓縮kernel代碼

1.4解壓縮ramdisk image

1.5最終初始化設(shè)備樹

1.6跳到內(nèi)核代碼中執(zhí)行

有兩個(gè)調(diào)用語句,,應(yīng)該是運(yùn)行了語句:kentry(ft_addr, 0, NULL); need confirm

2,、  進(jìn)入linux內(nèi)核

入口:arch/powerpc/kernel/head_32.S中的_start

2.1 early_init() ,,arch/powerpc/kernel/setup_32.c

計(jì)算運(yùn)行地址和鏈接地址的差值,。根據(jù)cpu型號(hào)調(diào)用do_feature_fixups函數(shù)來對(duì)__ftr_fixup段進(jìn)行修復(fù)處理。

例如若HIDO寄存器的HIGH_BAT_EN位置位,,另外的4組寄存器 IBATs (4–7) 4 DBATs (4-7) 將會(huì)被激活,,__ftr_fixup段中對(duì)這8組寄存器進(jìn)行初始化的代碼就會(huì)生效;否則__ftr_fixup中的這段代碼就會(huì)被nop指令所代替,!

early_init()函數(shù)調(diào)用identify_cpu()函數(shù)通過cpu中的pvr寄存器存放的CPU核的版本號(hào)在全局?jǐn)?shù)組cpu_specs中尋找到當(dāng)前cpu的詳細(xì)信息,,identify_cpu()函數(shù)在找到之后,會(huì)調(diào)用setup_cpu_spec()函數(shù)把上述cpu的信息所在的鏈接地址賦值給cur_cpu_spec變量

 

2.2 mmu_off() 關(guān)閉mmu

2.3 flush_tlbs() TLB中移除頁表

2.4 call_setup_cpu()call_setup_cpu()位于misc_32.S文件中

2.5 relocate_kernel():把內(nèi)核代碼拷貝到鏈接地址指向的位置

2.6 turn_on_mmu():映射了256MB內(nèi)存,,就可以避免調(diào)用reloc_offset()函數(shù)來顯式得把虛擬地址映射到物理地址!

2.7跳到start_here()函數(shù)中運(yùn)行,,可以認(rèn)為是真正內(nèi)核開始運(yùn)行。,。,。

2.7.1加載0號(hào)線程上下文,全局變量init_task

注:0號(hào)線程優(yōu)先級(jí)為120,從#define INIT_TASK(tsk)中可以看出,。

init_task是進(jìn)程0使用的進(jìn)程描述符,,也是Linux系統(tǒng)中第一個(gè)進(jìn)程描述符,該進(jìn)程的描述符在arch/powerpc/kernel/init_task.c中定義,,代碼片段如下:

struct  task_struct  init_task = INIT_TASK(init_task);

init_task描述符使用宏INIT_TASK對(duì)init_task的進(jìn)程描述符進(jìn)行初始化,,宏INIT_TASKinclude/linux/init_task.h文件中

init_taskLinux內(nèi)核中的第一個(gè)線程,它貫穿于整個(gè)Linux系統(tǒng)的初始化過程中,,該進(jìn)程也是Linux系統(tǒng)中唯一一個(gè)沒有用kernel_thread() 函數(shù)創(chuàng)建的進(jìn)程,!在init_task進(jìn)程執(zhí)行后期,它會(huì)調(diào)用kernel_thread()函數(shù)創(chuàng)建第一個(gè)核心進(jìn)程kernel_init,,同時(shí)init_task進(jìn)程繼續(xù)對(duì)Linux系統(tǒng)初始化,。在完成初始化后,init_task會(huì)退化為cpu_idle進(jìn)程,,當(dāng)Core 0的就緒隊(duì)列中沒有其它進(jìn)程時(shí),,該進(jìn)程將會(huì)獲得CPU運(yùn)行。新創(chuàng)建的1號(hào)進(jìn)程kernel_init將會(huì)逐個(gè)啟動(dòng)次CPU,并最終創(chuàng)建用戶進(jìn)程,!

備注:core0上的idle進(jìn)程由init_task進(jìn)程退化而來,,而APidle進(jìn)程則是BSP在后面調(diào)用fork()函數(shù)逐個(gè)創(chuàng)建的,我們會(huì)在后面詳細(xì)討論,。

init_task進(jìn)程使用init_thread_union數(shù)據(jù)結(jié)構(gòu)描述的內(nèi)存區(qū)域作為該進(jìn)程的堆??臻g,并且和自身的thread_info參數(shù)公用這一內(nèi)存空間空間,,其數(shù)據(jù)結(jié)構(gòu)的定義如下(linux- 2.6.38/include/linux/sched.h)

2.7.2 調(diào)用machine_init()分析OF樹的結(jié)構(gòu),,獲得當(dāng)前處理器的內(nèi)存使用情況, 創(chuàng)建LMB結(jié)構(gòu),同時(shí)獲得當(dāng)前CPUOF樹中的硬件信息;保存命令行等,,從cmd_line拷貝uboot引導(dǎo)kernel時(shí)使用的命令行參數(shù)到boot_command_line,,并并使用parse_early_param()函數(shù)分析這些命令行參數(shù)。

 

2.7.3 調(diào)用MMU_init(),,為LinuxPowerPC建立MMU地址映射,,區(qū)分memory normal 區(qū)域和高端區(qū)域。(768M896M為分界線)

注:會(huì)把也映射信息更新到init_mm. pgd,,即swapper_pg_dir指向的頁表中,。最終應(yīng)該會(huì)把init_mm填到init1 線程任務(wù)結(jié)構(gòu)的mm_struct中。需要后續(xù)驗(yàn)證***********************

*****************************************************************************************************************************************

2.7.4 調(diào)用load_up_mmu()重新裝載MMU相關(guān)的寄存器,,開啟MMU并跳到start_kernel

再次讓CPU進(jìn)入是實(shí)地址模式,,去運(yùn)行load_up_mmu()函數(shù)。這樣做的目的是讓core 0在實(shí)模式下調(diào)用load_up_mmu()函數(shù)來重新裝載MMU相關(guān)的寄存器,,比如SDR1,,BAT寄存器等。之所以要重新轉(zhuǎn)載,是因?yàn)槲覀冊?/span><11>bl initial_bats,,創(chuàng)建的臨時(shí)BAT塊地址映射,,只是啟動(dòng)的第一階段用到的臨時(shí)映射,現(xiàn)在這個(gè)臨時(shí)地址映射需要舍棄了,,我們需要重新初始化MMU,來建立正式的MMU地址映射,。

 

注:從__start()start_here()再到調(diào)用start_kernel(),,主要的工作與當(dāng)前目標(biāo)板的硬件結(jié)構(gòu)密切相關(guān),包含對(duì)一些底層硬件進(jìn)行最基本初始化操作等等,,從start_kernel()開始的初始化操作與處理器的類型基本無關(guān)了,。

 

3 start_kernel

本階段也是有0號(hào)線程init_task中調(diào)用的,將完成Linux內(nèi)核核心數(shù)據(jù)結(jié)構(gòu)的初始化,,最終創(chuàng)建1號(hào)線程kernel_init,,最后由1號(hào)內(nèi)核線程啟動(dòng)1號(hào)用戶進(jìn)程。需要后續(xù)確認(rèn)***

 

3.1 關(guān)中斷

3.2 調(diào)用tick_init(),,初始化系統(tǒng)時(shí)鐘滴答鏈

3.3 調(diào)用page_address_init(),,將高端內(nèi)存組織在一起。應(yīng)該是為buddy初始化做準(zhǔn)備,,需要進(jìn)一步確認(rèn)

3.4 setup_arch(),,setup_arch()函數(shù)是start_kernel()中非常重要函數(shù),主要作用是對(duì)內(nèi)存進(jìn)行初始化后,,調(diào)用ppc_md結(jié)構(gòu)的setup_arch()函數(shù)對(duì)當(dāng)前目標(biāo)板系統(tǒng)進(jìn)行基本的初始化,。

3.4.1 unflatten_device_tree()check_for_initrd();對(duì)OF Treeinitrd進(jìn)行檢查

3.4.2 find_legacy_serial_ports(),,對(duì)串口進(jìn)行檢查和設(shè)置

3.4.3 register_early_udbg_console()對(duì)調(diào)試口進(jìn)行檢查和設(shè)置

3.4.4設(shè)置指令和數(shù)據(jù)cache的長度

3.4.5 Linux系統(tǒng)進(jìn)入Panic后,,180秒后重啟系統(tǒng)

3.4.6設(shè)置0號(hào)進(jìn)程mm_struct結(jié)構(gòu)的代碼段,數(shù)據(jù)段和堆棧段

3.4.7 irqstack_early_init();//初始化中斷棧,,需要進(jìn)一步研究

3.4.8 do_init_bootmem();//初始化Boot Memory

3.4.9 ppc_md.setup_arch()對(duì)具體的處理器系統(tǒng)進(jìn)行初始化,,不同的處理器系統(tǒng)使用不同的ppc_md.setup_arch()函數(shù),該函數(shù)在probe_machine()函數(shù)中設(shè)置

3.4.10 paging_init(),,初始化ZONE_DMA,,ZONE_NORMALZONE_HIGHMEM區(qū)域的空閑頁表相關(guān),需要后續(xù)深入理解*************************************

3.5 setup_command_line(command_line)該函數(shù)對(duì)命令行參數(shù)進(jìn)行處理

注:命令行參數(shù)保存到全局?jǐn)?shù)組中,,見定義:char cmd_buf[256];  char *cmd_line = cmd_buf;

3.6 setup_per_cpu_areas()該函數(shù)初始化每個(gè)CPU的專用數(shù)據(jù)區(qū)域

 

3.7 smp_prepare_boot_cpu():它設(shè)置當(dāng)前BSP有效,,設(shè)置current_set數(shù)組中下標(biāo)為boot_cpuid的指針指向0號(hào)進(jìn)程init_taskthread_info描述符。

struct thread_info *current_set[NR_CPUS];

 

 

 

注:struct thread_infostruct task_struct間的關(guān)系,,參見下面的數(shù)據(jù)結(jié)構(gòu)

union thread_union {

       struct thread_info thread_info;

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

};

union thread_union init_thread_union;  init_task->stack 就是init_thread_union的起始地址,。

thread_union中的前12個(gè)字是thread_infostack共用的,其實(shí)是thread_info利用了stack8192B)的低地址的一部分空間而已。Stack 會(huì)從高地址向低地址方向使用,。

問題:只有init_task這樣用,?還是所有的線程都這樣用法?,?,?need confirmation

 

3.8 build_all_zonelists()該函數(shù)調(diào)用__build_all_nozelists函數(shù)初始化每個(gè)CPU的存儲(chǔ)節(jié)點(diǎn),并根據(jù)Linux PowerPC提供的數(shù)據(jù)區(qū)域,,如ZONE_DMAZONE_HIMEM來劃分內(nèi)存區(qū)間,。這部分的初始化也被稱之為存儲(chǔ)節(jié)點(diǎn)的初始化。

3.9 page_alloc_init()該函數(shù)為系統(tǒng)設(shè)置一個(gè)page_alloc_cpu_notify回調(diào)函數(shù),,該函數(shù)用來實(shí)現(xiàn)CPU的關(guān)閉與使能,。在一個(gè)MPP結(jié)構(gòu)的處理器系統(tǒng)或者大型服務(wù)器中有大量的CPU,該函數(shù)可以臨時(shí)打開或者關(guān)閉某些Core或者CPU,,此時(shí)Linux系統(tǒng)會(huì)調(diào)用page_alloc_cpu_notify函數(shù),,但是在我們的針對(duì)MPC8641HPCN平臺(tái),linux-smp沒有該功能,,page_alloc_init()為空,!

3.10 parse_early_param()parse_args():這兩個(gè)函數(shù)解析UBoot傳到給Linux內(nèi)核的一些參數(shù)。

 

3.11 vfs_caches_init_early();初始化VFS系統(tǒng)使用的dentryinode結(jié)構(gòu)專用SLAB描述符,,Linux使用dentry結(jié)構(gòu)保存有關(guān)文件目錄的信息,,使用inode結(jié)構(gòu)保存有關(guān)文件的信息。

3.12 sort_main_extable()該函數(shù)對(duì)異常調(diào)用表進(jìn)行重新排序,,Linux系統(tǒng)將異常調(diào)用表放在__ex_table調(diào)用表中,。

 

3.13 mm_init():該函數(shù)是一個(gè)靜態(tài)的函數(shù),它調(diào)用mem_init()函數(shù)初始化所有的頁表描述符,并初始化Buddy System,;然后調(diào)用kmem_cache_init()函數(shù)初始化Linux系統(tǒng)的SLAB分配器,。

 

3.14 sched_init():初始化主調(diào)度器的運(yùn)行隊(duì)列rq,在Linux SMP系統(tǒng)中每一個(gè)CPU都有自己的運(yùn)行隊(duì)列,!

3.16 preempt_disable():正如代碼注釋所說的那樣,,現(xiàn)在是禁用進(jìn)程搶占功能的,因?yàn)槟壳暗恼{(diào)度器還比較脆弱,,只有執(zhí)行了cpu_idle()函數(shù)之后才能進(jìn)行進(jìn)程搶占功能,!

3.17 idr_init_cache():該函數(shù)的初始化idr_layer_cache結(jié)構(gòu)的SLAB分配器,idr ,?,??,?,?

Linux基數(shù)樹(radix tree),,ID radixIDRID Radix)機(jī)制是將對(duì)象的身份鑒別號(hào)整數(shù)值ID與對(duì)象指針建立關(guān)聯(lián)表,,完成從ID與指針之間的相互轉(zhuǎn)換,。IDR機(jī)制使用radix樹狀結(jié)構(gòu)作為由id進(jìn)行索引獲取指針的稀疏數(shù)組,通過使用位圖可以快速分配新的ID,,IDR機(jī)制避免了使用固定尺寸的數(shù)組存放指針,。

可以認(rèn)為IDR機(jī)制是一種可伸展的數(shù)組的機(jī)制,并且?guī)?/span>bitmask,。

 

3.18 rcu_init():初始化Linux PowerPCRCU部件,,RCU是一種鎖機(jī)制

 

3.19 radix_tree_init():使用idr_init_cache()分配的Slab cache初始化radix樹。

3.20 init_IRQ (),,調(diào)用ppc_md.init_IRQ()初始化IRQ,需要跟進(jìn)理解

3.21 init_timers():初始化linux系統(tǒng)使用的定時(shí)器

3.22 hrtimers_init():初始化高精度定時(shí)器,,與Linux 系統(tǒng)提供的標(biāo)準(zhǔn)定時(shí)器相比,,該定時(shí)器更為準(zhǔn)確。

3.23 softirq_init():對(duì)Linux系統(tǒng)軟件中斷進(jìn)行初始化

3.24 time_init(): 初始化Linux系統(tǒng)的定時(shí)器,,Linux PowerPC可以使用外部RTC作為系統(tǒng)的定時(shí)器,,也可以使用TB寄存器!

3.25 local_irq_enable():開中斷

3.26 console_init():初始化控制器console,,consoleLinux系統(tǒng)用于輸出一些監(jiān)控信息的設(shè)備,,Linux系統(tǒng)一般使用串口或者監(jiān)視器作為console設(shè)備!

3.27 setup_per_cpu_pageset():初始化當(dāng)前CPU(BSP)每一個(gè)數(shù)據(jù)區(qū),,如ZONE_DMA,ZONE_HIMEM使用per_cpu_pageset緩沖

3.28 pidmap_init():建立pid結(jié)構(gòu)使用的專用Cache描述符表pid_cachep

3.29 fork_init(totalram_pages):創(chuàng)建task_struct結(jié)構(gòu)專用的Slab Cache描述符task_struct_cachep,并確定當(dāng)前Linux系統(tǒng)所能容納的最大進(jìn)程數(shù)目max_threads

3.30 proc_caches_init():創(chuàng)建專用的Slab Cache描述符sighand_cachep,、signal_cachepfiles_cachep,、fs_cachep,、mm_cachepvm_area_cachep,。

3.31 buffer_init():創(chuàng)建buffer_head結(jié)構(gòu)的專用Slab Cache描述符bh_cachep,linux的文件系統(tǒng)使用buffer_head結(jié)構(gòu)保存來自外部設(shè)備的數(shù)據(jù),。

3.32 vfs_caches_init(totalram_pages):創(chuàng)建專用的Slab cache描述符names_cachepfilp_cachep,然后調(diào)用   dcache_init()inode_init(),、files_init(mempages),、mnt_init()bdev_cache_init()chrdev_init()函數(shù)對(duì)Linux文件系統(tǒng)的各個(gè)子系統(tǒng)進(jìn)行初始化,。

3.33 signals_init():創(chuàng)建信號(hào)專用的Slab cache描述符sigqueue_cachep,,并初始化Linux系統(tǒng)的信號(hào)機(jī)制

3.34 page_writeback_init():初始化文件系統(tǒng)的回調(diào)函數(shù),Linux文件系統(tǒng)中會(huì)有很多“臟”頁,,這些頁不會(huì)立即和存儲(chǔ)系統(tǒng)中的數(shù)據(jù)進(jìn)行同步,,只有在需要進(jìn)行同步時(shí)才調(diào)用這些回調(diào)函數(shù)進(jìn)行同步,。

3.35 proc_root_init():創(chuàng)建根文件系統(tǒng),其實(shí)是根據(jù)數(shù)據(jù)結(jié)構(gòu)proc_fs_type,,mount 文件系統(tǒng),,并創(chuàng)建相應(yīng)的文件夾。沒看到根文件系統(tǒng)相關(guān),,從注釋到函數(shù)名都顯示是proc文件系統(tǒng),。不知何故?,?,??,?

3.36 調(diào)用rest_init()函數(shù),。

 

 

4. rest_init()函數(shù)。

 

 

4.1 調(diào)用kernel_thread()創(chuàng)建1號(hào)內(nèi)核線程,。

4.2 調(diào)用kernel_thread()創(chuàng)建kthreadd內(nèi)核線程,。尚不明作用。

4.3 init_idle_bootup_task():當(dāng)前0號(hào)進(jìn)程init_task最終會(huì)退化成idle進(jìn)程,,所以這里調(diào)用init_idle_bootup_task()函數(shù),,讓init_task進(jìn)程隸屬到idle調(diào)度類中。即選擇idle的調(diào)度相關(guān)函數(shù),。

4.4 調(diào)用schedule()函數(shù)切換當(dāng)前進(jìn)程,,在調(diào)用該函數(shù)之前,Linux系統(tǒng)中只有兩個(gè)進(jìn)程,,即0號(hào)進(jìn)程init_task1號(hào)進(jìn)程kernel_init,,其中kernel_init進(jìn)程也是剛剛被創(chuàng)建的。調(diào)用該函數(shù)后,,1號(hào)進(jìn)程kernel_init將會(huì)運(yùn)行,!

4.5 調(diào)用cpu_idle()0號(hào)線程進(jìn)入idle函數(shù)的循環(huán),,在該循環(huán)中會(huì)周期性地檢查,。

 

5 kernel_init 1號(hào)線程初始化

主要包括三方面

第一:引導(dǎo)SMP系統(tǒng)中的其它CPU(AP(Aplication Processor))

第二:調(diào)用do_basic_setup()函數(shù),完成Linux系統(tǒng)其它模塊的初始化,;

第三:更換核心進(jìn)程kernel_init為普通進(jìn)程之后,,完成對(duì)Linux系統(tǒng)的二次引導(dǎo),即對(duì)Linux系統(tǒng)應(yīng)用程序的引導(dǎo),!

 

5.1設(shè)置當(dāng)前1號(hào)線程所允許的BSP(core 0)cpu_all_mask中的對(duì)應(yīng)bit

5.2 init_pid_ns.child_reaper = current; 設(shè)置1號(hào)線程回收orphan 線程,。1號(hào)進(jìn)程在Linux系統(tǒng)中相當(dāng)于一個(gè)收容所,專門用于處理那些孤兒進(jìn)程,。

5.3 smp_prepare_cpus(setup_max_cpus)該函數(shù)的作用是首先探測我們的目標(biāo)系統(tǒng)中有多少個(gè)CPU,,該函數(shù)為每個(gè)CPU創(chuàng)建一個(gè)idle進(jìn)程,。

5.4 smp_init()是我們的linux-smp映像中啟動(dòng)另外一個(gè)核的最重要的代碼,該函數(shù)主要是引導(dǎo)SMP系統(tǒng)中的AP,,該函數(shù)會(huì)依次調(diào)用:smp_init()-> cpu_up()-> _cpu_up()-> __cpu_up()-> smp_ops-> kick_cpu(kick_cpu是一個(gè)函數(shù)指針,,指向smp_86xx_kick_cpu,故會(huì)執(zhí)行smp_86xx_kick_cpu()函數(shù))smp_86xx_kick_cpu()->  smp_86xx_release_core()-> __secondary_start_mpc86xx()-> __secondary_start()來啟動(dòng)core 1,,并調(diào)用set_cpu_online()函數(shù)將次CPU加入到cpu_online_map變量中,用以向主CPU通知該次CPU已經(jīng)被激活,。

5.5 sched_init_smp()該函數(shù)的作用,有待遇進(jìn)一步的分析,!

5.6 do_basic_setup():到目前為止,,內(nèi)核已經(jīng)初始化了,memory管理和process scheduler 已經(jīng)開始運(yùn)行,。但尚未注冊設(shè)備,。在本函數(shù)中將初始化workqueue,初始化device drivers,,初始化中斷處理,,最后調(diào)用do_initcalls()進(jìn)行靜態(tài)安裝所有模塊,其中包括驅(qū)動(dòng)人員最關(guān)心的用device_initcall聲明的設(shè)備模塊的安裝,。

 

5.7 調(diào)用init_post()創(chuàng)建用戶模式1號(hào)進(jìn)程。

 

第三步:Linux的應(yīng)用程序的初始化

1號(hào)kernel_init進(jìn)程完成linux的各項(xiàng)配置(包括啟動(dòng)AP)后,,就會(huì)在/sbin,/etc,/bin尋找init程序來運(yùn)行,。該init程序會(huì)替換kernel_init進(jìn)程(注意:并不是創(chuàng)建一個(gè)新的進(jìn)程來運(yùn)行init程序,而是一次變身,,使用sys_execve函數(shù)改變核心進(jìn)程的正文段,,將核心進(jìn)程kernel_init轉(zhuǎn)換成用戶進(jìn)程init),此時(shí)處于內(nèi)核態(tài)的1號(hào)kernel_init進(jìn)程將會(huì)轉(zhuǎn)換為用戶空間內(nèi)的1號(hào)進(jìn)程init,。戶進(jìn)程init將根據(jù)/etc/inittab中提供的信息完成應(yīng)用程序的初始化調(diào)用,。然后init進(jìn)程會(huì)執(zhí)行/bin/sh產(chǎn)生shell界面提供給用戶來與Linux系統(tǒng)進(jìn)行交互。

調(diào)用init_post()創(chuàng)建用戶模式1號(hào)進(jìn)程,。

init_post()中最終調(diào)用下面的任何一個(gè)入口(按順序,,第一個(gè)執(zhí)行成功后將不返回)

       if (execute_command) {

              run_init_process(execute_command);

              printk(KERN_WARNING "Failed to execute %s.  Attempting "

                                   "defaults...\n", execute_command);

       }

       run_init_process("/sbin/init");

       run_init_process("/etc/init");

       run_init_process("/bin/init");

       run_init_process("/bin/sh");

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多