Linux2 6核心啟動分析

2021-07-11 00:52:14 字數 4059 閱讀 1121

我們已知u-boot的終極目的是啟動核心,那麼核心啟動的開始必定是u-boot傳入的引數。

開啟armlinux.c  發現有一行的**為:

thekernel (0, bd->bi_arch_number, bd->bi_boot_params);//帶入三個引數

第乙個引數是0,第二個引數是機器id,第三個引數是引數所存放的位址。

核心啟動時要做的幾個步驟

1.處理u-boot傳入的引數 //arch/arm/kernel/head.s

entry(stext)

msr    cpsr_c, #psr_f_bit | psr_i_bit | svc_mode @ 確立cpu是處於svc模式。

@ and irqs disabled

mrc    p15, 0, r9, c0, c0        @ get processor id  //將c0暫存器的數值傳送到r9暫存器中,獲取cpu的id

bl    __lookup_processor_type        @ r5=procinfo r9=cpuid   //判斷cpu型別,核心支援的cpu是固定的

movs    r10, r5                @ invalid processor (r5=0)?

beq    __error_p            @ yes, error 'p'

bl    __lookup_machine_type        @ r5=machinfo//判斷單板的型別  如果不能支援  就跳到error裡死迴圈,這裡就處理u-boot傳入的arch_number

movs    r8, r5                @ invalid machine (r5=0)?

beq    __error_a            @ yes, error 'a'

bl    __create_page_tables  @建立頁表

a.判斷是否支援這個cpu

b.判斷核心是否支援該單板,分析u-boot啟動核心時傳入的機器id

3:    .long    .

.long    __arch_info_begin

.long    __arch_info_end

__lookup_machine_type:

adr    r3, 3b              @r3 = 3b的 address  address of r3 = "3:    .long"   real address

ldmia    r3,   @r4 = "." virtual address of 3b,r5="__arch_info_begin"  r6 = "__arch_info_end"

/* __arch_info_begin = .;

*(.arch.info.init)

__arch_info_end = .;*/

sub    r3, r3, r4            @ get offset between virt&phys  r3 = r3 - r4

add    r5, r5, r3            @ convert virt addresses to //r5 = r5 + r3

add    r6, r6, r3            @ physical address space//r6 = r3 + r6

1:    ldr    r3, [r5, #machinfo_type]    @ get machine type

teq    r3, r1                @ matches loader number

beq    2f                @ found

add    r5, r5, #sizeof_machine_desc    @ next machine_desc

cmp    r5, r6

blo    1b

mov    r5, #0                @ unknown machine

2:    mov    pc, lr

在這裡  出現了.arch.info.init   我們搜尋下 發現在arch.h處有定義

#define machine_start(_type,_name)            \

static const struct machine_desc __mach_desc_##_type    \

__used                            \

__attribute__((__section__(".arch.info.init"))) = ;

machine_start(s3c2440, "smdk2440")

/* maintainer: ben dooks */

.phys_io    = s3c2410_pa_uart,

.io_pg_offst    = (((u32)s3c24xx_va_uart) >> 18) & 0xfffc,

.boot_params    = s3c2410_sdram_pa + 0x100,        //0x30000100,儲存u-boot傳進的引數

.init_irq    = s3c24xx_init_irq,

.map_io        = smdk2440_map_io,

.init_machine    = smdk2440_machine_init,

.timer        = &s3c24xx_timer,

machine_end

#define machine_start(_type,_name)            \

//由上面兩段**整合後是這樣的

static const struct machine_desc __mach_desc_s3c2440    \

__used                            \

__attribute__((__section__(".arch.info.init"))) = {    \

.nr        = mach_type_s3c2440,        \

.name        = smdk2440,

.phys_io    = s3c2410_pa_uart,

.io_pg_offst    = (((u32)s3c24xx_va_uart) >> 18) & 0xfffc,

.boot_params    = s3c2410_sdram_pa + 0x100,

.init_irq    = s3c24xx_init_irq,

.map_io        = smdk2440_map_io,

.init_machine    = smdk2440_machine_init,

.timer        = &s3c24xx_timer,

;c.建立頁表

d.使能mmu

e.跳轉到startkernel

//為什麼要建立頁表呢,我們觀察鏈結檔案得位址為(0xc0000000) + 0x00008000; //指定核心位址,但是這位址不對應真實存在的記憶體,所以需要開啟mmu對映位址

核心的啟動流程

/arch/arm/kernel/head.s

start_kernel

setup_arch          //解析u-boot傳入的啟動引數

setup_command_line  //解析u-boot傳入的啟動引數

parse_early_param

do_early_paramt

從_setup_start到_setup_end;呼叫early函式

unknown_bootoption

obsolete_checksetup        

從_setup_start到_setup_end;呼叫非early函式

rest_init();

kernel_init

prepare_namespace();

mount_root();(掛接根檔案系統)

init_post();    //開啟/dev/console  執行應用程式run_init_professor

linux2 6核心啟動流程

計算機在啟動時都是先加電,然後進行硬體檢測並引導作業系統的初始化程式,然後作業系統的初始化程式程負責讀入系統核心並建產系統的執行環境.一這過程相對來說比較復而且與cpu體系結構相關,這裡我們通過linux並以i386的體系結構對這一過程進行較為詳細的說明.一 硬體檢測 當 機器加電後它首先執行bio...

Linux 2 6 核心引導過程分析

本文以x86為例,x86與嵌入式系統的區別在於多了乙個bios轉移到bootloader的過程。linux核心引導的過程包含多個階段,接下來將依次解讀 系統加電時,處理器會執行乙個位於已知位置處的 pc中即我們熟知的bios,它儲存在主機板的快閃儲存器中。bios從0xffff0處開始執行,首先執行...

Linux 2 6 核心引導過程分析

本文以x86為例,x86與嵌入式系統的區別在於多了乙個bios轉移到bootloader的過程。linux核心引導的過程包含多個階段,接下來將依次解讀 系統加電時,處理器會執行乙個位於已知位置處的 pc中即我們熟知的bios,它儲存在主機板的快閃儲存器中。bios從0xffff0處開始執行,首先執行...