linux内核-x86_32位内核启动流程

arch/x86/boot/header.S

执行_start,第274行:
.global _start
_start:

然后跳转执行start_of_setup,准备实模式建立堆栈,BSS段清0,为下步C语言执行建立环境。
start_of_setup:

然后跳转到C代码执行main:
# Jump to C code (should not return)
calll main

arch/x86/boot/main.c

执行main函数:
void main(void)
maim中使用BIOS中断读取一些硬件信息,如内存信息等。

main函数最后,再执行go_to_protected_mode函数。

arch/x86/boot/pm.c

执行go_to_protected_mode函数。
void go_to_protected_mode(void)
禁用中断,开启20位以上的地址线,设置保护模式,设置全局描述表。

函数最后执行protected_mode_jump

arch/x86/boot/pmjump.S

执行protected_mode_jump:
GLOBAL(protected_mode_jump)
该段开始的.code16指令,表示这段代码依然是16位的实模式代码。使能CR0寄存器中的PE(Protection Enable)位,进入32位保护模式。建立32位的堆栈,清除寄存器以允许将来扩展到32位引导协议。

跳转到了code32_start地址处执行。

arch/x86/boot/compressed/head_32.S

执行startup_32:
__HEAD
ENTRY(startup_32)
执行过程,调用了efi_main

执行到,解压内核
call decompress_kernel

arch/x86/boot/compressed/misc.c

执行decompress_kernel函数。
asmlinkage void decompress_kernel
会输出打印Decompressing Linux…字样。

解压完成后跳转到output。

/arch/x86/kernel/head_32.S

进入到第88行,开始执行
__HEAD
ENTRY(startup_32)

执行到第454行,跳转到i386_start_kernel函数。
jmp *(initial_code)

/arch/x86/kernel/head32.c

执行i386_start_kernel函数。此函数最后调用start_kernel函数。

/init/main.c
执行start_kernel函数。开始启动内核。

参考链接:
https://blog.csdn.net/jn1158359135/article/details/7436211
https://www.cnblogs.com/long123king/p/3545991.html
http://blog.chinaunix.net/uid-1701789-id-148056.html

猜你喜欢

转载自blog.csdn.net/chentaoxie/article/details/86352305