引言
本文关注点 在 架构相关的启动过程
代码在 arch/xxx 中
arch/xxx 的作用是
1.boot(从kernel的第一行代码到start_kernel)
2.start_kernel之后调用的平台(MACH)相关代码,架构相关代码(ARCH)
arm : arm32(ARMv7-A ARMv6)
arm64 : ARMv8-A ARMv9-A
x86 : x86 x86_64
riscv : rv32 rv64
概述
- 从上电到 转换控制权到linux(这里的linux是linux镜像)
x86 启动过程包括
BIOS->MBR->GRUB->vmlinuz(bzImage,objcopy生成的东西,类似uImage中的负载,可以执行)
arm 启动过程包括
bootrom->bootloader(u-boot)->uImage/Image
arm64 启动过程包括
bootrom->bootloader(u-boot)->Image
riscv 启动过程包括
bootrom->u-boot-spl->opensbi->u-boot->Image
linux启动过程最复杂的是 x86
x86 启动过程包括
1.实模式向保护模式的转换 2.解压缩 3.boot&调用start_kernel
arm 启动过程包括
1.解压缩 2.boot&调用start_kernel
arm64 启动过程包括
1.boot&调用start_kernel
riscv 启动过程包括
1.boot&调用start_kernel
详述
-------------------------------- 实模式
_start
calll main
----------------------- go_to_protected_mode 后进入保护模式
go_to_protected_mode
protected_mode_jump
boot_params.hdr.code32_start/即startup_32
startup_64
extract_kernel
handle_relocations
jmp *%rax/即startup_64
jmp 1f/即secondary_startup_64的标号1
---- 第一个 C 函数 x86_64_start_kernel
lretq/即x86_64_start_kernel
start_kernel
-------------------------------- 实模式
_start
calll main
----------------------- go_to_protected_mode 进入保护模式
go_to_protected_mode
protected_mode_jump
boot_params.hdr.code32_start/即startup_32
extract_kernel
jmp *%eax/即startup_32
start_cpu0
---- 第一个 C 函数 i386_start_kernel
call *(initial_code)/即i386_start_kernel
start_kernel
- 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:
- 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:
架构相关与架构无关
可以先去 https:
在刚接触 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指令,原语先关指令(自旋锁等).这些到底层都是架构相关的