decompress kernel

本文介绍Linux i386架构下内核的加载与解压缩过程,包括检查A20地址线是否启用、解压内核到内存指定位置0x100000并跳转执行,以及对于高地址加载的内核如何移动解压后的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

arch/i386/boot/compress/head.S is responsible for decompressed the kernel and move it to 0x100000. when it is executed, the virtual address is 0x1000 for low loaded vmlinux and 0x100000 for high loaded one, which are the same with their physical addresses, respectively.

 

/* check contents of 0x000000 and 0x100000, if not equal, means A20 is enabled. */

  xorl %eax,%eax
1: incl %eax  # check that A20 really IS enabled
  movl %eax,0x000000 # loop forever if it isn't
  cmpl %eax,0x100000
  je 1

 

/* decompress the kernel and jump to it (0x100000) for low loaded kernel */

 subl $16,%esp # place for structure on the stack
 pushl %esp # address of structure as first arg
 call SYMBOL_NAME(decompress_kernel)
 orl  %eax,%eax
 jnz  3f
 xorl %ebx,%ebx
 ljmp $(__KERNEL_CS), $0x10000

 

/* move move_routine_start to 0x1000 and jump to it */

 movl $move_routine_start,%esi
 movl $0x1000,%edi
 movl $move_routine_end,%ecx
 subl %esi,%ecx
 cld
 rep
 movs

 

 popl %esi # discard the address
 popl %esi # low_buffer_start
 popl %ecx # lcount
 popl %edx # high_buffer_start
 popl %eax # hcount
 movl $0x100000,%edi
 cli  # make sure we don't get interrupted
 ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine

 

/* move hcount from high_buffer_start to 0x100000 and jump to it for high loaded kernel */

move_routine_start:
 rep
 movsb
 movl %edx,%esi
 movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0
 rep
 movsb
 xorl %ebx,%ebx
/*
 * Well, the kernel relies on %esp pointing into low mem,
 * with the decompressor loaded high this is no longer true,
 * so we set esp here.
 */
 mov  $0x90000,%esp
 ljmp $(__KERNEL_CS), $0x100000
move_routine_end:

### Linux 系统开发板程序启动流程 Linux 开发板的启动过程是一个复杂的过程,涉及从硬件初始化到操作系统加载、再到用户应用程序运行等多个阶段。以下是简化的启动流程: #### 1. **上电复位 (Power-On Reset)** - 当开发板通电时,CPU会首先执行ROM中的引导代码,通常是BIOS或U-Boot等固件。 #### 2. **引导加载程序 (Bootloader)** - 引导加载程序的主要任务是初始化硬件并准备将内核加载到内存中。 - 第一阶段:通常是从SPI Flash或其他存储设备读取第二阶段引导加载程序。 - 第二阶段:负责设置MMU(内存管理单元)、缓存、中断控制器等,并最终加栽Linux内核映像文件到RAM中。 #### 3. **解压缩内核 (Decompress Kernel)** - 内核通常是压缩过的,所以需要先将其解压至内存中特定位置。 #### 4. **跳转到内核入口点 (Jump to Kernel Entry Point)** - 解压完成后,控制权交给了内核的第一个指令地址处开始执行。 #### 5. **内核初始化 (Kernel Initialization)** - 这一步骤包括: - 初始化进程0 (idle process) - 创建初始环境变量 - 设置根文件系统(rootfs),可以是initramfs 或者直接挂载实际rootfs(如ext4,nfs etc.) #### 6. **用户空间初始化 (User Space Initiation)** - 执行`/sbin/init` 或 `/etc/init.d/rcS`, 它们会依次启动各种服务守护进程,例如网络配置、日志记录等等。 #### 7. **应用层启动 (Application Layer Start-up)** - 最终进入图形界面GUI或是命令行CLI模式供开发者交互操作;与此同时各类后台服务也开始正常运作起来。 --- 为了更直观地理解这个过程,可以用一张简单的流程图表示: ``` +-------------------+ | 上电复位 | +--------+----------+ v +--------v----------+ | Bootloader | <- U-Boot or other bootloader +--------+----------+ v +--------v----------+ | 解压缩内核 | +--------+----------+ v +--------v----------+ | 跳转到内核入口 | +--------+----------+ v +--------v----------+ | 内核初始化 | <-- 启动进程0, 挂载rootfs +--------+----------+ v +--------v----------+ | 用户空间初始化 | <-- init / rcS脚本 +--------+----------+ v +--------v----------+ | 应用层启动 | <-- GUI/CMD + services startup +-------------------+ ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值