grub越过实模式直接跳转到保护模式的内核,找到自己的位置
ENTRY(startup_32) //head_32.S (arch\x86\boot\compressed) 3871 2010/8/3
testb $(1<<6), BP_loadflags(%esi) //来源于grub的struct linux_kernel_params.loadflags
jnz 1f
cli
movl $__BOOT_DS, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs
movl %eax, %ss
1:
leal (BP_scratch+4)(%esi), %esp //建立临时堆栈, 只有4Byte, 来源于grub的struct linux_kernel_params.padding8[0x1e8 - 0x1e4]
call 1f
1: popl %ebp
subl $1b, %ebp //ebp为 startup_32 实际运行地址, 也就是bootloader加载地址
movl $LOAD_PHYSICAL_ADDR, %ebx //LOAD_PHYSICAL_ADDR为linux内核解压缩后的起始物理地址
=>#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
+ (CONFIG_PHYSICAL_ALIGN - 1)) \
& ~(CONFIG_PHYSICAL_ALIGN - 1))
[xxx@cliffr linux-2.6.32]$ ll .config
-rw-r--r--. 1 root root 101479 Feb 8 2020 .config
[xxx@cliffr linux-2.6.32]$ cat .config | grep CONFIG_PHYSICAL_START
CONFIG_PHYSICAL_START=0x400000
[xxx@cliffr linux-2.6.32]$ cat .config | grep CONFIG_PHYSICAL_ALIGN
CONFIG_PHYSICAL_ALIGN=0x400000
[xxx@cliffr linux-2.6.32]$
搬移内核,为解压缩做准备
/* Target address to relocate to for decompression */
addl $z_extract_offset, %ebx //搬移当前内核, ebx为搬移后的压缩内核物理地址
/* Set up the stack */
leal boot_stack_end(%ebx), %esp
/* 搬移当前内核, 从后向前搬移, 搬移后, ebx为新的 startup_32的物理地址 */
pushl %esi
leal (_bss-4)(%ebp), %esi
leal (_bss-4)(%ebx), %edi
movl $(_bss - startup_32), %ecx
shrl $2, %ecx
std
rep movsl
cld
popl %esi
/* 调整eip地址 */
leal relocated(%ebx), %eax
jmp *%eax
ENDPROC(startup_32)
.text
relocated:
/*
* Clear BSS (stack is currently empty)
*/
xorl %eax, %eax
leal _bss(%ebx), %edi
leal _ebss(%ebx), %ecx
subl %edi, %ecx
shrl $2, %ecx
rep stosl
解压缩内核,并跳转到解压缩后的内核
/*
* Do the decompression, and jump to the new kernel..
*/
leal z_extract_offset_negative(%ebx), %ebp
/* push arguments for decompress_kernel: */
pushl %ebp /* output address */
pushl $z_input_len /* input_len */
leal input_data(%ebx), %eax
pushl %eax /* input_data */
leal boot_heap(%ebx), %eax
pushl %eax /* heap area */
pushl %esi /* real mode pointer */
call decompress_kernel
addl $20, %esp
/*
* Jump to the decompressed kernel.
*/
xorl %ebx, %ebx
jmp *%ebp
/*
* Stack and heap for uncompression
*/
.bss
.balign 4
boot_heap:
.fill BOOT_HEAP_SIZE, 1, 0
boot_stack:
.fill BOOT_STACK_SIZE, 1, 0
boot_stack_end:
Linux Kernel 2.6.37 启动过程:startup_32
http://blog.chinaunix.net/uid-1701789-id-148056.html
linux内核-x86_32位内核启动流程
https://blog.csdn.net/chentaoxie/article/details/86352305
[原创]linux-5.6.6 内核引导
https://bbs.pediy.com/thread-261718.html
linux有意避开了分段机制
https://blog.csdn.net/u012566181/article/details/38253937?utm_source=blogxgwz6
4. 切换到64位模式
https://blog.csdn.net/GerryLee93/article/details/106475973
内核引导过程. Part 4.
切换到64位模式
https://www.javascriptc.com/books/linux-insides-cn/Booting/linux-bootstrap-4.html
混沌初开--内核启动笔记
http://www.voidcn.com/article/p-dbwptazw-up.html
https://blog.csdn.net/richardysteven/article/details/52629731
Linux内核启动流程分析(一)
http://blog.chinaunix.net/uid-25909619-id-3380535.html
Linux内存初始化(汇编部分)
https://blog.csdn.net/shuanhuoguo/article/details/80122253
Linux内存初始化(汇编部分)
https://www.sohu.com/a/63559761_115128
内核启动之启动内核——startup_32
https://blog.csdn.net/yu616568/article/details/7581919
Linux内核启动过程分析
https://blog.csdn.net/chuifuhuo6864/article/details/100883445