init 进程号称天字一号进程,做系统的小伙伴应该都有了解。那么,这个一号进程是如何被启动的呢? 今天就来一起简单看看这个进程的前世今生。
因为目前运行Linux最多的就是ARM设备了,我们就基于Linux的master分支简单分析下ARM 32架构下的启动过程。
kernel的执行起点是stext函数,定义于arch/arm/kernel/head.S。我们就从这个函数开始看看init如何被启动的。
ENTRY(stext)
......
/*这里将__mmap_switched 函数的地址赋给了r13寄存器,
这个函数会在MMU被使能之后执行。
MMU是Memory Management Unit的缩写,中文名是内存管理单元,
同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权*/
ldr r13, =__mmap_switched @ address to jump to after
@ mmu has been enabled
badr lr, 1f @ return (PIC) address
......
/*接下来执行__enable_mmu 函数*/
1: b __enable_mmu
ENDPROC(stext)
下面来看__enable_mmu 函数做了什么
__enable_mmu:
......
/*主要调用了__turn_mmu_on 来打开MMU ,让CPU进入虚拟内存的运行阶段。*/
b __turn_mmu_on
ENDPROC(__enable_mmu)
ENTRY(__turn_mmu_on)
......
/*这里将r13保存的函数地址赋给PC指针,即IP寄存器。 RET指令的内部操作是:栈顶字单元出栈,其值赋给IP寄存器*/
mov r3, r13
ret r3
__turn_mmu_on_end:
ENDPROC(__turn_mmu_on)