linux kernel-6.18-x86架构启动流程
仅作为一个临时笔记,之前分析的,不一定准确
linux内核启动流程,以x86_64为例(解释一下,这里的x86是架构,64是位数),内核版本:6.18-rc4,大概率不准确,但是对理解大体流程还是很有用的
{
文件: arch/x86/boot/header.S
函数/段: _start
跳转: start_of_setup,_start直接无条件跳转,其中下面是无条件的跳转代码
.byte 0xeb # short (2-byte) jump
.byte start_of_setup-1f
说明: 在arch/x86/boot/setup.ld中有一段是ENTRY(_start),定义了入口是_start,.ld文件是链接配置文件
}
一直往下运行,会运行到start_of_setup,然后继续执行。
-->
{
文件: arch/x86/boot/header.S
函数/段: start_of_setup
跳转: main,最后的 calll main 执行了跳转
说明: 无
}
-->
{
文件: arch/x86/boot/main.c
函数/段: main
跳转: go_to_protected_mode
说明: 无
}
-->
{
文件: arch/x86/boot/pm.c
函数/段: go_to_protected_mode
跳转: protected_mode_jump
说明: protected_mode_jump是一个在汇编中实现的函数,定义在arch/x86/boot/boot.h
}
-->
{
文件: arch/x86/boot/pmjump.S
函数/段: protected_mode_jump
跳转: startup_64,一直运行到arch/x86/boot/pmjump.S的最后运行跳转汇编代码jmpl *%eax,其中eax的值在protected_mode_jump(u32 entrypoint, u32 bootparams)的entrypoint中指定的
说明: protected_mode_jump是一个在汇编中实现的函数,定义在arch/x86/boot/boot.h
}
#####################不确定的部分
-->
先到head_32.S中的startup_32???
{
文件: arch/x86/boot/compressed/head_32.S
函数/段: startup_32,定义位置为SYM_FUNC_START(startup_32),最后通过jmp *%eax跳转到64。不清楚为什么必须先经过32才能再到64
跳转: startup_64
说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口
}
-->
还是直接到到head_64.S中的startup_32,然后直接运行后面的startup_32???
{
文件: arch/x86/boot/compressed/head_64.S
函数/段: startup_32,定义位置为SYM_FUNC_START(startup_32),不跳转,直接继续运行到startup_64。不清楚为什么必须先经过32才能再到64
跳转: 直接运行startup_64
说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口
}
#######################
{
文件: arch/x86/boot/compressed/head_64.S
函数/段: startup_64,定义位置为SYM_CODE_START(startup_64)
跳转: startup_64,注意这个是另一个文件的startup_64,通过jmp *%rax跳转到解压后内核的地址
说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口
}
-->
{
文件: arch/x86/kernel/head_64.S
函数/段: startup_64
跳转: common_startup_64,通过jmp *.Lcommon_startup_64(%rip)跳转,其中.Lcommon_startup_64通过SYM_DATA_LOCAL(.Lcommon_startup_64, .quad common_startup_64)将common_startup_64的地址赋值给.Lcommon_startup_64
说明: 可通过arch/x86/boot/compressed下的/vmlinux.lds或vmlinux.lds.S知道startup_64也是一个入口
}
-->
{
文件: arch/x86/kernel/head_64.S
函数/段: common_startup_64,在SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)是入口
跳转: Lsetup_cpu,通过最后的 jmp .Lsetup_cpu 跳转
说明:
}
-->
{
文件: arch/x86/kernel/head_64.S
函数/段: Lsetup_cpu,在SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)是入口
跳转: 执行完Lsetup_cpu段之后没有跳转,继续运行后面的段,直到段Ljump_to_C_code的callq *initial_code(%rip)
说明:
}
-->
{
文件: arch/x86/kernel/head64.c
函数/段: x86_64_start_kernel,终于进入c函数了,后面的跳转就好找了
跳转: x86_64_start_reservations
说明:
}
-->
{
文件: arch/x86/kernel/head64.c
函数/段: x86_64_start_reservations,终于进入c函数了,后面的跳转就好找了
跳转:
说明:
}

浙公网安备 33010602011771号