1 Linux 内核启动过程
1.1 U-Boot 调用
在文件在 U-Boot 文件 lib_arm/Armlinux.c 中。
s = getenv ("bootcmd");//读取启动命令
run_command (s, 0); //执行 bootcmd 命令,启动 linux kernel
首先得到环境参数 bootcmd,bootcmd 是 linux kernel 的启动,然后通过 run_command 执行该命令,启动内
核。
bootcmd=nand read 0x20008000 0x600000 0x500000 ;bootm 0x20008000
1、nand read 0x20008000 0x600000 0x500000 ;
从 nand 的 0x600000 地址读 0x500000 字节的 kernel 到 0x20008000 地址。
2、bootm 0x20008000
bootm 调用了 do_bootm()函数,
do_bootm( )这个函数会先去读 uImage 的头部以获取该 uImage 的加载地址和入口地址,当发现该 uImage
目前所处的内存地址不等于它的加载地址时,该函数会将该 uImage 移动到它的加载地址上。do_bootm( )
会调用 do_bootm_linux()函数,
do_bootm_linux()函数调用了函数 theKernel (0, machid, bd->bi_boot_params);// 启动 linux kernel, 进入 arm
linux 环境,调用的 kernel 入口是汇编程序,所以通过 r0、r1、r2 传递给内核。
1.2 vmlinux 入口
在 arch/arm/vmlinux.lds 的 链 接 脚 本 控 制 下 , 链 接 程 序 将 vmlinux 的 入 口 置 于
"arch/arm/kernel/head.S"。
.section ".text.head", "ax"
.typestext, %function
ENTRY(stext)
msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @确保进入管理模式,
@并且关闭 FIQ 和 IRQ
mrc p15, 0, r9, c0, c0 @ get processor id
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ r5=0,报错。yes, error 'p',死循环
bl __lookup_machine_type @ r5=machinfo
movs r8, r5 @ invalid machine (r5=0)?
beq __error_a @ yes, error 'a'
bl __vet_atags
bl __create_page_tables
ldr r13, __switch_data @ address to jump to after
@ mmu has been enabled
adr lr, __enable_mmu @ return (PIC) address
add pc, r10, #PROCINFO_INITFUNC
语句“add pc, r10, #PROCINFO_INITFUNC”通过查表调用 proc-v7.s 中__v7_setup 函数,该函数末尾通
过将 lr 寄存器赋给 pc,导致对__enable_mmu 的调用,完成使能 mmu 的操作,之后将 r13 寄存器值赋给
评论0
最新资源