各个架构下的linux启动流程-从linux被加载到start_kernel

引言

本文关注点 在 架构相关的启动过程
代码在 arch/xxx 中

arch/xxx 的作用是  
	1.boot(从kernel的第一行代码到start_kernel)
	2.start_kernel之后调用的平台(MACH)相关代码,架构相关代码(ARCH)
// 这里的 xxx(目录名称) 指代的是 arm arm64 x86 riscv , 分别对应 架构名称如下
	arm 	:  arm32(ARMv7-A ARMv6)
	arm64 	:  ARMv8-A ARMv9-A
	x86 	:  x86 x86_64
	riscv   :  rv32 rv64

概述

  • 从上电到 转换控制权到linux(这里的linux是linux镜像)
x86 启动过程包括 // x86的linux镜像只能是压缩的
BIOS->MBR->GRUB->vmlinuz(bzImage,objcopy生成的东西,类似uImage中的负载,可以执行)
arm 启动过程包括 // 过程1 在非压缩内核的时候 可以省略 // arm 的linux镜像可以是压缩的,可以是非压缩的
bootrom->bootloader(u-boot)->uImage/Image
arm64 启动过程包括 // arm64 的 linux 镜像 是非压缩的,没有压缩镜像
bootrom->bootloader(u-boot)->Image
riscv 启动过程包括 // rv 的linux 镜像 是非压缩的,没有压缩镜像
bootrom->u-boot-spl->opensbi->u-boot->Image
  • linux启动过程
linux启动过程最复杂的是 x86 // 这里指的 是 arch/x86,(代表 x86 和 x86_64)而不是 (x86 x86_64中的 x86)
x86 启动过程包括
1.实模式向保护模式的转换 2.解压缩 3.boot&调用start_kernel
arm 启动过程包括 // 过程1 在非压缩内核的时候 可以省略
1.解压缩 2.boot&调用start_kernel
arm64 启动过程包括
1.boot&调用start_kernel
riscv 启动过程包括
1.boot&调用start_kernel

详述

  • arch/x86 (以x86_64为例)
-------------------------------- 实模式
_start // arch/x86/boot/head.S
	calll main 	// arch/x86/boot/main.c
		----------------------- go_to_protected_mode 后进入保护模式
		go_to_protected_mode // arch/x86/boot/pm.c
			protected_mode_jump	// arch/x86/boot/pmjump.S
				boot_params.hdr.code32_start/即startup_32 //arch/x86/boot/compressed/head_64.S
					startup_64 // arch/x86/boot/compressed/head_64.S
						extract_kernel  // arch/x86/boot/compressed/misc.c
							handle_relocations // Lrelocated // 
								jmp *%rax/即startup_64 // arch/x86/kernel/head_64.S
									jmp 1f/即secondary_startup_64的标号1
										---- 第一个 C 函数 x86_64_start_kernel 
										lretq/即x86_64_start_kernel // arch/x86/kernel/head64.c 
											start_kernel // init/main.c
											
  • arch/x86 (以x86为例)
-------------------------------- 实模式
_start // arch/x86/boot/head.S
	calll main 	// arch/x86/boot/main.c
		----------------------- go_to_protected_mode 进入保护模式
		go_to_protected_mode // arch/x86/boot/pm.c
			protected_mode_jump	// arch/x86/boot/pmjump.S
				boot_params.hdr.code32_start/即startup_32 //arch/x86/boot/compressed/head_32.S
					extract_kernel  // arch/x86/boot/compressed/misc.c
						jmp *%eax/即startup_32 // arch/x86/kernel/head_32.S
							start_cpu0 // arch/x86/kernel/head_32.S
								---- 第一个 C 函数 i386_start_kernel 
								call *(initial_code)/即i386_start_kernel // arch/x86/kernel/head32.c 
									start_kernel // init/main.c
  • arch/arm (armv6和armv7-a是一样的流程)
非压缩内核


压缩内核

  • arch/arm64(armv8-a和armv9-a是一样的流程)
从 _head: 到 b	primary_entry
从 primary_entry 到 b	__primary_switch
从 __primary_switch 到 __primary_switched
从 __primary_switched 到 b	start_kernel
————————————————
版权声明:本文为CSDN博主「__pop_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011011827/article/details/107882040
  • arch/riscv(rv32和rv64是一样的流程)
ENTRY(_start) 到 j _start_kernel
_start_kernel
	call setup_vm
	call relocate
	la sp, init_thread_union + THREAD_SIZE
	tail start_kernel
————————————————
版权声明:本文为CSDN博主「__pop_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011011827/article/details/107882040

架构相关与架构无关

  • 引子
可以先去 https://www.zhihu.com/question/58121772/answer/156287959 中看 陈硕的回答

在刚接触 linux 时, 了解  linux 的启动 及 一些 底层 api 时
我关注的 是 arm32 ,但是经常会被网上很多资料带入 x86,让我误以为这些 x86的东西在arm32中也是有的,比如 bios,MBR,bzImage 等

linux 代码分为 架构相关代码
	架构相关代码"大都"分布在 arch/xxx中
	架构无关代码分布在 arch 除外的目录中

  • 架构相关代码有什么作用
当然,start_kernel 以后的代码应该与架构无关(除了宏指定的CONFIG_相关代码)
即arch/xxx之后的代码应该提供什么回调函数给架构无关函数
1.应该提供架构(ARCH)及板级(MACH)相关的boot流程
2.提供底层的操作函数 // 比如架构强相关的"原语指令"
  • 架构相关与无关的本质
注意
	每个架构用的指令及通用寄存器都是不一样的,比如一个C语句 "i++;" 经过编译器会生成不同的指令(指令中包括寄存器)
	这些编译器是可以cover的,所以这些都是架构无关码
	
	那些编译器不可以(以现有的技术)cover的,都是架构先相关码
		比如
			wfi指令,barrier指令,simd指令,原语先关指令(自旋锁等).这些到底层都是架构相关的

你可能感兴趣的:(杂七杂八总览,ARMv8,ARM64,linux,架构,运维)