linux内核学习(1)第一阶段启动 解压缩内核

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值